ARTICLE · 1017049
这个 Python 库,让你在 Word 里写模板、5 行代码批量生成文档
500份文档改一整天?
Word里写模板 5行代码
批量生成文档
docxtpl · Jinja2模板 · 批量生成 · Python办公自动化
python-docx-template
6 Parts + Conclusion
滑动
PART 01
为什么需要
痛点与方案
PART 02
上手试试
发票模板实战
PART 03
条件与循环
动态表格生成
PART 04
高级功能
富文本与子文档
PART 05
踩坑指南
常见问题排查
PART ///
写在最后
总结与推荐
一句话概要
让不会写代码的人用 Word 画模板,开发者只负责往里灌数据
先说个真事:之前帮 HR 的朋友处理入职通知书,500 个新员工,格式统一,每份就姓名、部门、日期不一样。她的办法是——打开模板,改,保存,关掉,再打开,再改……搞了一整天,中间还改错了好几个名字。
做过文档自动化的朋友应该都见过这种场面。你可能想过用 Python 搞定。现实是,python-docx 的 API 太底层了,段落、表格单元格、样式属性全要自己一个个操作,代码写一坨还特别容易崩。另一个路子是 HTML 转 docx,但格式控制力太弱,稍微复杂点的表格和页眉页脚就歇菜。
01
PART
为什么需要这玩意
WHY WE NEED THIS
说白了就是缺一个桥梁:让不会写代码的人用 Word 画好模板,开发者只负责往里灌数据。
这正是 docxtpl(python-docx-template)在做的事情。思路挺讨巧——把 Word 文档当 Jinja2 模板,在文档里插 {{ 变量名 }} 标签,然后 Python 端丢一个数据字典进去,渲染一下就完事了。
这项目在 GitHub 上 2.7K Star,从 2015 年到现在一直在更新,Reddit、知乎、CSDN、博客园上都能找到实战帖子。装起来也省事:
CMDpip install docxtpl
一行搞定。要子文档功能的话,pip install docxtpl[subdoc]。
Word 画模板
业务人员排版
Python 灌数据
开发者写代码
批量出文档
格式完全统一
docxtpl 的核心工作流:模板归业务,代码归开发
02
PART
上手试试:做个发票模板
QUICK START · INVOICE
废话不多说,直接上手。
Word 里建模板
打开 Word,按你想要的格式排好版,在需要动态填数据的地方插上 Jinja2 标签:
客户名称:{{ customer_name }}
发票编号:{{ invoice_number }}
日期:{{ date }}
就这么简单。它本质就是个普通 .docx 文件,只不过多了几对花括号。

— 原始 Word 模板文件示例
Python 渲染
from docxtpl import DocxTemplate
tpl = DocxTemplate("invoice_template.docx")
context = {
"customer_name": "张三科技有限公司",
"invoice_number": "INV-2026-0042",
"date": "2026年8月11日",
}
tpl.render(context)
tpl.save("output_invoice.docx")
拢共不到 10 行。DocxTemplate 加载模板,render() 传字典进去替换标签,save() 输出文件。

— 嵌入 Jinja2 标签的 Word 模板
跑完之后打开输出文件,标签已经变成了“张三科技有限公司”,其他字段同理。原来的字体、颜色、表格边框全都在——底层是在 Word 的 XML 结构上做文本替换,不会动你的排版。
Word 管样式,Python 管数据,井水不犯河水
以后模板要改,业务人员在 Word 里直接改,Python 代码一行都不用碰。
03
PART
条件判断、循环和动态表格
CONDITIONALS · LOOPS · DYNAMIC TABLES
光换个变量名算不上什么。docxtpl 真正好用的地方,是它把 Jinja2 的语法基本完整地搬进了 Word。
条件判断:内容按需显隐
比如发票里有个 VAT 信息区块,但不是所有客户都需要。模板里可以这么写:
{% if vat_info %}
增值税号:{{ vat_info }}
税 率:{{ vat_rate }}%
{% endif %}
数据里有 vat_info 时,这个区块正常显示:

— 提供了 VAT 信息后的文档生成结果
没有的话就自动隐藏:

