Skip to content

Tables

Tables are built structurally rather than by column count. doc.AddTable() returns an empty table, AddRow() appends a row, and AddCell() appends a cell to that row. Nothing fixes the number of columns in advance, so a table is only as regular as the rows you add to it.

table := doc.AddTable()
table.Properties().SetWidthPercent(100)

row := table.AddRow()
row.AddCell().AddParagraph().AddRun().AddText("Name")
row.AddCell().AddParagraph().AddRun().AddText("Value")

A cell holds paragraphs, not text. AddCell() gives you a cell and you still need AddParagraph() and AddRun() before any characters appear, which is why the snippet chains four calls to write one string. The same is true in reverse: a cell can hold several paragraphs, a nested table, or a structured document tag, and Word will not open a file whose cell does not end with a paragraph.

Where the settings live

Four Properties() calls return four different types, and picking the wrong level is the usual reason a setting appears to do nothing.

LevelTypeCovers
table.Properties()TablePropertiesWidth, alignment on the page, layout, table borders, style name, table look.
row.Properties()RowPropertiesHeight, splitting across pages, repeating as a header row.
cell.Properties()CellPropertiesCell width, shading, column span, vertical merge, vertical alignment, cell borders and margins.
paragraph.Properties()ParagraphPropertiesHorizontal alignment of the text, spacing, keep-with-next.

Width comes in an absolute form and a percentage form on both tables and cells: SetWidth takes a measurement.Distance and SetWidthPercent takes a number from 0 to 100. They are alternatives rather than a pair. Both write the same underlying width element, so setting one after the other keeps only the value set last, with no error and no combination of the two. SetWidthAuto() is the third option and hands sizing back to the layout engine.

Cell widths are preferences, not commands. Under the default autofit layout Word may override them to fit the content; table.Properties().SetLayout(wml.ST_TblLayoutTypeFixed) is what makes them binding.

Horizontal and vertical merging use different mechanisms. A cell spanning columns is one cell with SetColumnSpan(n), while a vertical merge is declared per row, with wml.ST_MergeRestart on the top cell and wml.ST_MergeContinue on each cell below it. Only the restart cell’s text is rendered.

Where to look

GuideCovers
Create and Format a TableRows and cells, widths, borders, shading, column and vertical spans, row height, and table styles with banding.
Paragraphs in CellsSeveral paragraphs in one cell, positioning them relative to each other, and nesting tables.
Keep a Row on One PageStopping a row from splitting across a page break, and the related keep-with-next setting.
Last updated on