Python第三⽅库之docxtpl(处理word⽂档)
docxtpl 软件包使⽤两个主要软件包:
python docx,⽤于读取、写⼊和创建⼦⽂档
jinja2⽤于管理插⼊到模板docx中的标记。,
简单⽰例
from docxtpl import DocxTemplate
tpl = DocxTemplate('test.docx')
context = {
'template': '123'
}
tpl.save('test1.docx')
安装
pip install docxtpl
导⾔
python-docx-template被开发出来,是因为python-docx的强⼤在于创建⽂档,⽽不是修改它们。
这个想法是开始于创建⼀个需要⽤MicrosoftWord⽣成的⽂档的⽰例,它可以像我们想要的那样复杂:如图⽚、索引表、页脚、页眉、变量,以及我们可以⽤Word做的任何事情。然后,当我们使⽤MicrosoftWord编辑⽂档时,直接在⽂档中插⼊类似于Jinja 2的标记。将⽂档保存为.docx⽂件(XML格式):它将是.docx模板⽂件。
现在,我们可以使⽤python-docx-template从这个.docx模板和将关联的上下⽂变量⽣成您想要的多个Word⽂档。
注意:python-docx-template是测试的是MS Word 97格式,它可能不适⽤于其他版本.
Jinja 2类语法
因Jinja 2包被使⽤,可以使⽤Word⽂档中的所有Jinja 2标记和过滤器。然⽽,要使它在Word⽂档中⼯作,进⾏了些限制和扩展:
限制
通常的Jinja 2标签,只能在同⼀个段落的同⼀个‘’run’中使⽤,它不能跨⼏个段落使⽤,表⾏、‘run’。如果您想要管理段落、表⾏和整个‘run’的样式,您必须使⽤特殊的标记语法,如下⼀章所述。
注意:MicrosoftWord的“Run”是⼀个具有相同风格的字符序列。例如,如果您创建⼀个具有相同风格的所有字符的段落:Word将在内部创建⼀个段落中的“Run”。现在,如果你在这段中间加了⼀个粗体,单词会把前⾯的“Run”转换成3‘Run’(普通-粗体-正常)。
扩展
为了管理段落、表⾏、表列、run,必须使⽤特殊的语法。(区别于jinja2)
{%p jinja2_tag %} for paragraphs
{%tr jinja2_tag %} for table rows
{%tc jinja2_tag %} for table columns
{%r jinja2_tag %} for runs
通过使⽤这些标记,python-docx-template将真正的Jinja 2标记放⼊⽂档的XML源代码中的正确位置。此外,这些标记还告诉python-docx-template移除位于开始和结束标记的位置的段落、表⾏、表列或run,只注意中间的位置。
重要*不要使⽤2次{%p, {%tr、`{%tc‘、{%r在同⼀段落、⾏、列或run中。例⼦:
不要⽤这个
{%p if display_paragraph %}Here is my paragraph {%p endif %}
⽽是使⽤
{%p if display_paragraph %}
Here is my paragraph
{%p endif %}
这种语法是可能是因为Microsoft word将每⼀⾏都看作是⼀个新的段落,{%p标签不在同⼀段中
显⽰变量
作为Jinja 2的⼀部分,可以使⽤双括弧:{{ <var> }}。但如果 <var> 是RichText对象,必须指定要更改实际的“Run”。{{r <var> }}注意’r紧跟左括弧。
重要*不要使⽤ r 变量出现在模板中,因为{{r}} 可以解释为 {{r 没有指定变量。不过,您可以使⽤以‘r’开头的更⼤的变量名。例如{{render_color}}将被解释为{{ render_color }}不像{{r ender_color}}.
重要*不要使⽤2次 {{r 在同⼀run上。使⽤RichText.add()⽅法在python端连接多个字符串和样式,并且只有⼀个字符串和样式 {{r 在模板边。
单元格颜⾊
当您想要更改表格单元格的背景⾊时,有⼀种特殊情况,您必须在单元格的开头放置以下标记
{% cellbg <var> %}
<var>必须包含颜⾊的⼗六进制代码⽆散列符号
列跨越
如果您想在多个列上动态地跨越⼀个表单元格(当您有⼀个具有动态列计数的表时,这是很有⽤的),您必须在单元格的最开始处放置下⾯的标记来跨越
{% colspan <var> %}
<var>必须包含要跨越的列数的整数。有关⽰例,请参见下⼀篇⽰例操作
Escaping
为了展⽰{%, %}, {{或}},你可以⽤
{%, %}, {{ or }}
RichText
当你使⽤{{ <var> }}标记,它将被包含在 var 变量的字符串替换。但它将保持⽬前的格式。如果要添加动态变化的样式,则必须同时使⽤以下两种⽅式:{{r <var> }}标签⼀个 RichText对象在 var 变量。您可以更改颜⾊、粗体、斜体、⼤⼩等,但最好的⽅法是使⽤microsoft word来定义⾃⼰的字符样式(主页选项卡->修改样式->管理样式按钮->新建样式,在窗体中选择“字符样式”),请参见
tests/richtext.py,除了使⽤RichText(),您可以使⽤它的快捷⽅式:R()
重要*当你使⽤{{r }}它从docx模板中移除当前字符样式,这意味着如果你没有在RichText()设置字体样式,样式将返回到Microsoft Word 默认样式。这只会影响字符样式,⽽不会影响段落样式(MSWord管理的这2种样式)。
可以通过Richtext将超链接添加到⽂本中。
将rt放在您的语境中,然后使⽤{{r rt}}在你的模板中
内嵌图像
您可以动态地将⼀个或多个图像添加到⽂档中(使⽤JPEG和PNG⽂件进⾏测试)。只要在你的模板中加上{{ <var> }},标记<var>是
doxtpl.inlineImage的实例。
myimage=InlineImage(tpl,‘test_files/python_logo.png’,width=Mm(20))
您只需指定模板对象、图像⽂件路径和可选宽度和/或⾼度即可。对于⾼度和宽度,您必须使⽤毫⽶(毫⽶),英⼨(英⼨)或点(Pt)类。有关⽰例,请参见test/inlineImage.py。
⼦⽂件
模板变量可以包含使⽤python-docxWord⽂档从头开始构建的复杂变量。为此,⾸先从模板对象获取⼦⽂档对象,并将其⽤作python-docx⽂档对象,参见tests/subdoc.py.
转义,换⾏符,新段落,列表
当您使⽤{{ <var> }},您正在修改XMLWord⽂档,这意味着您不能使⽤所有字符,特别是<, >和&。为了使⽤它们,你必须转义它们。有四种⽅式:
context = { ‘var’:R(‘my text’) }和在模板中{{r <var> }}(注意r),
context = { ‘var’:‘my text’}和在模板中{{ <var>|e }}
context = { ‘var’:escape(‘my text’)}和在模板中{{ <var> }}。
在调⽤呈现⽅法时启⽤⾃动转义:der(context, autoescape=True)(默认值autoescape=false)
RichText()或R()提供换⾏符和新段落功能:只需使⽤\n或\a在⽂本中,它们将作相应的转换。
有关更多信息,请参见tests/escape.py 。
另⼀个解决⽅案,如果要将列表包含到⽂档中,即转义⽂本并管理n和a,则可以使⽤’Listing’ class:
在python代码中
context = { 'mylisting':Listing('the listing\nwith\nsome\nlines \a and some paragraph \a and special chars : <>&') }
在docx模板中只需使⽤{{ mylisting }}带着Listing(),您将保持当前字符的样式(除⾮在⼀个\a之后你开始新的⼀段落)。
替换docx图⽚
在页眉/页脚中动态添加图像是不可能的,但您可以更改它们。这样做的⽬的是在模板中放置⼀个虚拟图⽚,像往常⼀样渲染模板,然后⽤另⼀个模板替换虚拟图⽚。你可以同时为所有媒体做到这⼀点。Note1:纵横⽐将与替换的图像相同 Note 2:指定⽤于在docx模板中插⼊图像的⽂件名(只要其basename,⽽不是完整路径)。
替换dummy_header_pic.jpg的语法:
替换发⽣在页眉、页脚和整个⽂档正⽂中。
替换docx媒体
在页眉/页脚中动态添加图⽚以外的其他媒体是不可能的,但您可以更改它们。这样做的⽬的是在模板中放置⼀个虚拟媒体,像往常⼀样呈现模板,然后⽤另⼀个模板替换虚拟媒体。你可以同时为所有媒体做到这⼀点。注意:对于图像,⾼宽⽐将与替换的图像注释2相同:重要的是要有源媒体⽂件,因为它们需要计算它们的CRC才能在docx中到它们。(虚拟⽂件名不重要)
替换dummy_header_pic.jpg的语法:
警告:与replace_pic() ⽅法不同,dummy_header_pic.jpg 必须存在模板⽬录中,当在渲染和保存⽣成docx时。它必须与⼿动插⼊在docx模板的⽂件相同。替换可以发⽣在页眉、页脚和整个⽂档正⽂中。
替换嵌⼊对象
它的⼯作⽅式类似于媒体替换,只是它适⽤于嵌⼊式docx这样的嵌⼊式对象。
替换embedded_dummy.docx的语法:
警告:与REPLE_PIC()⽅法不同,embdded_dumy.docx必须存在于模板⽬录中,在渲染和保存⽣成的docx时。它必须与⼿动插⼊docx模板的⽂件相同。替换发⽣在页眉、页脚和整个⽂档正⽂中。
Microsoft Word 2016特例
MS Word 2016将忽略表格的 \t。这对这个版本来说是特别的。但是LibreOffice或Wordpad没有这个问题。对于以jinja2标记产⽣空格来开头的⾏,也会出现同样的情况:它们将被忽略。要解决这些问题,解决⽅案是使⽤Richtext:
'test_space_r' : RichText('          '),
'test_tabs_r': RichText(5*'\t'),
})
在模板中,使⽤ {r 表⽰法:
{{r test_space_r}} Spaces will be preserved
{{r test_tabs_r}} Tabs will be displayed
表格
可以两种⽅式⽔平地跨表格单元格,⼀是利⽤colspan标记(请参阅tests/dynamic_table.py):
{% colspan %}
或者在for循环中(请参阅tests/horizontal_merge.py)):
{% hm %}
还可以在for循环中垂直合并单元格(请参阅 tests/vertical_merge.py):
{% vm %}
Jinja⾃定义过滤器
render() 接受 jinja_env 选项参数:您可以传递⼀个jinja环境对象。通过这种⽅式,您可以添加⼀些定制的jinja过滤器:
from docxtpl import DocxTemplate
import jinja2
python处理xml文件def multiply_by(value, by):
return value * by
doc = DocxTemplate("my_word_template.docx")
context = { 'price_dollars' : 5.00 }
jinja_env = jinja2.Environment()
jinja_env.filters['multiply_by'] = multiply_by
doc.save("generated_doc.docx")
然后在模板中,您将能够使⽤
Euros price : {{ price_dollars|multiply_by(0.88) }}
例⼦
查看其⼯作原理的最佳⽅法是阅读⽰例,它们位于 tests/ ⽬录。Docx测试模板在tests/templates/⽬录。要⽣成最终的docx⽂件:
cd tests/
python runtests.py
⽣成的⽂件位于tests/output ⽬录。
想要真正学会对应包,赶紧⾃⼰下载,根据测试⽂件测试吧!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。