@Nachti Please try using the following code. It uses LayoutCollector
and LayoutEnumerator
to determine where the table need to be split. One contiotion is the page index change and another X coordinate of the row change (column break):
Document doc = new Document(@"C:\Temp\in.docx");
LayoutCollector collector = new LayoutCollector(doc);
LayoutEnumerator enumerator = new LayoutEnumerator(doc);
NodeCollection tables = doc.GetChildNodes(NodeType.Table, true);
foreach (Table t in tables)
{
// Process only top level table in the main document's body.
if (t.ParentNode.NodeType != NodeType.Body)
continue;
Table table = t;
while (table != null)
{
table = SplitTalbeTextColumns(table, collector, enumerator);
if (table != null)
{
// Do not update layout if it is not required.
collector.Clear();
doc.UpdatePageLayout();
}
}
}
doc.Save(@"C:\Temp\out.docx");
private static Table SplitTalbeTextColumns(Table table, LayoutCollector collector, LayoutEnumerator enumerator)
{
int startPageIndex = collector.GetStartPageIndex(table.FirstRow);
enumerator.Current = collector.GetEntity(table.FirstRow.FirstCell.FirstParagraph);
while (enumerator.Type != LayoutEntityType.Row)
enumerator.MoveParent();
double startRowX = enumerator.Rectangle.Left;
int breakIndex = -1;
int firstDataRowIndex = -1;
// Determine index of row where page breaks. And index of the first data row.
for (int i = 1; i < table.Rows.Count; i++)
{
Row r = table.Rows[i];
if (!r.RowFormat.HeadingFormat && firstDataRowIndex < 0)
firstDataRowIndex = i;
int rowPageIndex = collector.GetEndPageIndex(r);
if (rowPageIndex > startPageIndex)
{
breakIndex = i;
break;
}
// Determine X coordinate of the row.
enumerator.Current = collector.GetEntity(r.FirstCell.FirstParagraph);
while (enumerator.Type != LayoutEntityType.Row)
enumerator.MoveParent();
double currentRowX = enumerator.Rectangle.Left;
if (startRowX != currentRowX)
{
breakIndex = i;
break;
}
}
if (breakIndex > 0)
{
Table clone = (Table)table.Clone(true);
// Insert a cloned table after the main table.
Paragraph para = new Paragraph(table.Document);
para.AppendChild(new Run(table.Document, ControlChar.ColumnBreak + "Continuation of the table"));
table.ParentNode.InsertAfter(para, table);
para.ParentNode.InsertAfter(clone, para);
// Remove content after the breaking row from the main table.
while (table.Rows.Count > breakIndex)
table.LastRow.Remove();
// Remove rows before the breaking row from the clonned table.
for (int i = 1; i < breakIndex; i++)
clone.Rows.RemoveAt(firstDataRowIndex);
return clone;
}
return null;
}
FYI: @Eduardo_Canal