Algernon70
Algernon70

Reputation: 47

Problem with python-docx putting pictures in a table

I am using python-docx to create a new document and then I add a table (rows=1,cols=5). Then I add a picture to each of the five cells. I have the code working but what I see from docx is not what I see when I use Word manually.

Specifically, if I set on "Show Formatting Marks" and then look at what was generated by docx, there is always a hard return in the beginning of each of the cells (put there by the add_paragraph method.) When I use Word manually, there is no hard return.

The result of the hard return is that each picture is down one line from where I want it to be. If I use Word, the pictures are where I expect them to be.

What is also strange is that on the docx document I can manually go in and single click next to the hard return, press the down cursor key once, and then press the Backspace key once and the hard return is deleted and the picture moves to the top of the cell.

So my question is, does anyone know of a way to get a picture in a table cell without having a hard return put in when the add_paragraph method is executed?

Any help would be greatly appreciated.

def paragraph_format_run(cell):
    paragraph = cell.add_paragraph()
    format = paragraph.paragraph_format
    run = paragraph.add_run()
    
    format.space_before = Pt(0)
    format.space_after = Pt(0)
    format.line_spacing = 1.0
    format.alignment = WD_ALIGN_PARAGRAPH.CENTER
    
    return paragraph, format, run

def main():
    document = Document()
    
    sections = document.sections
    section = sections[0]
    
    section.top_margin = Inches(1.0)
    section.bottom_margin = Inches(1.0)
    section.left_margin = Inches(0.75)
    section.right_margin = Inches(0.75)
    
    table = document.add_table(rows=1, cols=5)
    table.allow_autofit = False
    
    cells = table.rows[0].cells

    for i in range(5):
        pic_path = f"Table_Images\pic_{i}.jpg"
        
        cell = cells[i]
        cell.vertical_alignment = WD_ALIGN_VERTICAL.TOP
        cell_p, cell_f, cell_r = paragraph_format_run(cell)
        
        cell_r.add_picture(pic_path, width=Inches(1.25))

    doc_path = "TableTest_1.docx"
    document.save(doc_path)

Upvotes: 4

Views: 5811

Answers (1)

scanny
scanny

Reputation: 28893

Each blank cell in a newly created table contains a single empty paragraph. This is just one of those things about the Word format. I suppose it gives a place to put the insertion mark (flashing vertical cursor) when you're using the Word application. A completely empty cell would have no place to "click" into.

This requires that any code that adds content to a cell must treat the first paragraph differently. In short, you access the first paragraph as cell.paragraphs[0] and only create second and later paragraphs with cell.add_paragraph().

So in this particular case, the paragraph_format_run() function would change like this:

def paragraph_format_run(cell):
    paragraph = cell.paragraphs[0]
    ...

This assumes a lot, like it only works when cell is empty, but given what you now know about cell paragraphs you may be able to adapt it to adding multiple images into a cell if later decide you need that.

Upvotes: 7

Related Questions