Py里的邮件合并——灵活的docxtpl
创作者俱乐部成员
例如,有一套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里清洗整理,也可以在模板内过滤,字体、颜色等样式可以直接设置在语句上,相比于用域代码来控制,要省心省力一些。