— 未提供 VAT 信息的文档生成结果
做多版本模板的都知道这有多方便——一套模板搞定不同客户、不同场景,不用维护一堆文件。
循环标签:表格行想生成多少行都行
发票经常有多条商品明细,行数不固定。在 Word 模板的表格里用循环标签就行:
context = {
"customer_name": "张三科技有限公司",
"items": [
{"name": "Python 开发服务", "qty": 10, "price": 1500},
{"name": "系统架构咨询", "qty": 5, "price": 2000},
{"name": "技术培训(次)", "qty": 3, "price": 800},
]
}
列表里有 3 条就出 3 行,100 条就出 100 行,完全动态。
特殊标签:段落级、行级、列级
docxtpl 还提供了几种特殊标签:
段落级标签:控制整个段落的显隐
行级标签:控制表格行的显隐和循环
列级标签:控制表格列
为什么需要这玩意?因为 Word 保存文档时可能把一个完整的变量标签拆到不同的 Run 里,导致普通标签失效。用特殊标签从结构层面控制,能避开这个坑。
04
PART
高级功能:富文本、图片和子文档
RICH TEXT · IMAGES · SUBDOCS
RichText:同一段文字里混排不同样式
有时候你需要一段文字里某个词标红加粗,或者塞个超链接进去。RichText 就是干这个的:
from docxtpl import DocxTemplate, RichText
tpl = DocxTemplate("report_template.docx")
rt = RichText()
rt.add("正常文本 ")
rt.add("红色加粗", color="FF0000", bold=True)
rt.add(" 超链接", url="https://github.com/...")
context = {"summary": rt}
tpl.render(context)
tpl.save("output_report.docx")
渲染出来就是混排了不同颜色、样式的文本,加上可点击的链接。做报告摘要或者通知函的时候挺实用。
InlineImage:动态插图片
证件照、产品图、签名图片这些场景,需要在渲染时动态插入图片:
from docxtpl import DocxTemplate, InlineImage
from docx.shared import mm
tpl = DocxTemplate("employee_template.docx")
context = {
"employee_name": "李四",
"photo": InlineImage(tpl, "photos/li_si.jpg",
width=mm(25), height=mm(35))
}
tpl.render(context)
tpl.save("output_employee.docx")
毫米、英寸、磅都支持,图片尺寸可以精确控制。
Subdoc:把多个 .docx 拼到一起
文档特别复杂的时候——比如一份合同,不同章节由不同团队维护——可以用 Subdoc 把它们组装起来:
from docxtpl import DocxTemplate, Subdoc
tpl = DocxTemplate("contract_main.docx")
context = {
"chapter1": Subdoc(tpl, "chapter1_terms.docx"),
"chapter2": Subdoc(tpl, "chapter2_appendix.docx"),
}
tpl.render(context)
tpl.save("output_contract.docx")
主文档只是个壳子,各章节内容作为子文档动态嵌进去。文档级别的模块化,管理起来清爽很多。

— 最终生成的完整 Word 文档输出示例
05
PART
几个容易踩的坑
COMMON PITFALLS
docxtpl 用起来简单,但有几件事不知道的话会浪费不少时间。
踩坑提示
标签不能跨 Run:Word 有时会把一个完整标签拆成好几个 Run,标签就废了。在 Word 里重新手打标签,别复制粘贴;实在不行就用段落级、行级特殊标签。
踩坑提示
定界符内侧必须加空格:花括号和变量名之间的空格不能省,不然解析器认不出来。
踩坑提示
特殊字符会导致 XML 报错:变量值里有 XML 特殊字符,用 RichText 包装或加 |e 过滤器转义。
踩坑提示
replace_media() 的源文件不能删:底层靠 CRC 校验匹配文件,模板目录里的原始占位图必须留着。
踩坑提示
Word 2016 会吞制表符:建议用 Word 2019 以上版本或 LibreOffice 打开渲染后的文档。
一些实用建议
调试模板:get_undeclared_template_variables() 能列出模板里所有需要但没传的变量,开发时非常好使。
Web 服务集成:社区里有不少把 docxtpl 跟 Flask 或 FastAPI 结合的教程。前端提交表单,后端加载模板渲染,返回下载链接。
批量渲染:同一个 DocxTemplate 对象可以反复调 render(),模板只需加载一次。一次性生成上千份文档时,比每次都重新加载快得多。
///
LAST
最后说两句
SUMMARY
总结一下 docxtpl 值得用的几个理由:
模板和代码各管各的:业务人员画模板,开发者填数据
功能齐全:变量、条件、循环、富文本、图片、子文档,应有尽有
靠得住:持续维护 11 年,2.7K Star,社区活跃
和其他方案比一下:如果你要从零创建文档、对结构有极致控制需求,python-docx 更灵活,但学习成本高;如果你在用 Node.js,docxtemplater 也行,但对 Python 项目来说集成费劲。
总的来讲,在 Python 生态里做 Word 文档自动化,docxtpl 目前是最成熟也最实用的选择之一。
项目地址:github.com/elapouya/python-docx-template
完整文档:python-docx-template.readthedocs.io
如果你正好在做合同生成、报告自动化、批量通知之类的需求,建议花半小时试一下。一个模板加几行代码,说不定能帮你省掉一整个下午的重复劳动。
我是 技术小助手,一个专注分享 Python 自动化办公技巧的开发者
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING