Search code examples
pythonpython-docx

python-doxc table cell align adds a new line


I want to right align the text inside a table cell of a Word document created with python-docx. I followed this advice, but the problem with it is that a new line is added inside de cell before the text, so the vertical alignment is broken.

This is the code without the right alignment setting:

table = document.add_table(rows=1, cols=4)
hdr_cells = table.rows[0].cells

hdr_cells[0].width = Inches(0.1)
hdr_cells[1].width = Inches(10)
hdr_cells[2].width = Inches(1)
hdr_cells[3].width = Inches(1)

for entry in context['invoices']['entries']:
    row_cells = table.add_row().cells
    row_cells[0].text = str(entry['amount'])
    row_cells[1].text = entry['line']
    row_cells[2].text = entry['unit_price_label']
    row_cells[3].text = entry['subtotal']

And this is the resulting document: enter image description here

This is the code with the right alignment setting:

table = document.add_table(rows=1, cols=4)
hdr_cells = table.rows[0].cells

hdr_cells[0].width = Inches(0.1)
hdr_cells[1].width = Inches(10)
hdr_cells[2].width = Inches(1)
hdr_cells[3].width = Inches(1)

for entry in context['invoices']['entries']:
    row_cells = table.add_row().cells
    row_cells[0].text = str(entry['amount'])
    row_cells[1].text = entry['line']
    row_cells[2].add_paragraph(entry['unit_price_label']).alignment = WD_ALIGN_PARAGRAPH.RIGHT
    row_cells[3].add_paragraph(entry['subtotal']).alignment = WD_ALIGN_PARAGRAPH.RIGHT

And the resulting document:

enter image description here

Is there any way to avoid this carriage return when right aligning table cells with python-docx?


Solution

  • Short answer: Yes, use

    row_cells[0].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT
    

    A table cell must always include at least one paragraph; this is prescribed by the ISO 29500 spec (and makes sense once you look into it deeply enough).

    In accordance with this requirement, a new (and empty) cell contains a single empty paragraph. If you call .add_paragraph() on an empty cell, then you end up with two paragraphs.

    So the secret to avoiding extra paragraphs is to start by using the one you already have. Only if you need more than one paragraph do you call .add_paragraph().

    The single existing paragraph is accessed as cell.paragraphs[0] and can be manipulated the same way as any other paragraph in python-docx