Merge Table Cells
Sometimes certain rows in a table require a heading or large blocks of text that take up the full width of the table. For proper design of the table, the user can merge several table cells into one. Aspose.Words supports merged cells when working with all input formats, including importing HTML content.
How to Merge Table Cells
In Aspose.Words, merged cells are represented by the following properties of the CellFormat class:
- HorizontalMerge which describes if the cell is a part of a horizontal merge of cells
- VerticalMerge which describes if the cell is a part of a vertical merge of cells
The values of these properties determine the merge behavior of cells:
- The first cell in a sequence of merged cells will have CellMerge.First
- Any subsequently merged cells will have CellMerge.Previous
- A cell that is not merged will have CellMerge.None
Check if Cell is Merged
To check if a cell is part of a sequence of merged cells, we simply check the HorizontalMerge and VerticalMerge properties.
The following code example shows how to print the horizontal and vertical cell merge type:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Table with merged cells.docx") | |
table = doc.get_child(aw.NodeType.TABLE, 0, True).as_table() | |
for row in table.rows: | |
for cell in row.as_row().cells: | |
print(self.print_cell_merge_type(cell.as_cell())) |
Merge Table Cells When Using DocumentBuilder
To merge cells in a table created with the DocumentBuilder, you need to set the appropriate merge type for each cell where the merge is expected – first CellMerge.First and then CellMerge.Previous.
Also, you must remember to clear the merge setting for those cells where no merge is required – this can be done by setting the first non-merge cell to CellMerge.None. If this is not done, all cells in the table will be merged.
The following code example shows how to create a table with two rows where the cells in the first row are merged horizontally:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document() | |
builder = aw.DocumentBuilder(doc) | |
builder.insert_cell() | |
builder.cell_format.horizontal_merge = aw.tables.CellMerge.FIRST | |
builder.write("Text in merged cells.") | |
builder.insert_cell() | |
# This cell is merged to the previous and should be empty. | |
builder.cell_format.horizontal_merge = aw.tables.CellMerge.PREVIOUS | |
builder.end_row() | |
builder.insert_cell() | |
builder.cell_format.horizontal_merge = aw.tables.CellMerge.NONE | |
builder.write("Text in one cell.") | |
builder.insert_cell() | |
builder.write("Text in another cell.") | |
builder.end_row() | |
builder.end_table() | |
doc.save(ARTIFACTS_DIR + "WorkingWithTables.horizontal_merge.docx") |
The following code example shows how to create a two-column table where the cells in the first column are vertically merged:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document() | |
builder = aw.DocumentBuilder(doc) | |
builder.insert_cell() | |
builder.cell_format.vertical_merge = aw.tables.CellMerge.FIRST | |
builder.write("Text in merged cells.") | |
builder.insert_cell() | |
builder.cell_format.vertical_merge = aw.tables.CellMerge.NONE | |
builder.write("Text in one cell") | |
builder.end_row() | |
builder.insert_cell() | |
# This cell is vertically merged to the cell above and should be empty. | |
builder.cell_format.vertical_merge = aw.tables.CellMerge.PREVIOUS | |
builder.insert_cell() | |
builder.cell_format.vertical_merge = aw.tables.CellMerge.NONE | |
builder.write("Text in another cell") | |
builder.end_row() | |
builder.end_table() | |
doc.save(ARTIFACTS_DIR + "WorkingWithTables.vertical_merge.docx") |
Merge Table Cells in Other Cases
In other situations where the DocumentBuilder is not used, such as in an existing table, merging cells in the previous way may not be as easy. Instead, we can wrap the basic operations involved in applying merge properties to cells in a method that makes the task much easier. This method is similar to the Merge automation method, which is called to merge a range of cells in a table.
The code below will merge the table cells in the specified range, starting at the given cell and ending at the end cell. In this case, the range can span multiple rows or columns:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
@staticmethod | |
def merge_cells(start_cell: aw.tables.Cell, end_cell: aw.tables.Cell): | |
parent_table = start_cell.parent_row.parent_table | |
# Find the row and cell indices for the start and end cell. | |
start_cell_pos = drawing.Point(start_cell.parent_row.index_of(start_cell), parent_table.index_of(start_cell.parent_row)) | |
end_cell_pos = drawing.Point(end_cell.parent_row.index_of(end_cell), parent_table.index_of(end_cell.parent_row)) | |
# Create a range of cells to be merged based on these indices. | |
# Inverse each index if the end cell is before the start cell. | |
merge_range = drawing.Rectangle( | |
min(start_cell_pos.x, end_cell_pos.x), | |
min(start_cell_pos.y, end_cell_pos.y), | |
abs(end_cell_pos.x - start_cell_pos.x) + 1, | |
abs(end_cell_pos.y - start_cell_pos.y) + 1) | |
for row in parent_table.rows: | |
row = row.as_row() | |
for cell in row.cells: | |
cell = cell.as_cell() | |
current_pos = drawing.Point(row.index_of(cell), parent_table.index_of(row)) | |
# Check if the current cell is inside our merge range, then merge it. | |
if merge_range.contains(current_pos): | |
cell.cell_format.horizontal_merge = aw.tables.CellMerge.FIRST if current_pos.x == merge_range.x else aw.tables.CellMerge.PREVIOUS | |
cell.cell_format.vertical_merge = aw.tables.CellMerge.FIRST if current_pos.y == merge_range.y else aw.tables.CellMerge.PREVIOUS | |
The following code example shows how to merge a range of cells between two specified cells:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Table with merged cells.docx") | |
table = doc.first_section.body.tables[0] | |
# We want to merge the range of cells found inbetween these two cells. | |
cell_start_range = table.rows[0].cells[0] | |
cell_end_range = table.rows[1].cells[1] | |
# Merge all the cells between the two specified cells into one. | |
self.merge_cells(cell_start_range, cell_end_range) | |
doc.save(ARTIFACTS_DIR + "WorkingWithTables.merge_cell_range.docx") |
Depending on the version of the Framework you are using, you may want to refine this method by turning it into an extension method. In this case, you can call this method directly on a cell to merge a range of cells, such as cell1.Merge(cell2)
.
Convert to Horizontally Merged Cells
Sometimes it is not possible to detect which cells are merged because some newer versions of Microsoft Word no longer use the merge flags when cells are merged horizontally. But for situations where cells are merged into a cell horizontally by their width using merge flags, Aspose.Words provides the ConvertToHorizontallyMergedCells
method to convert cells. This method simply transforms the table and adds new cells as needed.
The following code example shows the above method in operation:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Table with merged cells.docx") | |
table = doc.first_section.body.tables[0] | |
# Now merged cells have appropriate merge flags. | |
table.convert_to_horizontally_merged_cells() |