Python自动化之Docx文档处理(二)
1 基本概念
1.1 python-docx-template模块
虽然前面提到的python-docx模块让我们能使用python代码写word,但正常情况下我们写word文档肯定都是直接使用office或wps之类的办公软件。更常用的需求是拿到一个word模板,用python往word模板中填充数据,python-docx-template正好就能实现我们这个需求。[1]
python-docx-template会用到两个模块。
- python-docx:用于读取、写入和创建子文档
- jinja2:用于管理插入docx模板中的标签
我们可以使用jinjia2[2]制作word模板,并动态向模板中插入文字、图片、表格等内容。
安装python-docx-template模块
pip install docxtpl
然后我们依然是通过几个案例来熟悉该模块的使用
2 如何填充word模板中的变量
2.1 模板准备
首先准备一个docx模板,template.docx
模板使用到了jinja2语法。在jinja2中,{{}}表示定义一个变量,{{}}中的为变量名。
2.2 代码准备
接下来准备python代码
from docxtpl import DocxTemplate
template_doc="./template.docx" ##定义模板所在位置
doc_save="./填充结果.docx" ##定义docx文档保存位置
tpl = DocxTemplate(template_doc)
context = {
"日期": '2023-11-02',
"作者": 'Singless',
}
tpl.render(context=context)
tpl.save(doc_save)
代码解析
- tpl = DocxTemplate(template_doc):打开一个docx默认模板
- context:定义要填充的内容,通常定义为一个字典,key为模板中的jinja2变量名,value为要给变量所赋的值。一段代码中只能定义一个context。
- tpl.render:将内容写入到模板中
- tpl.save:将写好内容的文档保存
运行代码,该文档最终展现形式如下
3 修改填充字体样式
3.1 word模板准备
准备一个word模板
模板使用到了jinja2的循环语法
{%tr for row in table%}
{% ... %}:在jinja2中用来包裹控制、循环、条件语句,endfor表示循环的结束。注意"{"和"%"之间不能有空格,开头的%tr表示表格的第一行,最后也需要以%tr结束。
3.2 准备python代码
from docxtpl import DocxTemplate, RichText
# 初始化模板对象
tpl = DocxTemplate("./template.docx")
# 待填充的字典数据,其中key对应word模板中的填充名
context = {
"table": [
{ "app_level": 'A类',
"app": "营业",
"db_name": "YY",
"db_type": "PDB",
"run": RichText('READ ONLY', color='FF0000', size=16, ), ##通过ricktext方法修改字体颜色和格式
},
{ "app_level": 'B类',
"app": "账务",
"db_name": "ZW",
"db_type": "PDB",
"run": RichText('READ WRITE', color='000000', size=16, ),
},
{ "app_level": 'C类',
"app": "报表",
"db_name": "BB",
"db_type": "PDB",
"run": RichText('MOUNTED', color='FF0000', size=16, ),
},
{ "app_level": 'D类',
"app": "计费",
"db_name": "JF",
"db_type": "PDB",
"run": RichText('READ WRITE', color='000000', size=16, ),
},
],
}
# 开始渲染context数据到模板文件中
tpl.render(context=context)
tpl.save("填充结果2.docx")
运行代码后,word文档效果如下
当然我们也可以直接在word模板中将jinja2变量的颜色或字号进行修改。内容填充时不会改变模板中内容原来的格式。
4 插入图片
4.1 word模板准备
准备一个word模板
4.2 准备python代码
from docxtpl import DocxTemplate, InlineImage
# for height and width you have to use millimeters (Mm), inches or points(Pt) class :
from docx.shared import Mm
import jinja2
tpl = DocxTemplate('template.docx')
context = {
'myimage': InlineImage(tpl, 'touxiang.jpg', width=Mm(20)),
'frameworks': [
{
'image': InlineImage(tpl, 'touxiang.jpg', height=Mm(10)),
'desc': 'The web framework for perfectionists with deadlines',
},
{
'image': InlineImage(tpl, 'touxiang.jpg', width=Mm(20),height=Mm(10)),
'desc': 'Zope is a leading Open Source Application Server and Content Management Framework',
},
],
}
# testing that it works also when autoescape has been forced to True
jinja_env = jinja2.Environment(autoescape=True)
tpl.render(context, jinja_env)
tpl.save('填充结果3.docx')
代码通过InlineImage插入图片,并可通过width和height调整图片的宽度和长度
执行代码后效果如下
5 参考资料
关注公众号 singless,获取更多有价值的文章
浙公网安备 33010602011771号