>>> from env_helper import info; info()
页面更新时间: 2024-04-05 10:32:16
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

2.9. 使用python-docx-template修改word文档

前面的介绍中我们使用python-docx库来创建word文档,但是对于文档的修改功能,还可以使用另一个库 python-docx-template可以完成对word的修改工作。

python-docx-template 模块主要依赖两个库, python-docx用于读取,编写和创建子文档 , jinja2用于管理插入到模板docx中的标签 。 其基本思路是利用jinja2制作Word模板,并动态向模板中插入文字、图片、表格等内容。

安装使用下面的命令:

pip install docxtpl

2.9.1. 使用 python-docx-template

首先创建一个word文档 test.docx,并设置好模板

这是一个模板:{{ template }}

在python中对设置的模板进行修改

>>> from docxtpl import DocxTemplate
>>> tpl = DocxTemplate('test.docx')
>>> context = {
>>>     'template': '123'
>>> }
>>> tpl.render(context)
>>> tpl.save('test1.docx')

打开生成的test1.doxc查看,文字已经被替换掉:

>>> from docx import Document
>>> dfile = Document('test1.docx')
>>> for para in dfile.paragraphs:
>>>     print(para.text)
这是一个模板:123

2.9.2. 内嵌图片

可以动态地将一个或多个图像添加到文档中(已通过JPEG和PNG文件测试)。只需 {{ <var> }} 在模板中添加标记.

>>> dfile = Document('image.docx')
>>> for para in dfile.paragraphs:
>>>     print(para.text)
这里插入一个图片:{{ myimage }}
>>> from docxtpl import  InlineImage
>>> from docx.shared import Mm
>>> import jinja2
>>>
>>> tpl = DocxTemplate('image.docx')
>>> context = {
>>>     'myimage': InlineImage(tpl, 'img/img10.jpg', width=Mm(20)),
>>> }
>>> jinja_env = jinja2.Environment(autoescape=True)
>>> tpl.render(context, jinja_env)
>>> tpl.save('test2.docx')

结果如下:

_images/insertimg.png

只需要指定模板对象,图像文件路径以及可选的宽度和/或高度。对于高度和宽度,必须使用毫米(Mm),英寸(Inches)或点(Pt)类。

2.9.3. 转义,换行符,新段落,清单

在 DOCX 文档中使用的 {{ }} 有特殊的意义,这意味着你不能使用所有字符,特别是 <>& 。 为了使用它们,必须要对它们进行转义。有四种方法:

  • context = { 'var':R('my text') }和{{r <var> }} 模板(注意 r

  • context = { 'var':'my text'}并{{ <var>|e }} 在您的Word模板

  • context = { 'var':escape('my text')}并{{ <var> }} 在模板中

  • 调用渲染方法时启用自动转义:( tpl.render(context, autoescape=True )默认值为 autoescape = False

RichText()R() 函数提供换行,新的段落,以及分页功能: 只需在文本中使用 \n\a\f ,它们将作相应转换。

>>> 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\aand some\aother\aparagraphs\aNOTE: the current character styling is removed'
>>>     ),
>>>     'mylisting': Listing(
>>>         'the listing\nwith\nsome\nlines\nand special chars : <>&\f ... and a page break'
>>>     ),
>>>     'page_break': R('\f'),
>>> }

2.9.4. 替换图片

无法在页眉/页脚中动态添加图像,但可以更改它们。这个想法是在模板中放置一个虚拟图片,照常渲染模板,然后用另一张替换该虚拟图片。可以同时对所有媒体执行此操作。注意:长宽比将与替换后的图像相同。指定用于在docx模板中插入图像的文件名(仅其基名,而不是完整路径)

方法

tpl.replace_pic('old','new')

我们就上次插入的图片进行替换。

>>> t = DocxTemplate('escape.docx')
>>> context = {}
>>> t.replace_pic('img10.jpg', 'img/aaa.jpg')
>>> t.render(context)
>>> t.save('text3.docx')

替换时文件的后缀要相同,否则会发生错误。