Automatic creation of DOCX files from template using data from a CSV

from docxtpl import DocxTemplate

“yes we need you to write 102 workplans”

Me: *I’ll pretend to write them but sure I can automate it*

So began 2 days of reading up on docxtpl and fine tuning my Python code to generate 102 Word documents with pretty much identical information except for some site specific details such as:

Site, Model, Firmware

Other than this the files were identical, but there was much scope for errors if I had to manually copy and paste long firmware version names and drift off halfway through due to the boredom of it.

word doc from python

So how did I create these?

Answer : Python, docxtpl , Libre Office, and some Tea and biscuits….

{image_name} in the word docx template means that it will pick up the ‘image_name’ from the Column of the same name CSV via the Python code.

The Python code has a for loop to go through each row.
Dynamically generate word documents using data from a CSV - with 1 template file.
# pip install python-docx
# pip install docxtpl <- Better for making new files from a template
import random
import time
import csv
import pandas as pd
from docxtpl import DocxTemplate

# Source CSV - column names that must match the *** that are {{***}} inside "template.docx"
csvfn = "cnw.csv"

def mkw(n):
    tpl = DocxTemplate("template.docx") # In same directory
    df = pd.read_csv(csvfn)
    df_to_doct = df.to_dict() # dataframe -> dict for the template render
    x = df.to_dict(orient='records')
    context = x
    tpl.render(context[n])"%s.docx" %str(n+1))
    # Wait a random time - increase for production run.
    wait = time.sleep(random.randint(300,400))


df2 = len(pd.read_csv(csvfn)) 
print ("There will be ", df2, "files")

#for i in range(0,df2):
for i in range(6,10):
    print("Making file: ",f"{i}," ,"..Please Wait...")
print("Done! - Now check your files")

The full code relies on “cnw.csv” and the “template.docx” being present in the local directory.

The template file is a standard word docx file, but with {stuff} in the braces where you want the eventual data to appear, and where ‘stuff’ is the name of a Column in the CSV file.

Leave a Reply