当前位置:首页>python>用 Python 实现 Word 文档模板化生成:批量生成员工合同

用 Python 实现 Word 文档模板化生成:批量生成员工合同

  • 2026-09-10 13:31:30
用 Python 实现 Word 文档模板化生成:批量生成员工合同

在日常办公中需要大量使用word的小伙伴们应该会发现,其实许多文档具有高度固定的结构:比如合同条款、报告框架、通知函等,变化的通常只是其中的业务数据或人员信息。当需要生成大量相似文件的时候,手动复制旧文件、查找替换、调整排版的方式,不仅耗时,还容易导致版本错乱、关键字段遗漏等问题。

今天我们来看看利用 Python 的 docxtpl 库实现文档模板化生成的方法。其核心思路是将排版结构与业务数据解耦,通过模板引擎实现数据注入,提供可复用、可维护的自动化方案。(跑通一次就可以无限复用!)


一、模板化的优势

传统替换/手动操作

模板化生成

容易破坏格式,比如局部加粗、字体丢失

100% 继承模板原有样式、段落与表格结构

业务规则变更需逐个调整文件

仅需更新模板文件,代码逻辑保持稳定

依赖人工核对

可直接对接数据库、Excel、API 返回的 JSON

非常适用于:批量合同/协议、周期性报告、标准化表单、证书/通知等。


二、核心工具:docxtpl 与 Jinja2 语法

docxtpl 基于 python-docx 与 Jinja2 模板引擎封装,允许在 Word 文档中直接使用模板语法。其核心工作原理如下:

  1. 在 Word 中完成排版,用 {{ 变量名 }} 标记需替换的字段。
  2. Python 加载模板文件,将结构化数据(字典/列表)传入 render() 方法。
  3. 引擎解析 Jinja2 语法,生成保留原格式的 .docx 文件。

三、完整实现:批量生成员工合同

1. 模板设计 (contract_template.docx)

在 Word 中按标准合同排版,需动态替换的位置使用双大括号标记:

劳动合同甲方:{{ company_name }}乙方:{{ employee_name }}身份证号:{{ id_number }}一、合同期限本合同期限自 {{ start_date }} 起至 {{ end_date }} 止。二、岗位与薪酬乙方在 {{ department }} 担任 {{ position }},月薪资为 {{ salary }} 元。

💡 注意:模板中的占位符建议使用英文命名,避免与中文字体渲染冲突;排版完成后保存为 .docx 格式。

2. Python 渲染代码

import osfrom datetime import datetime, timedeltafrom docxtpl import DocxTemplatedef batch_generate_contracts(data_list: list[dict], template_path: str, output_dir: str):    if not os.path.exists(template_path):        raise FileNotFoundError(f"模板文件不存在: {template_path}")    os.makedirs(output_dir, exist_ok=True)    doc = DocxTemplate(template_path)  # 模板只需加载一次    for employee in data_list:        # 计算结束日期(示例:固定3年)        start = datetime.strptime(employee["start_date"], "%Y-%m-%d")        end = start + timedelta(days=3*365)        context = {            "company_name": "XX科技有限公司",            "employee_name": employee["name"],            "id_number": employee["id_number"],            "start_date": employee["start_date"],            "end_date": end.strftime("%Y-%m-%d"),            "department": employee["department"],            "position": employee["position"],            "salary": f"{employee['salary']:,.0f}"        }        doc.render(context)        filename = f"{employee['name']}_劳动合同.docx"        doc.save(os.path.join(output_dir, filename))        print(f"已生成: {filename}")if __name__ == "__main__":    # 示例数据(实际可从数据库、CSV 或内部 API 获取)    employees = [        {"name": "张三", "id_number": "1111", "start_date": "2026-05-01", "department": "研发部", "position": "后端工程师", "salary": 15000},        {"name": "李四", "id_number": "2222", "start_date": "2026-05-01", "department": "产品部", "position": "产品经理", "salary": 13000},        {"name": "王五", "id_number": "3333", "start_date": "2026-05-01", "department": "设计部", "position": "UI设计师", "salary": 11000}    ]    batch_generate_contracts(        data_list=employees,        template_path="contract_template.docx",        output_dir="./output_contracts"    )

运行后,程序会读取模板,注入对应数据,并在 output_contracts 目录下生成排版一致、数据准确的合同文件。


四、进阶场景:循环、条件与动态表格

1. 动态表格行

若需在合同中附加项目履历或培训记录,可在 Word 表格中使用行循环语法:

项目名称

担任角色

{%tr for p in projects %}{{ p.name }}

{{ p.role }}

⚠️ 注意:{%tr %} 必须包裹表格行级别,不可跨单元格拆分。渲染时会自动复制该行并填充数据。

2. 条件渲染

根据岗位类型显示不同条款:

{% if position == "高级软件工程师" %}四、技术保密与竞业限制乙方在职期间及离职后两年内,不得参与与甲方核心业务存在直接竞争的项目。{% endif %}

3. 富文本与特殊对象

  • 图片插入:使用 InlineImage 类可动态插入公章、签名或图表。
  • 页眉/页脚变量:需在模板页眉/页脚区域显式写入 {{ header_var }},代码中传入对应键值即可生效。

当文档生成从“重复劳动”沉淀为“标准流程”,我们真正优化的并非只是时间,而是人与事之间的关系。技术的意义从不在于替代思考,而在于腾出空间,让人重新成为工作的主导者~

更多python在办公自动化中的应用可以看这本


过往文章
Python编程小技巧--用Python查询天气
Python可视化 | 无需游戏引擎,用 tkinter 手写一个物理模拟器
Python 图形界面入门:一个能自动录屏的 2048 游戏
Python编程基础算法--斐波那契数列的矩阵算法
细数那些经典教材 | 算法图解Grokking Algorithms:像小说一样有趣
Python 库巡礼 | Django:Web开发的基石
最速降线:比直线更快的曲线
Python与办公自动化--批量生成报告/通知
计算机科学人物志 | 匈牙利算法:二分图匹配的百年寻踪
VS Code插件漫游 | Material Icon Theme:让代码世界色彩斑斓
过往合集
Python--数据/图像可视化
Python编程基础算法
Python编程小技巧
细数那些经典教材
Python库巡礼
Python与数学之美
Python与办公自动化
计算机科学人物志
VS Code插件漫游

最新文章

随机文章