1

I want a paragraph inside a cell, but I get a stray carriage return which pushes down the text by one line:

enter image description here

My code:

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Cm


document = Document()
document.add_heading("The Heading", 1).alignment = WD_ALIGN_PARAGRAPH.CENTER

table = document.add_table(rows=0, cols=2)
table.style = 'Table Grid'
for i in range(3):
    row_cells = table.add_row().cells
    row_cells[0].text = 'row {}, col 1'.format(i)
    row_cells[0].width = Cm(3)
    row_cells[1].width = Cm(8)
    p = row_cells[1].add_paragraph()
    p.add_run('This is an example of')
    p.add_run(' some text').bold = True
    p.add_run(' in a table cell.')

document.save('test.docx')

How can I get the cell text to align at the top of the cell without the stray CR? And how should I be setting the cell widths to 3 cm and 8 cm: setting _Cell.width isn't respected.

xnx
  • 24,509
  • 11
  • 70
  • 109

2 Answers2

3

I worked this out: you get a free paragraph with each cell, so I just needed to add my text runs to this paragraph:

p = row_cells[1].paragraphs[0]
p.add_run('This is an example of')
p.add_run(' some text').bold = True
p.add_run(' in a table cell.')

To set the widths, I had to manipulate the columns directly and not set them cell-by-cell (despite this answer):

table.columns[0].width = Cm(3)
table.columns[1].width = Cm(8)
xnx
  • 24,509
  • 11
  • 70
  • 109
  • 1
    The WordprocessingML ISO spec requires a minimum of one paragraph inside each table cell. This makes some sense from a Word UI perspective as there wouldn't be any place to put your insertion point in the cell otherwise. But it does unfortunately make the code to add cell content special-case for the first paragraph. There's an internal call `cell._element.clear_content()` which can help. This removes any existing content (including default empty paragraph) and then adding multiple paragraphs is uniform. Note it leaves cell in invalid state if no content is added after. – scanny Nov 14 '18 at 18:48
  • Thank you for this clarification: I was trying to use the `clear` function instead and found it wasn't working. – xnx Nov 15 '18 at 14:28
0

Tanks for the clear_content it made my image not to be placed beneath a linefeed, tanks for the coment, it was the last pice of advice I needed after hours of problemsolving:

#This seams to clear the content in my cell
tables[1].rows[0].cells[4]._element.clear_content()

#Then when the image is inserted to the cell it is not placed one linefeed down.
img = tables[1].rows[0].cells[4].add_paragraph().add_run().add_picture('AgressoLogga.png', width=Inches(0.4))
Michael Larsson
  • 187
  • 2
  • 11