Search code examples
pythonpython-docx

How to change alignment of cell text in MS Word table without "paragraph" object


I have a MS Word "template" file that I am opening, modifying with new data from various sources, and then saving as a new file. I have multiple tables in the template document which are appropriately styled, including centered text inside of table cells.

Having some familiarity with the python-docx module, I am able to alter the table's data easily, by assigning new values to cell.text. However, whenever I assign cell.text a new value, the new data is no longer centered, but is instead left-justified.

I have browsed several similar questions, but all of the answers seem to involve modifying paragraph objects. This post was helpful and provided a quick POC, but also doesn't deal with cells, but instead adding paragraphs to tables. However, it was helpful seeing that paragraph objects have an alignment attribute.

# Example table
table = doc.add_table(rows=0, cols=2)
row = table.add_row().cells

p=row[0].add_paragraph('center justified text')
p.alignment = WD_ALIGN_PARAGRAPH.CENTER

p.alignment
>>> 1

For my current case, I noticed that cells do not have the alignment attribute. I then tried to modify the paragraph objects, but nothing changes.

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
doc = Document(BASE_DOC)

# test table, row, and cell
table = doc.tables[1]
row = table.rows[4]
cells = row.cells
cells[0].alignment
>>> AttributeError: '_Cell' object has no attribute 'alignment'

# attempt to modify paragraph alignment in table cells
for col in table.columns:
    for cell in col.cells:
        for par in cell.paragraphs:
            par.alignment = WD_ALIGN_PARAGRAPH.CENTER

doc.save(NEW_DOC)


Solution

  • Assigning to _Cell.text is a convenient and compact way to set the contents of a cell to a known state. To do this, _Cell.text removes all content from the cell and then adds a single paragraph containing a single run containing the text you specified.

    Because run and paragraph formatting is part of the run or paragraph it formats, all run formatting and all paragraph formatting disappears when you assign to _Cell.text. This is part of the "setting to known state" bit.

    If you apply your paragraph centering after assigning to _Cell.text, you will see it reflected in the output.

    Alternatively, you would avoid assigning to _Cell.text and navigate the existing paragraphs and runs yourself.