Search code examples
c#ms-wordopenxml

Prevent tables from breaking over a page, if possible


I am using OpenXML to generate a word document which contains thousands of tables. Some of them span over the length of entire page, which is fine as there is no way to prevent that from happening, however, many of the tables contain only a few rows. Is there a property I can set to prevent these tables from breaking?

It looks awful when a table with only two rows is split between two pages, or when a key row is the only one split on the previous page. I've spent a serious chunk of time navigating the MSDN pages with no luck... hopefully somebody has done this before.


Solution

  • This is kind of a pain, but there is a way to do it. If you were editing a document directly in Word and wanted to achieve this behavior, you would play with the "Keep with next" and "Keep lines together" properties under Paragraph > Line and Page Breaks. Basically you would check the box to enable this property for each row in the table (technically all but the last row, although setting all rows may work as well). Since anything that can be done in Word can be accomplished using the OOXML API as well, it's just a matter of figuring it out. Here's a code snippet that illustrates the code needed.

    First, the code below generates a Word document with a table that WILL break across pages. It first adds a simple style for the table, then adds a series of paragraphs to push the table down the page, before finally adding the table at the bottom.

    using (WordprocessingDocument document = WordprocessingDocument.Create("TableBreaksAcrossPage.docx", WordprocessingDocumentType.Document))
            {
                MainDocumentPart mainDocumentPart = document.AddMainDocumentPart();
    
                #region Styles
    
                Styles styles = new Styles();
    
                Style style = new Style() { Type = StyleValues.Table, StyleId = "TableGrid" };
                StyleName styleName10 = new StyleName() { Val = "Table Grid" };
                BasedOn basedOn2 = new BasedOn() { Val = "TableNormal" };
                UIPriority uIPriority8 = new UIPriority() { Val = 59 };
                Rsid rsid7 = new Rsid() { Val = "003B7411" };
    
                StyleParagraphProperties styleParagraphProperties2 = new StyleParagraphProperties();
                SpacingBetweenLines spacingBetweenLines4 = new SpacingBetweenLines() { After = "0", Line = "240", LineRule = LineSpacingRuleValues.Auto };
    
                styleParagraphProperties2.Append(spacingBetweenLines4);
    
                StyleTableProperties styleTableProperties4 = new StyleTableProperties();
                TableIndentation tableIndentation4 = new TableIndentation() { Width = 0, Type = TableWidthUnitValues.Dxa };
    
                TableBorders tableBorders2 = new TableBorders();
                TopBorder topBorder2 = new TopBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                LeftBorder leftBorder2 = new LeftBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                BottomBorder bottomBorder2 = new BottomBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                RightBorder rightBorder2 = new RightBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                InsideHorizontalBorder insideHorizontalBorder2 = new InsideHorizontalBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                InsideVerticalBorder insideVerticalBorder2 = new InsideVerticalBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
    
                tableBorders2.Append(topBorder2);
                tableBorders2.Append(leftBorder2);
                tableBorders2.Append(bottomBorder2);
                tableBorders2.Append(rightBorder2);
                tableBorders2.Append(insideHorizontalBorder2);
                tableBorders2.Append(insideVerticalBorder2);
    
                TableCellMarginDefault tableCellMarginDefault4 = new TableCellMarginDefault();
                TopMargin topMargin4 = new TopMargin() { Width = "200", Type = TableWidthUnitValues.Dxa };
                TableCellLeftMargin tableCellLeftMargin4 = new TableCellLeftMargin() { Width = 108, Type = TableWidthValues.Dxa };
                BottomMargin bottomMargin4 = new BottomMargin() { Width = "200", Type = TableWidthUnitValues.Dxa };
                TableCellRightMargin tableCellRightMargin4 = new TableCellRightMargin() { Width = 108, Type = TableWidthValues.Dxa };
    
                tableCellMarginDefault4.Append(topMargin4);
                tableCellMarginDefault4.Append(tableCellLeftMargin4);
                tableCellMarginDefault4.Append(bottomMargin4);
                tableCellMarginDefault4.Append(tableCellRightMargin4);
    
                styleTableProperties4.Append(tableIndentation4);
                styleTableProperties4.Append(tableBorders2);
                styleTableProperties4.Append(tableCellMarginDefault4);
    
                style.Append(styleName10);
                style.Append(basedOn2);
                style.Append(uIPriority8);
                style.Append(rsid7);
                style.Append(styleParagraphProperties2);
                style.Append(styleTableProperties4);
    
                styles.Append(style);
    
                StyleDefinitionsPart styleDefinitionsPart = mainDocumentPart.AddNewPart<StyleDefinitionsPart>("Styles");
                styleDefinitionsPart.Styles = styles;
    
                #endregion
    
                mainDocumentPart.Document =
                new Document(
                    new Body(
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Table(
                            new TableProperties(
                                new TableStyle() { Val = "TableGrid" },
                                new TableWidth() { Width = "0", Type = TableWidthUnitValues.Auto }),
                            new TableGrid(
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" }),
                            new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 1"))))),
                           new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 2"))))),
                          new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
    
                                            ),
                                        new Run(
                                        new Text("Table Row 3"))))),
                         new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4"))))))));
            }
    

    The code below generates a Word document with a table that WILL NOT break across pages. Note that the ParagraphProperties of each paragraph have an instance of the KeepNext() and KeepLines() classes appended. As far as I can tell, this needs to be done for each TableCell, which is the painful part. Might be able to offload cell creation to a helper method though, to avoid all the repetitive code. Run the code and see for yourself, hope it helps.

    using (WordprocessingDocument document = WordprocessingDocument.Create("TableDoesNotBreakAcrossPage.docx", WordprocessingDocumentType.Document))
            {
                MainDocumentPart mainDocumentPart = document.AddMainDocumentPart();
    
                #region Styles
    
                Styles styles = new Styles();
    
                Style style = new Style() { Type = StyleValues.Table, StyleId = "TableGrid" };
                StyleName styleName10 = new StyleName() { Val = "Table Grid" };
                BasedOn basedOn2 = new BasedOn() { Val = "TableNormal" };
                UIPriority uIPriority8 = new UIPriority() { Val = 59 };
                Rsid rsid7 = new Rsid() { Val = "003B7411" };
    
                StyleParagraphProperties styleParagraphProperties2 = new StyleParagraphProperties();
                SpacingBetweenLines spacingBetweenLines4 = new SpacingBetweenLines() { After = "0", Line = "240", LineRule = LineSpacingRuleValues.Auto };
    
                styleParagraphProperties2.Append(spacingBetweenLines4);
    
                StyleTableProperties styleTableProperties4 = new StyleTableProperties();
                TableIndentation tableIndentation4 = new TableIndentation() { Width = 0, Type = TableWidthUnitValues.Dxa };
    
                TableBorders tableBorders2 = new TableBorders();
                TopBorder topBorder2 = new TopBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                LeftBorder leftBorder2 = new LeftBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                BottomBorder bottomBorder2 = new BottomBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                RightBorder rightBorder2 = new RightBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                InsideHorizontalBorder insideHorizontalBorder2 = new InsideHorizontalBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
                InsideVerticalBorder insideVerticalBorder2 = new InsideVerticalBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt32Value)4U, Space = (UInt32Value)0U };
    
                tableBorders2.Append(topBorder2);
                tableBorders2.Append(leftBorder2);
                tableBorders2.Append(bottomBorder2);
                tableBorders2.Append(rightBorder2);
                tableBorders2.Append(insideHorizontalBorder2);
                tableBorders2.Append(insideVerticalBorder2);
    
                TableCellMarginDefault tableCellMarginDefault4 = new TableCellMarginDefault();
                TopMargin topMargin4 = new TopMargin() { Width = "200", Type = TableWidthUnitValues.Dxa };
                TableCellLeftMargin tableCellLeftMargin4 = new TableCellLeftMargin() { Width = 108, Type = TableWidthValues.Dxa };
                BottomMargin bottomMargin4 = new BottomMargin() { Width = "200", Type = TableWidthUnitValues.Dxa };
                TableCellRightMargin tableCellRightMargin4 = new TableCellRightMargin() { Width = 108, Type = TableWidthValues.Dxa };
    
                tableCellMarginDefault4.Append(topMargin4);
                tableCellMarginDefault4.Append(tableCellLeftMargin4);
                tableCellMarginDefault4.Append(bottomMargin4);
                tableCellMarginDefault4.Append(tableCellRightMargin4);
    
                styleTableProperties4.Append(tableIndentation4);
                styleTableProperties4.Append(tableBorders2);
                styleTableProperties4.Append(tableCellMarginDefault4);
    
                style.Append(styleName10);
                style.Append(basedOn2);
                style.Append(uIPriority8);
                style.Append(rsid7);
                style.Append(styleParagraphProperties2);
                style.Append(styleTableProperties4);
    
                styles.Append(style);
    
                StyleDefinitionsPart styleDefinitionsPart = mainDocumentPart.AddNewPart<StyleDefinitionsPart>("Styles");
                styleDefinitionsPart.Styles = styles;
    
                #endregion
    
                mainDocumentPart.Document =
                new Document(
                    new Body(
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Paragraph(
                            new Run(
                                new Text("Test"))),
                        new Table(
                            new TableProperties(
                                new TableStyle() { Val = "TableGrid" },
                                new TableWidth() { Width = "0", Type = TableWidthUnitValues.Auto }),
                            new TableGrid(
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" },
                                new GridColumn() { Width = "2000" }),
                            new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 1")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 1"))))),
                           new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 2")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 2"))))),
                          new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 3")))),
                                new TableCell(
                                    new Paragraph(
                                        new ParagraphProperties(
                                            new KeepNext(),
                                            new KeepLines()),
                                        new Run(
                                        new Text("Table Row 3"))))),
                         new TableRow(
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4")))),
                                new TableCell(
                                    new Paragraph(
                                        new Run(
                                        new Text("Table Row 4"))))))));
            }