跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

python-docx-template 模板化生成 Word 文档指南

综述由AI生成介绍如何使用 python-docx-template 库基于 Jinja2 模板引擎批量生成 Word 文档。主要涵盖安装方法、核心概念(如段落、表格、文本标签)、常见元素(变量显示、注释、表格合并)、复杂元素(富文本、浮动图片、子文档)以及补充操作(转义、未定义变量检测、自定义过滤器)。通过示例代码展示了如何动态填充数据、插入图片和处理格式,解决了原生 python-docx 库修改模板繁琐的问题。

刀狂发布于 2026/3/30更新于 2026/5/2236 浏览
python-docx-template 模板化生成 Word 文档指南

python-docx 库的核心功能是程序化创建全新的 Word 文档,但在基于已有模板替换其部分内容时,其操作会非常繁琐。用户需要先解析文档结构、定位具体位置、手动替换内容,并维护原有格式与布局,导致开发效率较低。

python-docx-template 正是为解决这一痛点而设计的。它借鉴 Jinja2 模板引擎的思路,允许在 Word 文档中直接插入类似 {{variable}} 的占位符,随后仅用几行代码即可完成数据填充,无需关心底层文档结构,完美适配基于模板修改文档的场景。

文章配图

python-docx-template 基于 python-docx 实现文档读写功能,并借助 jinja2 提供灵活的模板标签支持,其设计思路如下:

  1. 用 Word 制作模板 在 Microsoft Word 中自由设计文档格式,如插入图片、设置页眉页脚、调整表格样式,充分利用 Word 强大的排版功能。
  2. 插入模板变量 在需要动态内容的位置,直接输入 Jinja2 风格的标签,例如 {{company_name}} 或 {%for item in list%}。
  3. 保存为模板文件 将文档保存为普通的.docx 文件,该文件即成为可复用的模板。
  4. 用 Python 批量生成 加载模板并传入字典或对象,python-docx-template 会自动替换标签,生成最终文档。

python-docx-template 的官方代码仓库地址为:python-docx-template,详细文档可参阅:python-docx-template doc。本文使用的 python-docx-template 版本为 0.20.2,安装命令如下:

pip install docxtpl

其中,docxtpl 是 python-docx-template 库的正式分发名称,二者指代同一工具。

1 使用说明

1.1 核心概念

1.1.1 标签说明

python-docx-template 允许在 Word 文档中使用 Jinja2 标签和过滤器。但为确保其在 Word 中正常运作,需遵循若干限制。

常规 Jinja2 标签仅能在同一段落内且同一文本运行中使用,若需控制段落、表格行或包含样式的完整文本运行,则必须使用后续章节介绍的复杂元素标签语法。

举例而言,若创建一个所有字符样式相同的段落,Word 内部只会生成一个文本运行对象。但若在该段落中将部分文字设置为加粗,Word 会将原有文本运行拆分为三个独立部分,分别对应普通样式、加粗样式及恢复后的普通样式。

标签

若要对段落、表格行、表格列以及文本段进行管理,需使用以下专用语法:

  • 段落标签:{%p jinja2_tag %}
  • 表格行标签:{%tr jinja2_tag %}
  • 表格列标签:{%tc jinja2_tag %}
  • 文本段标签:{%r jinja2_tag %}

这些以{% %}包裹的内容是 Jinja2 模板语法标签,引擎会识别并执行其中的逻辑。一个完整的模板标签基本结构如下:

{% 指令关键字 参数/条件 %} // 起始标签 内容 // 被标签控制的文本 {% 结束关键字 %} // 结束标签 

通过此类标签,python-docx-template 可自动将标准 Jinja2 标签,即去除前缀 p、tr、tc、r 后的内容,精确嵌入到文档 XML 源码的相应位置。

文章配图

假设模板内容如下:

{%p if display_paragraph %} 一段或多段文本内容 {%p endif %} 

无论 display_paragraph 变量取值如何,首尾两个包含{%p ... %}标签的段落,都不会出现在最终生成的 docx 文档中。
只有当 display_paragraph 的值为 True 时,以下内容才会被保留在生成的文档里:

一段或多段文本内容 

