前面介绍了使用python-docx
库来创建word文档,但是对于文档的修改功能,
还可以使用另一个库 python-docx-template
来完成对word的修改工作。
python-docx-template
模块主要依赖两个库,python-docx
用于读取,编写和创建子文档,
jinja2用于管理插入到模板docx中的标签 。
其基本思路是利用jinja2制作Word模板,并动态向模板中插入文字、图片、表格等内容。
安装使用下面的命令:
pip install docxtpl
这是一个模板:{{ template }}
在python中对设置的模板进行修改:
from docxtpl import DocxTemplate
tpl = DocxTemplate('xx_test.docx')
context = {
'template': '123'
}
tpl.render(context)
tpl.save('xx_test1.docx')
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Cell In[2], line 1 ----> 1 from docxtpl import DocxTemplate 2 tpl = DocxTemplate('xx_test.docx') 3 context = { 4 'template': '123' 5 } ModuleNotFoundError: No module named 'docxtpl'
打开生成的test1.doxc
查看,文字已经被替换掉:
from docx import Document
dfile = Document('xx_test1.docx')
for para in dfile.paragraphs:
print(para.text)
dfile = Document('xx_image.docx')
for para in dfile.paragraphs:
print(para.text)
from docxtpl import InlineImage
from docx.shared import Mm
import jinja2
tpl = DocxTemplate('xx_image.docx')
context = {
'myimage': InlineImage(tpl, 'xx_img/img10.jpg', width=Mm(20)),
}
jinja_env = jinja2.Environment(autoescape=True)
tpl.render(context, jinja_env)
tpl.save('xx_test2.docx')
结果如下:
只需要指定模板对象,图像文件路径以及可选的宽度和/或高度。对于高度和宽度,必须使用毫米(Mm),英寸(Inches)或点(Pt)类。
转义,换行符,新段落,清单
在 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'),
}
1tpl.replace_pic('old','new')
根据上次插入的图片进行替换。
t = DocxTemplate('xx_escape.docx')
context = {}
t.replace_pic('xx_img10.jpg', 'xx_img/aaa.jpg')
t.render(context)
t.save('xx_text3.docx')
替换时文件的后缀要相同,否则会发生错误。