如何用Python的docxtpl库从多数据表生成复杂Word文档?
使用docxtpl基于多数据表生成复杂Word文档方案
核心结论
完全可以实现。docxtpl的context本质就是一个Python字典,支持同时传入任意多组数据集(无论各表行数多少),结合Jinja2语法就能在Word模板的不同位置实现条件判断、嵌套循环等复杂动态渲染逻辑。
具体实现步骤
1. 构造包含多数据集的Context字典
把从Excel读取的所有数据集,以键值对形式存入同一个字典,键名要便于在模板中识别调用:
# 假设已从Excel读取完成,得到四个结构化列表 person_list = [{"id": 1, "name": "张三"}, {"id": 2, "name": "李四"}] issue_list = [{"issue_id": 101, "content": "系统报错"}, {"issue_id": 102, "content": "数据丢失"}] relation_list = [{"person_id": 1, "issue_id": 101}, {"person_id": 2, "issue_id": 101}, {"person_id": 2, "issue_id": 102}] case_list = [{"case_id": "CASE001", "title": "系统故障排查", "date": "2024-05-20"}] # 整合所有数据到上下文字典 context = { "persons": person_list, "issues": issue_list, "relations": relation_list, "cases": case_list }
2. 在Word模板中用Jinja2语法调用多数据集
docxtpl基于Jinja2模板引擎,直接在Word里写标签就能实现循环、条件判断,甚至跨表关联匹配:
示例1:渲染单条案件全局数据
# 案件基本信息 案件编号:{{ cases[0].case_id }} 案件标题:{{ cases[0].title }} 立案日期:{{ cases[0].date }}
示例2:嵌套循环渲染人员-问题关联数据
通过Jinja2的selectattr过滤器匹配关联字段,实现跨表数据联动:
## 人员关联问题清单 {% for person in persons %} ### {{ person.name }}(ID: {{ person.id }})负责的问题: {% set person_rel = relations | selectattr('person_id', 'equalto', person.id) | list %} {% if person_rel %} {% for rel in person_rel %} {% set target_issue = issues | selectattr('issue_id', 'equalto', rel.issue_id) | first %} - 问题ID: {{ target_issue.issue_id }},内容:{{ target_issue.content }} {% endfor %} {% else %} - 无关联问题 {% endif %} {% endfor %}
示例3:条件渲染特定优先级内容
## 紧急问题提醒 {% for issue in issues %} {% if '数据丢失' in issue.content %} > 【高优先级】问题内容:{{ issue.content }},请立即处理! {% endif %} {% endfor %}
3. 执行渲染生成文档
最后用docxtpl加载模板,传入上下文完成渲染:
from docxtpl import DocxTemplate # 加载提前制作好的Word模板 doc = DocxTemplate("case_template.docx") # 传入多数据集上下文 doc.render(context) # 保存最终文档 doc.save("final_case_doc.docx")
优化提示
- 如果数据集极大,建议提前在Python中预处理关联数据(比如把
relation_list转成以person_id为键的字典),避免模板中多次过滤拖慢渲染速度 - 确保Excel读取的每行数据都是字典格式,键名要和模板中的变量名严格对应
- 模板中Jinja2标签要注意闭合(比如
{% endfor %}、{% endif %}),避免渲染报错
内容的提问来源于stack exchange,提问作者Rycliff
相关产品推荐
相关产品推荐

