Python 第三方库之 docxtpl (处理word文档)

项目官方文档

项目官方git

docxtpl 软件包使用两个主要软件包:

  • python docx,用于读取、写入和创建子文档
  • jinja2用于管理插入到模板docx中的标记。jinja官网, jinja中文网站

简单示例

from docxtpl import DocxTemplatetpl = DocxTemplate('test.docx')context = {'template': '123'
}tpl.render(context)
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将超链接添加到文本中。

tpl=DocxTemplate(‘your_template.docx’)
rt = RichText('You can add an hyperlink, here to ')
rt.add(‘google’,url_id=tpl.build_url_id(‘http://google.com’))

将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> }}。
在调用呈现方法时启用自动转义:tpl.render(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的语法:

tpl.replace_pic('dummy_header_pic.jpg','header_pic_i_want.jpg')

替换发生在页眉、页脚和整个文档正文中。

替换docx媒体

在页眉/页脚中动态添加图片以外的其他媒体是不可能的,但您可以更改它们。这样做的目的是在模板中放置一个虚拟媒体,像往常一样呈现模板,然后用另一个模板替换虚拟媒体。你可以同时为所有媒体做到这一点。注意:对于图像,高宽比将与替换的图像注释2相同:重要的是要有源媒体文件,因为它们需要计算它们的CRC才能在docx中找到它们。(虚拟文件名不重要)

替换dummy_header_pic.jpg的语法:

tpl.replace_media('dummy_header_pic.jpg','header_pic_i_want.jpg')

警告:与replace_pic() 方法不同,dummy_header_pic.jpg 必须存在模板目录中,当在渲染和保存生成docx时。它必须与手动插入在docx模板的文件相同。替换可以发生在页眉、页脚和整个文档正文中。

替换嵌入对象

它的工作方式类似于媒体替换,只是它适用于嵌入式docx这样的嵌入式对象。

替换embedded_dummy.docx的语法:

tpl.replace_embedded('embdded_dummy.docx','embdded_docx_i_want.docx')

警告:与REPLE_PIC()方法不同,embdded_dumy.docx必须存在于模板目录中,在渲染和保存生成的docx时。它必须与手动插入docx模板的文件相同。替换发生在页眉、页脚和整个文档正文中。

Microsoft Word 2016特例

MS Word 2016将忽略表格的 \t。这对这个版本来说是特别的。但是LibreOffice或Wordpad没有这个问题。对于以jinja2标记产生空格来开头的行,也会出现同样的情况:它们将被忽略。要解决这些问题,解决方案是使用Richtext:

tpl.render({'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
def multiply_by(value, by):return value * bydoc = DocxTemplate("my_word_template.docx")
context = { 'price_dollars' : 5.00 }
jinja_env = jinja2.Environment()
jinja_env.filters['multiply_by'] = multiply_by
doc.render(context,jinja_env)
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 目录。

想要真正学会对应包,赶紧自己下载,根据测试文件测试吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

域添加另一台机器_巨杉Tech | SequoiaDB数据域概念解读与实践

近年来&#xff0c;银行各项业务发展迅猛&#xff0c;客户数目不断增加&#xff0c;后台服务系统压力也越来越大&#xff0c;系统的各项硬件资源也变得非常紧张。因此&#xff0c;在技术风险可控的基础上&#xff0c;希望引入大数据技术&#xff0c;利用大数据技术优化现有IT系…

Citrix XenServer 池要求

池要求 资源池是一台或多台服务器的同类或异类聚合&#xff0c;每个池最多包含 16 台服务器。创建池或将服务器加入现有池前&#xff0c;应确保池中的所有服务器满足下面介绍的要求。 硬件要求 XenServer 资源池中的所有服务器必须具有广泛兼容的 CPU&#xff0c;也就是说&…

推荐一个接口文档工具

ShowDoc 转载于:https://www.cnblogs.com/LW-baiyun/p/8003975.html

自动转换flv文件

在线转化.谁有 把其他的视频文件格式的视频,经过上传自动转化FLV格式的一种插件.提供编程接口.给我一份.类似新浪网播客上传视频的一样. (还有上传是的哪个效果,进度条如何作的?)或者给我个参考地址什 ... 环境&#xff1a;redhat as41。首先获取ffmpeg很多人找不到怎么下载,其…

云计算的概念_云计算概念掀起涨停潮 美利云奠定板块龙头地位

温馨提示&#xff1a;股市风险时刻存在&#xff0c;文中所提个股仅为个人观点&#xff0c;请勿盲目跟随操作&#xff0c;笔者希望大家都做到不贪婪&#xff0c;不恐惧&#xff0c;不瞎猜&#xff0c;不跟风做一个纪律严明轻松淡定的股票交易者。社4月26日讯&#xff0c;沪深两市…

Python 第三方模块之 PDFMiner(pdf信息提取)

PDFMiner简介 pdf提取目前的解决方案大致只有pyPDF和PDFMiner。据说PDFMiner更适合文本的解析&#xff0c;首先说明的是解析PDF是非常蛋疼的事&#xff0c;即使是PDFMiner对于格式不工整的PDF解析效果也不怎么样&#xff0c;所以连PDFMiner的开发者都吐槽PDF is evil. 不过这些…

TFS2017持续发布中调用PowerShell启停远程应用程序

目前团队项目中有多个Web、服务以及与大数据平台对接接口等应用&#xff0c;每次的发布和部署采用手工的方式进行。停止应用程序&#xff0c;拷贝发布包&#xff0c;启动应用程序&#xff0c;不停的循环着&#xff0c;并且时不时地会出现一些人为错误性问题。这种模式消耗的很多…

Flask 多线程

参数 app.run()中可以接受两个参数&#xff0c;分别是threaded和processes&#xff0c;用于开启线程支持和进程支持。 threaded&#xff1a; 是否开启多线程&#xff0c;默认不开启。 if __name__ __main__:app.run(threadedTrue)processes&#xff1a;进程数量&#xff0c…

40天python入门教程_Python入门教程超详细1小时学会Python

Java和Javascript,不用1小时你就可以用Python快速流畅地写有用的Python程序.为什么使用Python假设我们有这么一项任务:简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200.思路:用shell编程.(Linux通常是bash而Windows是批处理脚本).例如,在Windo…

基于LVS对LAMP做负载均衡集群

一、简介 LVS是Linux Virtual Server的简称&#xff0c;也就是Linux虚拟服务器, 是一个由章文嵩博士发起的自由软件项目&#xff0c;它的官方站点是www.linuxvirtualserver.org。现在LVS已经是 Linux标准内核的一部分&#xff0c;在Linux2.4内核以前&#xff0c;使用LVS时必须要…

Python_Day1

1、猜年龄游戏&#xff1a; &#xff08;1&#xff09;&#xff1a;每循环3次&#xff0c;counter值返回为0&#xff0c;重新开始循环&#xff1b;&#xff08;2&#xff09;&#xff1a;continue 意思是跳出当前循环&#xff1b;&#xff08;3&#xff09;&#xff1…

kafka 入门

初识 Kafka 什么是 Kafka Kafka 是由 Linkedin 公司开发的&#xff0c;它是一个分布式的&#xff0c;支持多分区、多副本&#xff0c;基于 Zookeeper 的分布式消息流平台&#xff0c;它同时也是一款开源的 基于发布订阅模式的消息引擎系统。 Kafka 的基本术语 消息&#xf…

实体词典 情感词典_tidytextpy包 | 对三体进行情感分析

腾讯课堂 | Python网络爬虫与文本分析TidyTextPy前天我分享了 tidytext | 耳目一新的R-style文本分析库 但是tidytext不够完善&#xff0c;我在tidytext基础上增加了情感词典&#xff0c;可以进行情感计算&#xff0c;为了区别前者&#xff0c;将其命名为tidytextpy。大家有时间…

TensorFlow实现LeNet5模型

# -*- coding: utf-8 -*-import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data# 获取mnist数据mnist input_data.read_data_sets("MNIST_data/", one_hotTrue)# 注册默认session 后面操作无需指定session 不同sesson之间的数据是独立…

Python基础第一天

一、内容 二、练习 练习1 题目&#xff1a;使用while循环输出1 2 3 4 5 6 8 9 10 方法一&#xff1a; 图示&#xff1a; 代码&#xff1a; count 1 while count < 11:if count ! 7:print(count)count 1输出结果&#xff1a; 1 2 3 4 5 6 8 9 10 View Code方法二&#xff1…

python flask 上传下载 api_Flask 文件下载API

给前端提供一个文件下载接口时, 遇到了文件名乱码的问题, 几经折腾总算实现效果, 代码如下:import requestsfrom flask import Response, jsonify, request, stream_with_contextfrom flask_login import login_requiredfrom . import bpfrom .models import Coursewarebp.rout…

OpenGL实用开源代码列表

有了网络的最大好处就是可以资源共享。网络是最大的知识库&#xff0c;也是最好的老师&#xff0c;正所谓“没有你想不到的&#xff0c;只有你找不到的”。以下是我收集的以游戏编程&#xff0c;OpenGL 3D编程相关的免费扩展库资料。不断更新中&#xff0c;如果你有好的建义&am…

vaOJ10369 - Arctic Network

1 /*2 The first line of each test case contains 1 < S < 100, the number of satellite channels!3 注意&#xff1a;S表示一共有多少个卫星&#xff0c;那么就是有 最多有S-1个通道&#xff01; 然后将最小生成树中的后边的 S-1通道去掉就行了&#xff01; 4…

python-kafka 常用 api 汇总

简介 python连接kafka的标准库&#xff0c;kafka-python和pykafka。kafka-python使用的人多是比较成熟的库&#xff0c;kafka-python并没有zk的支持。pykafka是Samsa的升级版本&#xff0c;使用samsa连接zookeeper&#xff0c;生产者直接连接kafka服务器列表&#xff0c;消费者…

scp选择二进制_二进制传输与文本传输区别

Ftp&#xff0c;winscp等工具下载文件时候有选项&#xff0c;可选的有二进制方式和文本方式。文本方式又称为ASCII方式两者区别如下。ASCII 方式和BINARY方式的区别是回车换行的处理&#xff0c;binary方式不对数据执行任何处理&#xff0c;ASCII 方式将回车换行转换为本机的回…