diff --git a/Examples/ApiExamples/ApiExamples/ExTable.cs b/Examples/ApiExamples/ApiExamples/ExTable.cs
index 66b8d3be..56ab17bc 100644
--- a/Examples/ApiExamples/ApiExamples/ExTable.cs
+++ b/Examples/ApiExamples/ApiExamples/ExTable.cs
@@ -1696,5 +1696,201 @@ public void GetTextFromCells()
}
//ExEnd
}
+
+ [Test]
+ public void ConvertWithParagraphMark()
+ {
+ Document doc = new Document(MyDir + "Nested tables.docx");
+ Table table = (Table)doc.GetChild(NodeType.Table, 0, true);
+
+ // Replace the table with the new paragraph
+ ConvertTable(table);
+
+ table.Remove();
+
+ doc.Save(ArtifactsDir + "output.docx");
+ }
+
+ ///
+ /// Recursively converts nested tables within a given table.
+ ///
+ /// The table to be converted.
+ private void ConvertTable(Table table)
+ {
+ Node currentNode = table;
+ foreach (Row row in table.Rows)
+ {
+ foreach (Cell cell in row.Cells)
+ {
+ // Get all nested tables within the current cell.
+ NodeCollection nestedTables = cell.GetChildNodes(NodeType.Table, true);
+ if (nestedTables.Count != 0)
+ foreach (Table nestedTable in nestedTables)
+ ConvertTable(nestedTable);
+
+ // Get the text content of the cell and trim any whitespace.
+ var cellText = cell.GetText().Trim();
+ if (cellText == string.Empty)
+ break;
+
+ foreach (Paragraph cellPara in cell.Paragraphs)
+ currentNode = table.ParentNode.InsertAfter(cellPara.Clone(true), currentNode);
+ }
+ }
+ }
+
+ [Test]
+ public void ConvertWith()
+ {
+ Document doc = new Document(MyDir + "Nested tables.docx");
+ Table table = (Table)doc.GetChild(NodeType.Table, 0, true);
+
+ // Convert table to text with specified separator.
+ ConvertWith(ControlChar.Tab, table);
+ // Remove table after convertion.
+ table.Remove();
+
+ doc.Save(ArtifactsDir + "Table.ConvertWith.docx");
+ }
+
+ ///
+ /// Converts the content of a table into a series of paragraphs, separated by a specified separator.
+ ///
+ /// The string used to separate the content of each cell.
+ /// The table to be converted.
+ private void ConvertWith(string separator, Table table)
+ {
+ Document doc = (Document)table.Document;
+ Node currentPara = table.NextSibling;
+ foreach (Row row in table.Rows)
+ {
+ double tabStopWidth = 0;
+ // By default MS Word adds 1.5 line spacing bitween paragraphs.
+ ((Paragraph)currentPara).ParagraphFormat.LineSpacing = 18;
+ foreach (Cell cell in row.Cells)
+ {
+ NodeCollection nestedTables = cell.GetChildNodes(NodeType.Table, true);
+ // If there are nested tables, process each one.
+ if (nestedTables.Count != 0)
+ foreach (Table nestedTable in nestedTables)
+ ConvertWith(separator, nestedTable);
+
+ ParagraphCollection paragraphs = cell.Paragraphs;
+ foreach (Paragraph paragraph in paragraphs)
+ {
+ // If there's more than one paragraph and it's not the first, clone and insert it after the current paragraph.
+ if (paragraphs.Count > 1 && !paragraph.Equals(cell.FirstParagraph))
+ {
+ Node node = currentPara.ParentNode.InsertAfter(paragraph.Clone(true), currentPara);
+ currentPara = node;
+ }
+ else if (currentPara.NodeType == NodeType.Paragraph)
+ {
+ // If the current cell is not the first cell, append a separator.
+ if (!cell.IsFirstCell)
+ {
+ ((Paragraph)currentPara).AppendChild(new Run(doc, separator));
+ // If the separator is a tab, calculate the tab stop position based on the width of the previous cell.
+ if (separator == ControlChar.Tab)
+ {
+ var previousCell = cell.PreviousCell;
+ if (previousCell != null)
+ tabStopWidth += previousCell.CellFormat.Width;
+
+ // Add a tab stop at the calculated position.
+ TabStop tabStop = new TabStop(tabStopWidth, TabAlignment.Left, TabLeader.None);
+ ((Paragraph)currentPara).ParagraphFormat.TabStops.Add(tabStop);
+ }
+ }
+
+ // Clone and append all child nodes of the paragraph to the current paragraph.
+ var childNodes = paragraph.GetChildNodes(NodeType.Any, true);
+ if (childNodes.Count > 0)
+ foreach (Node node in childNodes)
+ ((Paragraph)currentPara).AppendChild(node.Clone(true));
+ }
+ }
+ }
+
+ currentPara = currentPara.ParentNode.InsertAfter(new Paragraph(doc), currentPara);
+ }
+ }
+
+ [Test]
+ public void GetColSpanRowSpan()
+ {
+ Document doc = new Document(MyDir + "merged.docx");
+
+ var table = (Table)doc.GetChild(NodeType.Table, 0, true);
+ // Convert cells with merged columns into a format that can be easily manipulated.
+ table.ConvertToHorizontallyMergedCells();
+
+ foreach (Row row in table.Rows)
+ {
+ var cell = row.FirstCell;
+
+ while (cell != null)
+ {
+ var rowIndex = table.IndexOf(row);
+ var cellIndex = cell.ParentRow.IndexOf(cell);
+
+ var rowSpan = 1;
+ var colSpan = 1;
+
+ // Check if the current cell is the start of a vertically merged set of cells.
+ if (cell.CellFormat.VerticalMerge == CellMerge.First)
+ rowSpan = CalculateRowSpan(table, rowIndex, cellIndex);
+
+ // Check if the current cell is the start of a horizontally merged set of cells.
+ if (cell.CellFormat.HorizontalMerge == CellMerge.First)
+ cell = CalculateColSpan(cell, out colSpan);
+ else
+ cell = cell.NextCell;
+
+ Console.WriteLine($"RowIndex = {rowIndex}\t ColSpan = {colSpan}\t RowSpan = {rowSpan}");
+ }
+ }
+ }
+
+ ///
+ /// Calculates the row span for a cell in a table.
+ ///
+ /// The table containing the cell.
+ /// The index of the row containing the cell.
+ /// The index of the cell within the row.
+ /// The number of rows spanned by the cell.
+ private int CalculateRowSpan(Table table, int rowIndex, int cellIndex)
+ {
+ var rowSpan = 1;
+ for (int i = rowIndex; i < table.Rows.Count; i++)
+ {
+ var currentRow = table.Rows[i + 1];
+ var currentCell = currentRow.Cells[cellIndex];
+ if (currentRow == null || currentCell.CellFormat.VerticalMerge != CellMerge.Previous)
+ break;
+
+ rowSpan++;
+ }
+ return rowSpan;
+ }
+
+ ///
+ /// Calculates the column span of a cell based on its horizontal merge settings.
+ ///
+ /// The cell for which to calculate the column span.
+ /// The resulting column span value.
+ /// The next cell in the sequence after calculating the column span.
+ private Cell CalculateColSpan(Cell cell, out int colSpan)
+ {
+ colSpan = 1;
+
+ cell = cell.NextCell;
+ while (cell != null && cell.CellFormat.HorizontalMerge == CellMerge.Previous)
+ {
+ colSpan++;
+ cell = cell.NextCell;
+ }
+ return cell;
+ }
}
}
\ No newline at end of file