Generate Word Documents with Python: Batch-Make Letters, Contracts and Certificates from a Template

Plenty of companies put out the same kind of document every month: HR issues offer letters, tutoring centres issue student certificates, insurers and estate agents send customer notices, and finance sends monthly statements. The format is identical — only the name, date, amount and reference number change. Done by hand, you open the Word template and copy, paste and edit, over and over. Ten documents and your fingers are tired; a hundred and you will definitely mistype something.

This "template plus swapped data" work is exactly what Python does best. Using a package called python-docx, you can have Python read your Word template, fill in the data automatically and save each document — a hundred files in seconds, with zero typos. Below we build a batch document generator from scratch.

Step 1: Prepare a template with "holes" in it

It's simple: make a normal document in Word, and wherever data should change, write a placeholder in double curly braces. For example:

  • Dear Mr/Ms {{name}},
  • Your application reference is {{ref}}, approved on {{date}}.
  • Monthly fee: HK${{amount}}.

Those {{...}} are the "holes" Python will later fill in. Save it as template.docx next to your script.

Step 2: Fill the holes with python-docx

Install the package in your terminal:

pip install python-docx

Then the star of the show — the dozen or so core lines that read the template, swap the data and save:

import docx # Open the Word template doc = docx.Document("template.docx") # The data to fill in (in real use, read it from Excel) data = {"name": "Chan Tai Man", "ref": "A12345", "date": "2026-10-05", "amount": "1,280"} # Walk every paragraph, replace placeholders with real data for para in doc.paragraphs: for key, value in data.items(): if "{{" + key + "}}" in para.text: for run in para.runs: run.text = run.text.replace("{{" + key + "}}", value) # Save as a new file (the original template stays intact) doc.save("offer_ChanTaiMan.docx")

In a dozen lines you have "open template, fill data, save". A few key points:

  • paragraphs is every paragraph in the document, which Python walks through one by one.
  • runs is each small stretch of text inside a paragraph (one paragraph can be split because of formatting differences). Replacing at the run level keeps the original fonts and bold intact.
  • doc.save() writes the finished document to a new file, leaving the original template untouched.

Step 3: Produce hundreds at once

So far that's one customer. The real time-saver is putting the data in an Excel sheet and having Python read it row by row, producing one document per row:

import docx import pandas as pd contacts = pd.read_excel("customers.xlsx") # one table, N rows for i, row in contacts.iterrows(): doc = docx.Document("template.docx") data = { "name": str(row["Name"]), "ref": str(row["Ref"]), "date": str(row["IssueDate"]), "amount": str(row["MonthlyFee"]), } for para in doc.paragraphs: for key, value in data.items(): if "{{" + key + "}}" in para.text: for run in para.runs: run.text = run.text.replace("{{" + key + "}}", value) doc.save("output/notice_" + str(row["Name"]) + ".docx") print("All documents generated")

A hundred customers means running the script once, and the output folder fills with a hundred completed notices, each named after the customer. Work that used to take half a day by hand now takes seconds.

How is this different from Word Mail Merge?

Word has a built-in Mail Merge that also combines a template with a list. But it's restrictive: the data must be in a format Word accepts, you have to open Word and click through the steps every time, and it's hard to schedule. Python is far more flexible — data can come from Excel, CSV, a database or even a website API, and you can pair it with the task scheduling we covered earlier to generate everything overnight, ready for your team in the morning.

Advanced tips

  • Tables work too: if a placeholder sits inside a table, walk doc.tables and each cell the same way.
  • Auto convert to PDF: install docx2pdf or use Word's own conversion to batch-convert .docx files to PDF for emailing to customers.
  • Keep the date current: use Python's datetime to fill in today's date — no manual editing.
  • Certificates and awards: the same approach — student name and course name into the template, and hundreds of certificates come out at once.

Summary

Python Tutorial: any document work that is "one format, a few words change" is Python's home turf. You don't need to write complex programs — just remember two ideas: leave holes in your Word template with {{placeholders}}, then replace them paragraph by paragraph and run by run with python-docx. Whether your data comes from typing, Excel or a database, once it's a table you can generate hundreds of documents in one click — fast, accurate and typo-free. Next time someone asks you to "edit a hundred letters", you won't have to sit there copying each one.