对于模板里的标签格式需遵循如下要求,否则无法生成正确结果:

  • 起始标签分隔符后必须加空格,结束标签分隔符前必须加空格:

  • 同一段落、行、列或文本段内,禁止连续使用标签分隔符:

  • 标签与内容不可写在同一行,需换行排版:

正确示例:

{%p if display_paragraph %} Here is my paragraph {%p endif %} 

错误示例:

{%p if display_paragraph %}Here is my paragraph {%p endif %} 

错误示例:

{%p{%tr{%tc{%r 

正确示例:

{% if something %} {%p if display_paragraph %} 

错误示例:

{%if something%} {%pif display_paragraph%} 
1.1.2 常见元素

显示变量

Jinja2 模板里,可以用双大括号来显示变量:

{{ <变量名> }} 

如果变量是普通字符串,字符串里的特殊符号会自动转换成对应的格式:

  • → 换行
  • → 分段
  • → 制表符(按一下 Tab 键的效果)
  • → 分页符

如果变量是富文本(RichText)对象,必须在变量名前加一个 r,明确表示要渲染这个富文本内容:

{{r <变量名> }} 

注意,r 要紧跟在左大括号的后面。

此外,变量名中禁止直接使用 <,>, & 这类字符,除非用了转义语法。

注释

可以在模板中添加类 Jinja2 风格的注释,注释不会被渲染到最终文件:

{#p 这是一个段落类型的注释 #} {#tr 这是一个表格行类型的注释 #} {#tc 这是一个单元格类型的注释 #} 

在执行如下代码对模板文件进行渲染操作时,模板中原有的所有注释信息均会被清除,不会保留在最终的渲染结果中:

from docxtpl import DocxTemplate
import os
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/comments_tpl.docx
tpl = DocxTemplate("templates/comments_tpl.docx")
tpl.render({})
os.makedirs("output", exist_ok=True)
tpl.save("output/comments.docx")

文本的拆分与合并

若包含 Jinja2 标签的文本过长,会导致可读性下降,例如:

我的房子位于{% if living_in_town %}城市区域{% else %}乡村地区{% endif %},我非常喜欢它。 

借助{-语法,可将 Jinja2 标签与上一行内容合并,同时借助 -} 语法,可将 Jinja2 标签与下一行内容合并。此时可使用回车键(Enter)或 Shift+Enter 对文本进行拆分排版,再通过上述的标签语法将拆分后的内容合并为一个整体,示例如下:

我的房子位于 {%- if living_in_town -%} 城市区域 {%- else -%} 乡村地区 {%- endif -%} ,我非常喜欢它。 

渲染代码如下:

from docxtpl import DocxTemplate
tpl = DocxTemplate("template.docx")
context = {"living_in_town": True}
tpl.render(context)
tpl.save("output/output.docx")

表格

可以使用 colspan 标签实现表格单元格的水平合并:

{% colspan <var> %} 

<var> 必须为整数,用于指定需要合并的列数。也可通过 Jinja2 模板引擎自动计算,如内置过滤器 count 通过管道符 | 接收 col_labels,用于统计其元素数量:

{% colspan col_labels|count %} 

以下示例展示了如何利用 colspan 标签、tr 和 tc 标签动态填充一个表格:

from docxtpl import DocxTemplate
import os
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/dynamic_table_tpl.docx
tpl = DocxTemplate("templates/dynamic_table_tpl.docx")
context = {
    "col_labels": ["fruit", "vegetable", "stone", "thing"],
    "tbl_contents": [
        {"label": "yellow", "cols": ["banana", "capsicum", "pyrite", "taxi"]},
        {"label": "red", "cols": ["apple", "tomato", "cinnabar", "doubledecker"]},
        {"label": "green", "cols": ["guava", "cucumber", "aventurine", "card"]},
    ],
}
tpl.render(context)
os.makedirs("output", exist_ok=True)
tpl.save("output/dynamic_table.docx")

也可以在 for 循环中实现单元格水平合并:

{% hm %} 

以下代码展示了如何利用 hm 标签实现单元格水平合并:

from docxtpl import DocxTemplate
import os
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/horizontal_merge_tpl.docx
tpl = DocxTemplate("templates/horizontal_merge_tpl.docx")
tpl.render({})
os.makedirs("output", exist_ok=True)
tpl.save("output/horizontal_merge.docx")

此外,还可以在 for 循环中实现单元格垂直合并:

{% vm %} 

以下示例展示了如何实现表格单元格的垂直合并效果:

from docxtpl import DocxTemplate
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/vertical_merge_tpl.docx
tpl = DocxTemplate("templates/vertical_merge_tpl.docx")
context = {
    "items": [
        {"desc": "Python interpreters", "qty": 2, "price": "FREE"},
        {"desc": "Django projects", "qty": 5403, "price": "FREE"},
        {"desc": "Guido", "qty": 1, "price": "100,000,000.00"},
    ],
    "total_price": "100,000,000.00",
    "category": "Book",
}
tpl.render(context)
tpl.save("output/vertical_merge.docx")

若需要修改表格单元格的背景色,必须将以下标签放置在单元格内容的最开头位置:

{% cellbg <var> %} 

<var> 必须填写颜色的十六进制编码,且无需包含井号(#)。

1.2 复杂元素

文章配图

1.2.1 富文本

富文本(Rich Text)是相对于纯文本(Plain Text)而言的一种文本格式。它不仅包含文字内容,还支持为文字添加各种格式属性及多媒体元素,从而呈现出更为丰富的视觉效果。这种格式的编辑和处理也可以通过在 Microsoft Word 软件中预先定义字符样式来实现。

在 python-docx-template 中使用富文本的步骤如下:

  1. 在 Word 模板中,为富文本定义一个占位符。例如,使用 {{r rich_text_var}},其中的 r 表示富文本。
  2. 在 Python 代码中,利用 RichText 类构建带有格式的文本内容。
  3. 渲染模板时,占位符会被替换为富文本内容,并保留所有已定义的格式样式。

在代码中使用 RichText 类时,还可通过以下标记控制文本格式:

  • 换行: ;
  • 换段: ;
  • 分页: 。

以下为生成富文本 Word 文档的示例:

from docxtpl import DocxTemplate, RichText
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/richtext_tpl.docx
tpl = DocxTemplate("templates/richtext_tpl.docx")
rt = RichText()
# 向富文本对象中添加内容,依次演示不同的文本格式设置
rt.add("a rich text", style="myrichtextstyle")
# 使用自定义样式
rt.add(" with ")
rt.add("some italic", italic=True)
# 斜体文本
rt.add(" and ")
rt.add("some violet", color="#ff00ff")
# 紫色文本(十六进制颜色码)
rt.add(" and ")
rt.add("some striked", strike=True)
# 删除线文本
rt.add(" and ")
rt.add("some Highlighted", highlight="#ffff00")
# 黄色高亮文本
rt.add(" and ")
rt.add("some small", size=14)
# 小字号文本(14 磅)
rt.add(" or ")
rt.add("big", size=60)
# 大字号文本(60 磅)
rt.add(" text.")
rt.add("\nYou can add an hyperlink, here to ")
# 添加带超链接的文本,build_url_id 用于创建 URL 标识并关联到指定链接
rt.add("bing", url_id=tpl.build_url_id("http://bing.com"))
rt.add("\nEt voilà ! ")
# 演示换行符效果
rt.add("\n1st line")
rt.add("\n2nd line")
rt.add("\n3rd line")
# \n 用于创建新段落
rt.add("\nA new paragraph : <cool>\n")
# \f 用于插入分页符
rt.add("--- A page break here (see next page) ---\f")
# 循环演示不同类型的下划线样式
for ul in ["single", # 单下划线
           "double", # 双下划线
           "thick", # 粗下划线
           "dotted", # 点下划线
           "dash", # 短划线下划线
           "dotDash", # 点划线下划线
           "dotDotDash", # 双点划线下划线
           "wave", # 波浪线下划线]:
    rt.add("\nUnderline : "+ ul + " \n", underline=ul)
# 演示不同字体的设置
rt.add("\nFonts:\n", underline=True)
rt.add("Arial\n", font="Arial")
rt.add("Courier New\n", font="Courier New")
rt.add("Times New Roman\n", font="Times New Roman")
# 演示上标和下标文本
rt.add("\n\nHere some")
rt.add("superscript", superscript=True)
# 上标文本
rt.add(" and some")
rt.add("subscript", subscript=True)
# 下标文本
# 创建一个新的富文本对象,并将之前创建的 rt 对象嵌入其中,实现富文本嵌套
rt_embedded = RichText("an example of ")
rt_embedded.add(rt)
# 构建渲染上下文,将嵌套的富文本对象赋值给模板中的 "example" 变量
context = {"example": rt_embedded,}
# 将上下文数据渲染到 Word 模板中
tpl.render(context)
# 保存渲染后的 Word 文档到指定路径
tpl.save("output/richtext.docx")
1.2.2 富文本段落

若要精细控制单个段落的样式,可在代码中使用 RichTextParagraph() 或 RP() 对象。此对象需通过 {{p <var> }} 语法添加至模板。示例代码如下:

from docxtpl import DocxTemplate, RichText, RichTextParagraph
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/richtext_paragraph_tpl.docx
tpl = DocxTemplate("templates/richtext_paragraph_tpl.docx")
# 创建富文本段落对象组合不同样式的段落
rtp = RichTextParagraph()
# 创建富文本对象,用于设置文本的字符样式
rt = RichText()
# 向富文本段落中添加文本,并指定自定义样式 myrichparastyle
rtp.add("The rich text paragraph function allows paragraph styles to be added to text", parastyle="myrichparastyle",)
# 添加文本并使用内置段落样式 IntenseQuote
rtp.add("Any built in paragraph style can be used", parastyle="IntenseQuote")
# 添加文本并使用自定义样式 createdStyle
rtp.add("or you can add your own, unlocking all style options", parastyle="createdStyle")
# 添加文本并使用默认普通段落样式 normal
rtp.add("To use, just create a style in your template word doc with the formatting you want "
        "and call it in the code.", parastyle="normal",)
# 演示不同列表样式的使用
rtp.add("This allows for the use of")
rtp.add("custom bullet\apoints", parastyle="SquareBullet")
# 方形项目符号样式
rtp.add("Numbered Bullet Points", parastyle="BasicNumbered")
# 数字编号样式
rtp.add("and Alpha Bullet Points.", parastyle="alphaBracketNumbering")
# 字母编号样式
# 演示文本对齐方式的设置
rtp.add("You can", parastyle="normal")
# 默认左对齐
rtp.add("set the", parastyle="centerAlign")
# 应用自定义样式居中对齐
rtp.add("text alignment", parastyle="rightAlign")
# 应用自定义样式右对齐
# 演示行间距样式:紧凑行间距
rtp.add("as well as the spacing between lines of text. Like this for example, "
        "this text has very tight spacing between the lines.\nIt also has no space between "
        "paragraphs of the same style.", parastyle="TightLineSpacing",)
# 演示行间距样式:宽行间距
rtp.add("Unlike this one, which has extra large spacing between lines for when you want to "
        "space things out a bit or just write a little less.", parastyle="WideLineSpacing",)
# 演示段落背景色样式:绿色背景
rtp.add("You can also set the background colour of a line.", parastyle="LineShadingGreen")
# 构建富文本字符串,演示字符级样式
rt.add("This works with ")
rt.add("Rich ", bold=True)
# 加粗
rt.add("Text ", italic=True)
# 斜体
rt.add("Strings", underline="single")
# 单下划线
rt.add(" too.")
# 将富文本对象添加到富文本段落中,并指定方形项目符号样式
rtp.add(rt, parastyle="SquareBullet")
# 构建渲染上下文,将富文本段落对象绑定到模板中的 example 变量
context = {"example": rtp,}
# 将上下文数据渲染到 Word 模板中
tpl.render(context)
# 保存渲染后的 Word 文档到指定路径
tpl.save("output/richtext_paragraph.docx")
1.2.3 浮动对象

图片插入

可在文档中动态插入单张或多张图片,当前已支持 JPEG 和 PNG 格式。只需在模板中使用 {{ <var> }} 格式的标签即可。图片嵌入代码如下:

myimage = InlineImage(tpl, image_descriptor='test_files/python_logo.png', width=Mm(20), height=Mm(10))

使用时应传入模板对象与图片文件路径,宽高为可选参数。宽度和高度需通过 Mm(毫米)、Inches(英寸)或 Pt(磅)等类进行单位定义。示例代码如下:

from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm
import jinja2
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/inline_image_tpl.docx
tpl = DocxTemplate("templates/inline_image_tpl.docx")
# 定义渲染模板所需的上下文数据
context = {
    # 只设置宽或者高,则图片自适应变化
    "myimage": InlineImage(tpl, "templates/python_logo.png", width=Mm(20)),
    # 手动指定宽高度
    "myimageratio": InlineImage(tpl, "templates/python_jpeg.jpg", width=Mm(30), height=Mm(60)),
    # 定义图片 + 描述
    "frameworks": [
        {"image": InlineImage(tpl, "templates/django.png", height=Mm(10)),
         "desc": "The web framework for perfectionists with deadlines",},
        {"image": InlineImage(tpl, "templates/zope.png", height=Mm(10)),
         "desc": "Zope is a leading Open Source Application Server "
                 "and Content Management Framework",},
        {"image": InlineImage(tpl, "templates/pyramid.png", height=Mm(10)),
         "desc": "Pyramid is a lightweight Python web framework aimed at taking "
                 "small web apps into big web apps.",},
        {"image": InlineImage(tpl, "templates/bottle.png", height=Mm(10)),
         "desc": "Bottle is a fast, simple and lightweight WSGI micro web-framework "
                 "for Python",},
        {"image": InlineImage(tpl, "templates/tornado.png", height=Mm(10)),
         "desc": "Tornado is a Python web framework and asynchronous networking "
                 "library.",},
    ],
}
# autoescape 是否开启自动转义,把模板变量中的特殊字符转换成无害的 HTM 实体
jinja_env = jinja2.Environment(autoescape=True)
# 使用上下文数据和自定义的 jinja2 环境渲染 Word 模板
tpl.render(context, jinja_env)
tpl.save("output/inline_image.docx")

替换文档中的图片

可对文档中的现有图片进行替换,具体操作如下:先在模板中插入一张占位图,按常规流程渲染模板,之后再将占位图替换为目标图片。该方法支持批量处理文档内的所有媒体文件,且替换后的图片将维持原占位图的纵横比。在模板中插入图片时,只需指定文件名即可。该替换操作同时对页眉、页脚及正文区域生效。

例如,替换占位图 dummy_header_pic.jpg 的语法示例如下:

tpl.replace_pic('dummy_header_pic.jpg','header_pic_i_want.jpg')

注意,在将图片手动插入 Word 模板时,某些版本的 Word 会自动对其重命名并存储。这导致图片在 docx 文件内的实际文件名与原文件名完全不同,从而可能引发找不到图片的问题。若不确定图片的具体位置,可将 docx 文件视为 zip 压缩包进行解压,随后在 word\document.xml 文件中,通过查找 pic:nvPicPr 节点来定位图片信息。

在找到目标图片对应的 pic:nvPicPr 节点后,其 name 属性的值即为图片在文档中实际存储的文件名。此处的文件名可能不包含图片格式后缀,替换图片的示例代码可能如下:

tpl.replace_pic('Picture 1','header_pic_i_want.jpg')
1.2.4 子文档

模板变量可包含复杂的子文档对象,且能通过 python-docx 的文档操作方法从零构建。具体步骤为:先从模板对象中获取子文档对象,再将其当作 python-docx 文档对象使用。该功能需要安装额外依赖:

pip install "docxtpl[subdoc]"

以下代码展示了如何创建子文档,并将该子文档嵌入到主模板中,最终生成并保存新的文档:

from docxtpl import DocxTemplate
from docx.shared import Inches
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/subdoc_tpl.docx
# 1. 加载 Word 模板文件(指定模板文件路径)
tpl = DocxTemplate("templates/subdoc_tpl.docx")
# 2. 创建一个新的子文档对象
sd = tpl.new_subdoc()
# 3. 向下文档中添加段落内容
p = sd.add_paragraph("This is a sub-document inserted into a bigger one")
p = sd.add_paragraph("It has been ")
# 为文本片段设置自定义样式
p.add_run("dynamically").style = "dynamic"
p.add_run(" generated with python by using ")
# 为文本片段设置斜体样式
p.add_run("python-docx").italic = True
p.add_run(" library")
# 4. 向下文档添加标题
sd.add_heading("Heading, level 1", level=1)
# 向下文档添加带样式的段落(IntenseQuote 样式为内置样式)
sd.add_paragraph("This is an Intense quote", style="IntenseQuote")
# 5. 向下文档插入图片
sd.add_paragraph("A picture :")
sd.add_picture("templates/python_logo.png", width=Inches(1.25))
# 6. 向下文档插入表格
sd.add_paragraph("A Table :")
# 创建表格(初始 1 行 3 列,作为表头)
table = sd.add_table(rows=1, cols=3)
# 获取表头单元格并设置内容
hdr_cells = table.rows[0].cells
hdr_cells[0].text = "Qty"
hdr_cells[1].text = "Id"
hdr_cells[2].text = "Desc"
# 定义表格数据
recordset = ((1,101,"Spam"),(2,42,"Eggs"),(3,631,"Spam,spam, eggs, and ham"))
# 循环添加数据行到表格
for item in recordset:
    row_cells = table.add_row().cells
    row_cells[0].text = str(item[0]) # 数量(转为字符串)
    row_cells[1].text = str(item[1]) # ID(转为字符串)
    row_cells[2].text = item[2] # 描述
context = {"mysubdoc": sd,}
tpl.render(context)
tpl.save("output/subdoc.docx")

此外自 python-docx-template V0.12.0 版本起,支持将已有的.docx 文件作为子文档进行合并,如下所示:

from docxtpl import DocxTemplate
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates
tpl = DocxTemplate("templates/merge_docx_master_tpl.docx")
sd = tpl.new_subdoc("templates/merge_docx_subdoc.docx")
context = {"mysubdoc": sd,}
tpl.render(context)
tpl.save("output/merge_docx.docx")

1.3 补充操作

文章配图

1.3.1 转义操作

默认情况下,python-docx-template 不会对内容进行转义。这是因为在使用模板语法修改 Word 文档时,底层实际上是在处理 XML 结构,而像 <、> 和 & 这样的字符在 XML 中具有特殊含义,必须经过转义才能正确显示。以下提供几种实现转义的方法:

调用 render 方法时启用自动转义,默认值为 autoescape=False:

tpl.render(context, autoescape=True)

上下文使用 escape() 函数处理内容,模板直接引用:

context = {'var': escape('my text')}

模板中写法:{{ <var> }}

上下文保持原始字符串,模板中使用 |e 过滤器:

context = {'var':'my text'}

模板中写法:{{ <var>|e }}

上下文定义时使用 R() 包裹内容,模板中添加 r 标记:

context = {'var': R('my text')}

模板中写法:{{r <var> }}

在文档中插入代码清单时,如果需要同时转义文本并处理换行符( )、段落符( )和换页符( ),可以在 Python 代码中使用 Listing 类。

例如:

context = {'mylisting': Listing('the listing\nwith\nsome\nlines \n and some paragraph \n and special chars : <>&')}

在模板中直接引用即可:

{{ mylisting }} 

使用 Listing() 能够保持当前字符样式,除非遇到 分隔符,它会在该位置开始一个新的段落。

使用示例如下:

from docxtpl import DocxTemplate, R, Listing
# data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/escape_tpl.docx
tpl = DocxTemplate("templates/escape_tpl.docx")
context = {
    "myvar": R('"less than" must be escaped : <, this can be done with RichText() or R()'),
    "myescvar": 'It can be escaped with a "|e" jinja filter in the template too : < ',
    "nlnp": R("Here is a multiple\nlines\nstring\nand some\nother\nparagraphs", color="#ff00ff",),
    "mylisting": Listing("the listing\nwith\nsome\nlines\nand special chars : <>& ..."),
    "page_break": R("\f"),
    "new_listing": """ This is a new listing Here is a \t tab\n Here is a page break : \f That's it """,
    "some_html": ("HTTP/1.1 200 OK\n"
                  "Server: Apache-Coyote/1.1\n"
                  "Cache-Control: no-store\n"),
}
tpl.render(context)
tpl.save("output/escape.docx")

此外,若需在最终生成的 Word 文档中显示由 Jinja2 渲染后的特殊字符 %、{ 或 },可以使用以下方式进行转义:

  • 显示 %% → 使用 {_% %_}
  • 显示 {{ }} → 使用 {_{ }_}
1.3.2 获取未定义变量

要获取模板渲染时所需的未定义变量,可以按照以下步骤操作:

from docxtpl import DocxTemplate
tpl = DocxTemplate('template.docx')
context = {'name':'张三','age':30}
# 注意:department 变量未定义
# 检测缺失变量
missing = tpl.get_undeclared_template_variables(context=context)
print(f"缺失的变量:{missing}")
# 获取所有变量(不传 context)
all_vars = tpl.get_undeclared_template_variables()
print(f"模板所有变量:{all_vars}")

模板文档的内容包含:

姓名:{{name}} 年龄:{{age}} 部门:{{department}} 

若未传递 context 参数,该方法将返回模板中所有需要赋值的变量名的集合。此结果可用于向用户提示输入,或写入文件供后续手动处理。

1.3.3 Jinja 自定义过滤器

Python-docx-template 的 render 方法支持一个可选参数 jinja_env,作为其第二个参数。通过传递自定义的 Jinja 环境对象,可以实现自定义过滤器的添加,从而灵活扩展数据处理逻辑。以下为具体示例。

模板 word 内容如下:

=== 姓名展示对比 === 原始名字:{{ name }} 方法 A (Python 处理): {{ name_upper }} 方法 B (模板过滤器): {{ name|upper }} 

对应的 Python 渲染代码:

from docxtpl import DocxTemplate
import jinja2
# 准备数据
data = {'name':'zhangsan'}
# Python 中处理
data['name_upper']= data['name'].upper()
# 定义过滤器
def my_upper(text):
    return text.upper()
doc = DocxTemplate("template.docx")
# 创建环境并注册过滤器
env = jinja2.Environment()
env.filters['upper']= my_upper
doc.render(data, env)
doc.save("output/compare.docx")
print(f"原始数据:{data['name']}")
print(f"Python 处理结果:{data['name_upper']}")
print(f"模板过滤器结果:{data['name'].upper()}")
1.3.4 Microsoft Word 2016 特殊行为说明

MS Word 2016 会忽略文档中的制表符,这是该版本特有的情况。类似 LibreOffice 或 WordPad 等其他编辑工具则无此问题。同样,以 Jinja2 标签开头且带有前导空格的行,其空格也会被忽略。

为解决上述问题,可使用 RichText 进行处理:

tpl.render({'test_space_r': RichText(' '),'test_tabs_r': RichText(5*'	'),})

在模板中,通过 {{r ... }} 语法调用:

{{r test_space_r}} 空格将被保留 {{r test_tabs_r}} 制表符将正常显示 

2 参考

  • python-docx-template
  • python-docx-template doc

目录

  1. 1 使用说明
  2. 1.1 核心概念
  3. 1.1.1 标签说明
  4. 1.1.2 常见元素
  5. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/comments_tpl.docx
  6. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/dynamictabletpl.docx
  7. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/horizontalmergetpl.docx
  8. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/verticalmergetpl.docx
  9. 1.2 复杂元素
  10. 1.2.1 富文本
  11. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/richtext_tpl.docx
  12. 向富文本对象中添加内容,依次演示不同的文本格式设置
  13. 使用自定义样式
  14. 斜体文本
  15. 紫色文本(十六进制颜色码)
  16. 删除线文本
  17. 黄色高亮文本
  18. 小字号文本(14 磅)
  19. 大字号文本(60 磅)
  20. 添加带超链接的文本,buildurlid 用于创建 URL 标识并关联到指定链接
  21. 演示换行符效果
  22. \n 用于创建新段落
  23. \f 用于插入分页符
  24. 循环演示不同类型的下划线样式
  25. 演示不同字体的设置
  26. 演示上标和下标文本
  27. 上标文本
  28. 下标文本
  29. 创建一个新的富文本对象,并将之前创建的 rt 对象嵌入其中,实现富文本嵌套
  30. 构建渲染上下文,将嵌套的富文本对象赋值给模板中的 "example" 变量
  31. 将上下文数据渲染到 Word 模板中
  32. 保存渲染后的 Word 文档到指定路径
  33. 1.2.2 富文本段落
  34. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/richtextparagraphtpl.docx
  35. 创建富文本段落对象组合不同样式的段落
  36. 创建富文本对象,用于设置文本的字符样式
  37. 向富文本段落中添加文本,并指定自定义样式 myrichparastyle
  38. 添加文本并使用内置段落样式 IntenseQuote
  39. 添加文本并使用自定义样式 createdStyle
  40. 添加文本并使用默认普通段落样式 normal
  41. 演示不同列表样式的使用
  42. 方形项目符号样式
  43. 数字编号样式
  44. 字母编号样式
  45. 演示文本对齐方式的设置
  46. 默认左对齐
  47. 应用自定义样式居中对齐
  48. 应用自定义样式右对齐
  49. 演示行间距样式:紧凑行间距
  50. 演示行间距样式:宽行间距
  51. 演示段落背景色样式:绿色背景
  52. 构建富文本字符串,演示字符级样式
  53. 加粗
  54. 斜体
  55. 单下划线
  56. 将富文本对象添加到富文本段落中,并指定方形项目符号样式
  57. 构建渲染上下文,将富文本段落对象绑定到模板中的 example 变量
  58. 将上下文数据渲染到 Word 模板中
  59. 保存渲染后的 Word 文档到指定路径
  60. 1.2.3 浮动对象
  61. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/inlineimagetpl.docx
  62. 定义渲染模板所需的上下文数据
  63. autoescape 是否开启自动转义,把模板变量中的特殊字符转换成无害的 HTM 实体
  64. 使用上下文数据和自定义的 jinja2 环境渲染 Word 模板
  65. 1.2.4 子文档
  66. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/subdoc_tpl.docx
  67. 1. 加载 Word 模板文件(指定模板文件路径)
  68. 2. 创建一个新的子文档对象
  69. 3. 向下文档中添加段落内容
  70. 为文本片段设置自定义样式
  71. 为文本片段设置斜体样式
  72. 4. 向下文档添加标题
  73. 向下文档添加带样式的段落(IntenseQuote 样式为内置样式)
  74. 5. 向下文档插入图片
  75. 6. 向下文档插入表格
  76. 创建表格(初始 1 行 3 列,作为表头)
  77. 获取表头单元格并设置内容
  78. 定义表格数据
  79. 循环添加数据行到表格
  80. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates
  81. 1.3 补充操作
  82. 1.3.1 转义操作
  83. data: https://github.com/elapouya/python-docx-template/blob/master/tests/templates/escape_tpl.docx
  84. 1.3.2 获取未定义变量
  85. 注意:department 变量未定义
  86. 检测缺失变量
  87. 获取所有变量(不传 context)
  88. 1.3.3 Jinja 自定义过滤器
  89. 准备数据
  90. Python 中处理
  91. 定义过滤器
  92. 创建环境并注册过滤器
  93. 1.3.4 Microsoft Word 2016 特殊行为说明
  94. 2 参考
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 金仓 SQL 防火墙原理与核心优势解析
  • 图数据结构详解:存储结构、遍历与核心算法
  • WSL 2 安装 Ubuntu 24.04 及系统迁移至非系统盘
  • Clawdbot(Moltbot) 集成飞书机器人配置指南
  • Prompt 驱动的结构化抽取:从非结构化文本高效提取表格
  • Stable Diffusion v1.5 创意设计师指南:嵌入 Figma/PS 工作流
  • 妙鸭产品负责人:AI 时代产品经理不能只做模型搬运工
  • Python warnings 库底层机制与企业级 API 演进实战
  • C++ string 类常用成员函数与全局函数详解
  • VS Code 使用 VS2022 编译 C++ 的完整流程
  • C++ 继承机制详解:从基础语法到菱形继承
  • 主流时序数据库架构与性能深度评测
  • Python PEP 8 编码规范实战指南
  • 内容创作模式解析:UGC、PGC、PUGC、AIGC 等概念详解
  • Android 校招面试经验总结:Java 基础与系统原理
  • C++11 深度解析:重塑现代 C++ 的关键特性
  • AI 编程新范式:什么是 Skills,如何用它生成 Java 方法
  • LangChain 框架快速入门指南
  • Docker 部署 Web-Check 结合 cpolar 实现远程安全访问
  • VSCode 禁用 GitHub Copilot 功能指南

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online