-1

I have been trying for a while to replace certain image strings located in cells in a table in a docx file with the related images located in a folder. Let a compiled list of all images = Images.

My 'best' attempt so far is to iterate through all table cells in the document and attempt this task, as seen in the code below.

for Image in Images:                            
    for table in document.tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    if Image in paragraph.text:
                        
                        for p in enumerate(cell.paragraphs):
                             img_paragraph = p[1]
                                               
                        runner = paragraph.add_run(img_paragraph)
                        runner.add_picture(f'{Image}.gif', width=Cm(1))
                        
                        paragraph.text = paragraph.text.replace(Image, "")

Unfortunately, I am getting the error code "TypeError: 'Paragraph' object is not iterable", but every time I solve one error code, I find myself staring at another.

I really appreciate you taking the time to read through this question.

Fonti
  • 133
  • 1
  • 9

1 Answers1

0

A start is to factor out some of the iteration:

def iter_target_paragraphs(document):
    """Generate each paragraph inside all tables of `document`."""
    for table in document.tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    yield paragraph

I don't think you're going to get any errors from that and it makes the core code more straightforward.

Then I'd use a more descriptive name for what appear to be image-filenames. Also, iterating the paragraphs is going to be a lot slower than iterating filenames, so I'd reverse the order/nesting:

for paragraph in iter_target_paragraphs():
    for image_filename in image_filenames:
        if image_filename in paragraph.text:
            substitute_image_placeholder(paragraph, image_filename)

I don't expect this to (directly) raise errors either, so that leaves us with the substitute_image_placeholder() function. I think this will do the basic job:

def substitute_image_placeholder(paragraph, image_filename):
    # --- start with removing the placeholder text ---
    paragraph.text = paragraph.text.replace(image_filename, "")
    # --- then append a run containing the image ---
    run = paragraph.add_run()
    run.add_picture(f'{image_filename}.gif', width=Cm(1))

This is not "perfect" in that the location of the image will always be at the end of the paragraph, not right where the placeholder was, but that seemed to be what your original code was trying to do maybe that's what you're looking for.

If you needed the image to "replace" the placeholder in the middle of the paragraph somewhere then you'll need to isolate the placeholder text into its own run. There's another answer here that shows what that takes to accomplish:
https://stackoverflow.com/a/68507579/1902513

scanny
  • 26,423
  • 5
  • 54
  • 80