Py里的邮件合并——灵活的docxtpl

wils
wils

创作者俱乐部成员

例如,有一套txt格式的题库,格式是一行问题加四行选项,现在需要批量排版成docx,关键是要判断备选项的长短,将其分别排列成一行四列、两行两列、四行一列的形式。

正好昨天学习了,清华学弟任泽岩老师关于制表位的帖子,https://bbs.wps.cn/topic/34710,现学现卖,用到这里做自动的排版😁

下面用到的是python的docxtpl模块,功能可以简单理解成邮件合并,但用法上要灵活一些:

数据可以来源自任何地方,用python清洗整理成json,传递给docx格式的模板,即可渲染成最终的文件,而模板内可以使用python的循环判断过滤器等功能,比域代码方便一些

py代码如下:

🔔

from docxtpl import DocxTemplate

with open('dat.txt', 'r', encoding='utf-8') as f:

dat = [i.strip() for i in f.readlines()]

dat = [dat[i:i+5] for i in range(0, len(dat), 5)]

tpl = DocxTemplate('tpl.docx')

tpl.render({'dat': dat})

tpl.save('out.docx')

很短,就是打开txt题库,加载tpl.docx模板,将数据传递给模板,输出到out.docx。

在这里可以随意读取数据,进行清洗、整理,而在模板中,可以使用传递过来的字典dat

可以看到,从py传递过来的数据dat,是每5行一组,共4组题目的数组

🔔

标题

{% for i in dat -%}

{{ i[0] }}

{%- if i[1:]|map(‘length’)|max < 12 %}

{{ i[1] }} {{ i[2] }} {{ i[3] }} {{ i[4] }}

{% elif i[1:]|map(‘length’)|max < 24 %}

{{ i[1] }} {{ i[2] }}

{{ i[3] }} {{ i[4] }}

{% else %}

{{ i[1] }}

{{ i[2] }}

{{ i[3] }}

{{ i[4] }}

{% endif %}

{% endfor %}

而在tpl.docx模板里,先是一个居中的标题,然后是对dat做for循环,无论有几组题目,都在循环中逐个处理

然后是if判断,计算最长选项的长度,如果小于12,就排成一行;如果超过12小于24,就排成两行;剩下的排成四行

如果要输出多份结果,在py里的渲染部分,加个循环即可

总的来说,用docxtpl来做邮件合并,可以很灵活:固定的、动态的内容可以直白的同时写在模板docx里,循环判断等结构可以控制段落、表格、图片等等,数据可以在py里清洗整理,也可以在模板内过滤,字体、颜色等样式可以直接设置在语句上,相比于用域代码来控制,要省心省力一些。

海南省
浏览 607
1
5
分享
5 +1
1 +1
全部评论