How do I keep docx line format when using python pandas to replace a word in a line?

enter image description here
enter image description here

After the file is edited (with a real customer replacing Sample Customer, the format has been changed to the second image)

I am having some font issues editing a base word document template.
I’m trying to automate something to save me time, so I use pandas library to read in an excel file.
Then, after some data cleaning, I open a docx file and loop through each customer in the pandas dataframe and replace the placeholder customer in my template file with the grabbed customer and also the same thing for another value further down the document.

This all sort of works. It replaces the proper words and numbers, but it changes the format of the entire line to the base formatting.
I’ve tried so many things, but what’s perplexing me is that I even resorted to hard coding the format, but it’s still altering the entire line where one part of the string is changed.

Is there a way to achieve what I want? When the if condition in the loop is met, just change the word or number and retain the line’s formatting rules?

from docx import Document

import os

word_doc_path = r"\\placeholder\placeholder.docx"


#data cleaning

valid_customers = excel_data.iloc[1:-1, 1].dropna().astype(str)

valid_customers = valid_customers[valid_customers != "Customer"]

valid_customers = valid_customers[valid_customers != "Customer "]

valid_customers = valid_customers[valid_customers != "Intensity"]

#data cleaning end
 

for customer in valid_customers:

   print(f"Processing customer: {customer}")

   customer_data = excel_data[excel_data.iloc[:, 1].astype(str) == customer]

   print(customer_data)

   if not customer_data.empty:

       value_2023 = round(customer_data.iloc[0, 4], 2)

       doc = Document(word_doc_path)

       print(f"Processing {customer} - Document Loaded")

       for paragraph in doc.paragraphs:

           if "Sample Customer" in paragraph.text:

               for run in paragraph.runs: #trying to hard code formatting

                   run.font.name="Calibri"

                   run.font.size = Pt(14)

                   run.font.bold = True

                   run.font.underline = True  

               paragraph.text = paragraph.text.replace("Sample Customer", customer)

           if "tonnes" in paragraph.text:

               for run in paragraph.runs:

                   run.font.name="Calibri"

                   run.font.size = Pt(14)

                   run.font.bold = True

               index_tonnes = paragraph.text.find("tonnes")

               number_before_tonnes = paragraph.text[:index_tonnes].rsplit(maxsplit=1)[-1]

               paragraph.text = paragraph.text.replace(number_before_tonnes, str(value_2023))

       word_save_path = fr'\\placeholder\placeholder.docx'
 

       if os.path.exists(word_save_path):

           os.remove(word_save_path)

       doc.save(word_save_path)

       print(f"{customer} - Word Document Saved at: {word_save_path}")

I’ve tried both the hard-coding the format, copying the line and reinserting it after alter, but keeping the formatting is tricky for me. Nothing seems to work.

  • Can you provide an example placeholder docx that shows the problem?

    – 

  • Absolutely. One minute please.

    – 

  • I couldn’t see an insert file option so I took pre and post screenshots. Hopefully that provides the necessary context.

    – 

  • 1

    Does this question help? stackoverflow.com/questions/34779724/…

    – 

  • It certainly might. There are a few ideas on there I haven’t tried.

    – 

Leave a Comment