Python-docx-template是一个功能强大的Word文档自动化生成库,它基于模板引擎的设计思想,允许用户通过编写模板与Python代码逻辑分离的方式,高效生成结构复杂、样式多样的Word文档。在文章python-docx-template模板化Word文档生成指北介绍该库的基础用法之上,本文将进一步结合官方示例,提供多个实用场景的代码解析与拓展,涵盖复杂样式、自定义过滤器、嵌套循环及富文本渲染等高级功能,以提升文档生成的效率与灵活性。下文将分模块展开具体示例与实现。
python-docx-template的官方代码仓库地址为:python-docx-template,详细文档可参阅:python-docx-template doc。
本文使用的python-docx-template版本为0.20.2,安装命令如下:
pip install docxtpl
目录
- 1 实用案例
- 1.1 表格样式生成
- 1.2 自定义Jinja2过滤器
- 1.3 文档嵌入
- 1.4 自动转义
- 1.5 图片替换
- 1.6 命令行执行
- 1.7 多层嵌套
- 1.8 地区字体处理
- 1.9 富文本使用
- 1.10 错误管理
- 2 参考
1 实用案例
1.1 表格样式生成
本示例用于生成包含富文本样式与单元格背景色的Word表格文档。
模板内容:
渲染代码:- # python-docx-template/blob/master/tests/comments.py
- from docxtpl import DocxTemplate, RichText
- # data: python-docx-template/blob/master/tests/templates/cellbg_tpl.docx
- tpl = DocxTemplate("templates/cellbg_tpl.docx")
- context = {
- "alerts": [
- {
- "date": "2015-03-10",
- "desc": RichText("Very critical alert", color="FF0000", bold=True),
- "type": "CRITICAL",
- "bg": "FF0000",
- },
- {
- "date": "2015-03-11",
- "desc": RichText("Just a warning"),
- "type": "WARNING",
- "bg": "FFDD00",
- }
- ],
- }
- tpl.render(context)
- tpl.save("output/cellbg.docx")
复制代码 1.2 自定义Jinja2过滤器
本示例主要介绍通过自定义Jinja2过滤器实现动态数据渲染,Jinja2模板中过滤器的核心格式为:{{ 变量名|过滤器名(参数1, 参数2, ...) }},其中:
- |(竖线)是过滤器的分隔符,左侧是要处理的变量,右侧是过滤器名称;
- 括号()内是传给过滤器函数的参数(无参数时可省略括号);
- 示例:{{ base_value_float|my_filterB(2) }} 中,base_value_float是变量,my_filterB是过滤器名,2是传递的参数。
模板内容:
渲染代码:- # python-docx-template/blob/master/tests/custom_jinja_filters.py
- from docxtpl import DocxTemplate
- import jinja2
- # 创建jinja2环境对象,用于管理模板渲染的配置
- jinja_env = jinja2.Environment()
- # 自定义过滤器函数
- def my_filterA(value, my_string_arg):
- # 将原始值和参数字符串拼接,中间加空格
- return_value = value + " " + my_string_arg
- return return_value
- def my_filterB(value, my_float_arg):
- # 将原始值和参数数值相加
- return_value = value + my_float_arg
- return return_value
- # 将自定义过滤器注册到jinja2环境中,使其能在模板中被调用
- # 注册后在Word模板中可通过{{ 变量名| my_filterA('参数') }}形式使用
- jinja_env.filters["my_filterA"] = my_filterA
- jinja_env.filters["my_filterB"] = my_filterB
- context = {
- "base_value_string": " Hello",
- "base_value_float": 1.5
- }
- # data: python-docx-template/blob/master/tests/templates/custom_jinja_filters_tpl.docx
- tpl = DocxTemplate("templates/custom_jinja_filters_tpl.docx")
- tpl.render(context, jinja_env)
- tpl.save("output/custom_jinja_filters.docx")
复制代码 1.3 文档嵌入
以下代码展示了如何渲染子Word文档,替换主Word文档中嵌入的各类文件,填充数据后保存文档:- # python-docx-template/blob/master/tests/embedded.py
- from docxtpl import DocxTemplate
- # 加载内嵌子模板文件
- # data: python-docx-template/blob/master/tests/templates/embedded_embedded_docx_tpl.docx
- embedded_docx_tpl = DocxTemplate("templates/embedded_embedded_docx_tpl.docx")
- # 定义模板渲染的上下文数据
- context = {
- "name": "John Doe", # 要填充到模板中的姓名值
- }
- embedded_docx_tpl.render(context)
- # 保存渲染后的子模板到指定路径,供后续主模板调用
- embedded_docx_tpl.save("output/embedded_embedded_docx.docx")
- # 加载主模板文件
- tpl = DocxTemplate("templates/embedded_main_tpl.docx")
- # 定义主模板的上下文数据
- context = {
- "name": "John Doe",
- }
- # 替换主模板中嵌入的Word文档
- # 参数1:模原本嵌入的占位文件路径
- # 参数2:要替换成的目标文件路径
- tpl.replace_embedded(
- "templates/embedded_dummy.docx", "templates/embedded_static_docx.docx"
- )
- tpl.replace_embedded(
- "templates/embedded_dummy2.docx", "output/embedded_embedded_docx.docx"
- )
- # 说明:docx 本质是 zip 压缩包,嵌入的文件会存储在word/embeddings/目录下
- tpl.replace_zipname(
- "word/embeddings/Feuille_Microsoft_Office_Excel3.xlsx",
- "templates/real_Excel.xlsx" # 要替换成的实际文件路径
- )
- tpl.replace_zipname(
- "word/embeddings/Pr_sentation_Microsoft_Office_PowerPoint4.pptx",
- "templates/real_PowerPoint.pptx"
- )
- tpl.render(context)
- tpl.save("output/embedded.docx")
复制代码 1.4 自动转义
本示例展示了在自动转义模式下,将包含XML特殊字符、Unicode文本和动态键值对的上下文数据渲染到模板中。
模板内容:
渲染代码:
[code]# python-docx-template/blob/master/tests/escape_auto.pyimport osfrom unicodedata import namefrom docxtpl import DocxTemplateXML_RESERVED = """ |