pythonautomationformattingpowerpointpython-pptx

python-pptx access table cell properties and apply it back during replace


I am trying to replace the table headers in powerpoint using python-pptx using the code below

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):
            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(str(match), str(replacement))
                            cell.text = new_text


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

While this does the replacement successfully, but the terms after replacement lose the formatting such as font size, font color and alignment. example like below

enter image description here

When I press cell.f tab,it only populates for and find. When I press cell.c tab, it only populates curr_text, cell, cells. I was expecting to see color but it doesn't show up.

So, I tried the below but they returned None

            for cell in row.cells:
                for paragraph in cell.text_frame.paragraphs:
                    print(paragraph.font.size)
                    print(paragraph.font.color)
                    print(paragraph.font.alignment)

Along with value replacement, I would also like to explicitly code in my for loop to assign/copy the same format (such as font size, font color etc) to my replacement term as well.

I would like to extract the properties of cell (font color, font size etc) in a table and assign it back to same cell (after replacement)


Solution

  • Answering my own question for the benefit of others. I drilled down to run level to extract the font properties like name, size and reassigned it back to my replacement text. This solved the problem for me

       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