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)
b) Only for Certain tables, overlap issue occurs (after replacement) (because they become big in size) shown below
c) Only for Certain tables, column headers font size and alignment differs shown below
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.
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