Python Word生成合同模板批量填充方法
用python-docx基于合同模板批量填充变量,从Excel读取客户信息一键生成几十份定制合同,避免手动替换占位符出错,提升合同签订效率。
场景痛点
公司签合同,模板固定,但每份合同的甲方、乙方、金额、期限、地址都不一样。手动打开模板一个个替换,一份合同改十几处,签10份合同就要改一百多处,稍不留神就漏改或改错。用python-docx做合同模板批量填充,把客户信息存在Excel里,一键生成所有合同,每一份都是定制好的完整文档。
用到的库
pip install python-docx openpyxl
完整代码
# 导入库
from docx import Document
import openpyxl
import os
def fill_template(template_path, output_path, data_dict):
"""
用模板生成一份填充好的合同
data_dict: {占位符: 实际值},如 {'甲方': 'XX公司', '金额': '10万'}
"""
doc = Document(template_path)
# 替换段落里的占位符
for para in doc.paragraphs:
replace_in_paragraph(para, data_dict)
# 替换表格里的占位符
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
replace_in_paragraph(para, data_dict)
# 替换页眉页脚
for section in doc.sections:
for para in section.header.paragraphs:
replace_in_paragraph(para, data_dict)
for para in section.footer.paragraphs:
replace_in_paragraph(para, data_dict)
doc.save(output_path)
def replace_in_paragraph(paragraph, data_dict):
"""在单个段落里替换所有占位符"""
full_text = ''.join(run.text for run in paragraph.runs)
new_text = full_text
for key, value in data_dict.items():
placeholder = '{{' + key + '}}' # 模板里用{{key}}做占位符
if placeholder in new_text:
new_text = new_text.replace(placeholder, str(value))
if new_text != full_text and paragraph.runs:
paragraph.runs[0].text = new_text
for run in paragraph.runs[1:]:
run.text = ''
def read_excel_data(excel_path):
"""
从Excel读取客户数据
第一行是表头(字段名),从第二行开始每行一个客户
"""
wb = openpyxl.load_workbook(excel_path)
ws = wb.active
# 读表头作为字段名
headers = [cell.value for cell in ws[1]]
records = []
for row in ws.iter_rows(min_row=2, values_only=True):
record = dict(zip(headers, row))
records.append(record)
return records
def batch_generate_contracts(template_path, excel_path, output_dir):
"""批量生成所有客户的合同"""
os.makedirs(output_dir, exist_ok=True)
records = read_excel_data(excel_path)
for idx, record in enumerate(records, start=1):
# 用客户名称命名输出文件
company_name = record.get('甲方', f'客户{idx}')
output_path = os.path.join(output_dir, f'合同_{company_name}.docx')
fill_template(template_path, output_path, record)
print(f'已生成:{output_path}')
print(f'\n全部完成,共生成 {len(records)} 份合同')
if __name__ == '__main__':
batch_generate_contracts(
template_path='合同模板.docx',
excel_path='客户信息表.xlsx',
output_dir='./生成合同'
)
代码讲解
- 模板里用
{{甲方}}、{{金额}}这种双大括号做占位符,和普通正文区分开,替换时不会误伤。 fill_template()打开模板,遍历正文段落、表格单元格、页眉页脚三个地方的占位符,确保所有位置都替换到。replace_in_paragraph()用拼接run文本的方式解决跨run拆分问题,和之前替换文字的思路一致。- Excel第一行表头就是占位符的key,比如表头写"甲方",模板里就写
{{甲方}},对应自动匹配。每行数据生成一份合同。 - 输出文件名用客户名称自动命名,
合同_XX公司.docx,方便查找。
运行结果
运行脚本后,./生成合同文件夹里每个客户生成一份独立的合同docx文件。打开任意一份,所有{{甲方}}、{{乙方}}、{{金额}}、{{日期}}占位符都已替换成该客户的实际信息,正文、表格、页眉页脚全部替换完成。
注意事项
- 模板里的占位符不要分格式写,比如不要一半加粗一半不加粗,否则替换后格式会统一。占位符保持纯文字格式即可。
- Excel里日期列如果是日期格式,转成字符串时注意格式,建议在Excel里先写成文本格式。
- 批量生成前先用一两个客户测试,确认替换无误再跑全量。
- 合同模板本身要先排版好(字体、行距、页边距),Python只负责填数据,不负责排版。

更新时间:2026-09-15 08:55:29