Here is the function that perform this task and a results:
from docx import Document
def merge_table_columns_with_equal_text(table, column_index):
"""
Merge cells in a specific column of a given table only if the value of the previous row cell
is the same as the value of the current row cell. Only leaves one value in the merged cell.
:param table: The table object from python-docx
:param column_index: The index of the column to merge
"""
num_rows = len(table.rows)
start_row = None
start_row_value = None
for i in range(1, num_rows):
current_cell = table.cell(i, column_index)
previous_cell = table.cell(i - 1, column_index)
current_value = current_cell.text
previous_value = previous_cell.text
if previous_value == current_value:
if start_row is None:
start_row = i - 1
start_row_value = table.cell(start_row, column_index).text
if i + 1 == num_rows: # if this is the last row
table.cell(start_row, column_index).merge(table.cell(i, column_index))
table.cell(start_row, column_index).text = start_row_value
elif start_row is not None:
table.cell(start_row, column_index).merge(table.cell(i - 1, column_index))
table.cell(start_row, column_index).text = start_row_value
start_row = None
def create_test_document():
data = [
('a', '1', 'x'),
('a', '1', 'y'),
('a', '1', 'y'),
('b', '2', 'z'),
('b', '3', 'z'),
('c', '3', 'z'),
('c', '3', 'z'),
]
document = Document()
table = document.add_table(rows=len(data), cols=len(data[0]))
for row_idx, row_data in enumerate(data):
for col_idx, value in enumerate(row_data):
table.cell(row_idx, col_idx).text = value
return document
if __name__ == '__main__':
doc = create_test_document()
table = doc.tables[0]
doc.save('z_test_1_before_merging.docx')
for column_index in range(0, table._column_count):
merge_table_columns_with_equal_text(table, column_index)
doc.save('z_test_2_after_merging.docx')