|
| 1 | +using Syncfusion.DocIO; |
| 2 | +using Syncfusion.DocIO.DLS; |
| 3 | +using System.Collections.Generic; |
| 4 | +using System.IO; |
| 5 | + |
| 6 | +namespace Split_table_by_bookmark |
| 7 | +{ |
| 8 | + class Program |
| 9 | + { |
| 10 | + static void Main(string[] args) |
| 11 | + { |
| 12 | + using (FileStream fileStreamPath = new FileStream(Path.GetFullPath(@"Data/Template.docx"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) |
| 13 | + { |
| 14 | + //Open an existing Word document. |
| 15 | + using (WordDocument document = new WordDocument(fileStreamPath, FormatType.Docx)) |
| 16 | + { |
| 17 | + //Get all the bookmarkstart in the cell. |
| 18 | + //If bookmark mentioned anywhere in table "tr" in file level, DocIO parsed inside cell only. |
| 19 | + List<Entity> bookmarkStart = document.FindAllItemsByProperty(EntityType.BookmarkStart, "OwnerParagraph.IsInCell", true.ToString()); |
| 20 | + //Find start and end row based on bookmark start. |
| 21 | + //Then split the table. |
| 22 | + for (int i = 0; i < bookmarkStart.Count; i++) |
| 23 | + { |
| 24 | + BookmarkStart start = bookmarkStart[i] as BookmarkStart; |
| 25 | + WTableRow startRow = GetOwnerRow(start); |
| 26 | + WTable table = startRow.Owner as WTable; |
| 27 | + WTableRow endRow; |
| 28 | + |
| 29 | + #region Find start and end row to split based on bookmark start |
| 30 | + //If there is any bookmark start further in table, |
| 31 | + //then get previous row of bookmark start. |
| 32 | + if (i < bookmarkStart.Count - 1) |
| 33 | + { |
| 34 | + //Get the owner row of next bookmark start. |
| 35 | + WTableRow ownerRow = GetOwnerRow(bookmarkStart[i + 1] as BookmarkStart); |
| 36 | + //Get the previous row. |
| 37 | + endRow = ownerRow.PreviousSibling as WTableRow; |
| 38 | + } |
| 39 | + //If there is no further bookmark start in table, consider last row as end of splitted table. |
| 40 | + else |
| 41 | + endRow = (startRow.Owner as WTable).LastRow; |
| 42 | + #endregion |
| 43 | + |
| 44 | + #region Split table |
| 45 | + //Split the table from start row to end row. |
| 46 | + WTable splittedTable = SplitTable(table, startRow.GetRowIndex(), endRow.GetRowIndex()); |
| 47 | + //Get the owner of table. |
| 48 | + WTextBody ownerBody = table.OwnerTextBody; |
| 49 | + int indexToInsert = ownerBody.ChildEntities.IndexOf(table) + i * 2 + 1; |
| 50 | + //Insert paragraph to differentiate two tables. |
| 51 | + //As per Microsoft Word behavior, if two tables without any paragraph between them, it will be treated as one table. |
| 52 | + WParagraph paragraph = new WParagraph(document); |
| 53 | + ownerBody.ChildEntities.Insert(indexToInsert, paragraph); |
| 54 | + //Add splitted table, next to the paragraph. |
| 55 | + indexToInsert++; |
| 56 | + ownerBody.ChildEntities.Insert(indexToInsert, splittedTable); |
| 57 | + #endregion |
| 58 | + } |
| 59 | + //Create file stream. |
| 60 | + using (FileStream outputFileStream = new FileStream(Path.GetFullPath(@"Output/Output.docx"), FileMode.Create, FileAccess.ReadWrite)) |
| 61 | + { |
| 62 | + //Save the Word document to file stream. |
| 63 | + document.Save(outputFileStream, FormatType.Docx); |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + #region Helper methods |
| 69 | + /// <summary> |
| 70 | + /// Split a table from the bookmarks start row to the end row. |
| 71 | + /// </summary> |
| 72 | + /// <param name="table">Table to split.</param> |
| 73 | + /// <param name="rowStartIndex">Start row index.</param> |
| 74 | + /// <param name="rowEndIndex">End row index.</param> |
| 75 | + static WTable SplitTable(WTable table, int rowStartIndex, int rowEndIndex) |
| 76 | + { |
| 77 | + //Clone the table. |
| 78 | + WTable clonedTable = table.Clone(); |
| 79 | + //Table should have atleast 1 row and 1 cell. |
| 80 | + clonedTable.ResetCells(1, 1); |
| 81 | + |
| 82 | + //Clone the rows from owner table to new table one by one. |
| 83 | + for (int i = rowStartIndex; i <= rowEndIndex; i++) |
| 84 | + { |
| 85 | + clonedTable.Rows.Add(table.Rows[i].Clone()); |
| 86 | + } |
| 87 | + //Remove the first row from cloned table. |
| 88 | + clonedTable.Rows.RemoveAt(0); |
| 89 | + |
| 90 | + //Delete those row from owner table. |
| 91 | + for (int i = rowEndIndex; i >= rowStartIndex; i--) |
| 92 | + { |
| 93 | + table.Rows.RemoveAt(i); |
| 94 | + } |
| 95 | + return clonedTable; |
| 96 | + } |
| 97 | + /// <summary> |
| 98 | + /// Get the owner row of bookmark start. |
| 99 | + /// </summary> |
| 100 | + /// <param name="bookmarkStart">Bookmark start to get owner row.</param> |
| 101 | + static WTableRow GetOwnerRow(BookmarkStart bookmarkStart) |
| 102 | + { |
| 103 | + if (bookmarkStart.OwnerParagraph.IsInCell) |
| 104 | + { |
| 105 | + return (bookmarkStart.OwnerParagraph.OwnerTextBody as WTableCell).OwnerRow; |
| 106 | + } |
| 107 | + return null; |
| 108 | + } |
| 109 | + #endregion |
| 110 | + } |
| 111 | +} |
0 commit comments