Keep a Row on One Page
By default Word will break a table row across a page boundary, leaving the top
half of the text on one page and the rest on the next. SetCantSplit(true) on
the row properties turns that off: the row moves to the next page whole rather
than splitting. It is the inverse of the “Allow row to break across pages”
checkbox in Word’s table properties, so setting it to true is what unchecking
that box does.
Four settings in this area sound alike and do different things.
| Call | Scope | Effect |
|---|---|---|
row.Properties().SetCantSplit(true) | One row | The row is never split by a page break. It moves to the next page intact. |
para.Properties().SetKeepWithNext(true) | One paragraph | The paragraph stays on the same page as the content that follows it. |
para.Properties().SetKeepOnOnePage(true) | One paragraph | All lines of that paragraph stay together. |
row.Properties().SetTblHeader(true) | One row | The row repeats as a header at the top of each page the table spans. |
SetCantSplit is the one you want for a row whose cells hold a few lines each.
SetKeepWithNext on the paragraphs in a row pulls the following content along
with it, which is how you keep a label row attached to the row it describes.
Neither prevents the table itself from breaking; they only control where the
break is allowed to land.
Doing it
for i := 0; i < 25; i++ {
row := table.AddRow()
row.Properties().SetCantSplit(true)
para := row.AddCell().AddParagraph()
para.Properties().SetKeepWithNext(true)
para.AddRun().AddText(fmt.Sprintf("Row No. %d", i+1))
}Set the property per row as you build. There is no table-level switch that
applies it to every row, so a loop that adds rows has to call it inside the
loop. SetCantSplit(false) does not just turn the flag off, it clears the row’s
property list entirely.
Limitations
SetCantSplit, SetHeight and SetTblHeader all replace the row’s property
list rather than adding to it, so only the last of them called takes effect.
Calling SetHeight and then SetCantSplit on the same row silently drops the
height, and calling them the other way around drops the unsplittable flag. Until
that changes, a row can carry exactly one of the three.
A row that does not fit in the space left on the page moves to the next page
whole. A row taller than a whole page has nowhere to move to, and both Word and
UniOffice’s own PDF conversion truncate it rather than split it, so the content
past the bottom of the page is lost. SetCantSplit suits rows a few lines tall.
On a row whose cells hold a page or more of text, leaving the default in place
is the safer choice. Setting wml.ST_HeightRuleExact on a row height has the
same truncating effect for the same reason.
The flag is a layout instruction stored in the file, so nothing about it shows
until something paginates the document. Converting to PDF with
document/convert honors it.
Run the example
The example writes several paragraphs of filler text, then builds a 25 row table
where every row is marked unsplittable and every cell paragraph is marked keep
with next, so the table crosses a page boundary with the rows intact. It ships
with table-row-cant-split.docx, the expected output, for comparison.
git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/table-row-cant-split
go run main.goIf this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.