Search code examples
pythonreplaceformattingpowerpointpython-pptx

python-pptx format and alignment lost for specific tables and their headers


I am trying to automate the powerpoint find and replace using a python code.

With the help of multiple SO posts, I managed to get to the below piece of code which does the replacement of keywords by looping through all slides in a PPT. The issue below happens only for certain tables and rest of the tables work fine (no issues in formatting, font size, color etc) but certain tables have the below 3 issues (am not sure why)

slides = [slide for slide in ip_ppt.slides]
shapes = []
for slide in slides:
    for shape in slide.shapes:
        shapes.append(shape)

def replace_text(replacements:dict,shapes:list):
    """Takes dict of {match: replacement, ... } and replaces all matches.
    Currently not implemented for charts or graphics.
    """
    for shape in shapes:
        for match, replacement in replacements.items():
            if shape.has_text_frame:
                if (shape.text.find(match)) != -1:
                    text_frame = shape.text_frame
                    for paragraph in text_frame.paragraphs:
                        for run in paragraph.runs:
                            cur_text = run.text
                            new_text = cur_text.replace(str(match), str(replacement))
                            run.text = new_text
            if shape.has_table:
                for row in shape.table.rows:
                    for cell in row.cells:
                        if match in cell.text:
                            new_text = cell.text.replace(match, replacement)
                            cell.text = new_text


replace_text({'FY1920':'FY20/21'},shapes)
replace_text({'FY2021':'FY21/22'},shapes)
replace_text({'FY2122':'FY22/23'},shapes)

While this works correctly for 90% of the cases, I do encounter few scenarios like below. Is there anyway to identify these tables by name and make those changes?

a) Only for Certain table column headers, font color is changed (after replacement)

enter image description here

b) Only for Certain tables, overlap issue occurs (after replacement) (because they become big in size) shown below

enter image description here

c) Only for Certain tables, column headers font size and alignment differs shown below

enter image description here

How can I avoid the above 3 scenarios from happening?

Ideally, the code above isn't supposed to cause these issues but now that it has done, I am looking for some simple way to fix these issues (doesn't have to be efficient or elegant).

Is there anyway to tell/enforce the code (during for loop) explicitly to keep the same font color, font size, font alignment etc.


Solution

  • Answering my own question. I managed to solve this by drilling down to run level and reassigning the font size and name to my text. So, format is retained

    Please find my updated code for table section

               if shape.has_table:
                    for row in shape.table.rows:
                        for cell in row.cells:
                            paras = cell.text_frame.paragraphs
                            for para in paras:
                                #print(para.text)
                                for run in para.runs:
                                    if match in run.text:
                                        new_text = run.text.replace(str(match), str(replacement))
                                        fn = run.font.name
                                        fz = run.font.size 
                                        run.text = new_text
                                        run.font.name = fn
                                        run.font.size = fz