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")
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")
注意,在将图片手动插入 Word 模板时,某些版本的 Word 会自动对其重命名并存储。这导致图片在 docx 文件内的实际文件名与原文件名完全不同,从而可能引发找不到图片的问题。若不确定图片的具体位置,可将 docx 文件视为 zip 压缩包进行解压,随后在 word\document.xml 文件中,通过查找 pic:nvPicPr 节点来定位图片信息。
在找到目标图片对应的 pic:nvPicPr 节点后,其 name 属性的值即为图片在文档中实际存储的文件名。此处的文件名可能不包含图片格式后缀,替换图片的示例代码可能如下:
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 渲染后的特殊字符 %、{ 或 },可以使用以下方式进行转义: