变量不渲染主因是数据结构与模板路径不匹配,如{{user.name}}需传{'user':{'name':'张三'}};表格跨页需手动分页;关闭autoescape和慎用richtext可提升性能;模板须全选设中文字体防乱码。

模板里变量不渲染?检查 docxtpl 的语法和上下文传入方式
变量没替换,大概率不是模板写错了,而是传进去的数据结构对不上。比如模板里写 {{ user.name }},但你传的是 {'user': {'name': '张三'}} —— 这没问题;可如果传的是 {'name': '张三'},那就会静默失败,不报错也不渲染。
- 模板中用点号访问嵌套字段(如
{{ order.items.0.name }}),必须确保数据是字典/对象,且层级存在;items为空列表时,.0会直接跳过该段,不报错也不显示 - 用
{% for item in items %}...{% endfor %}循环时,items必须是 Python 可迭代对象,None或字符串都会导致崩溃,错误信息通常是TypeError: 'NoneType' object is not iterable - 中文冒号、全角括号、多余空格(如
{{ user . name }})会导致语法解析失败,但docxtpl默认不报错,只留原样文本
docxtpl 不支持表格跨页自动拆分?得手动预处理数据
Word 原生表格跨页断行是靠 Word 自己控制的,docxtpl 只负责把数据填进模板表格行里,它不会帮你判断“这一行放不下,要拆到下一页”。结果就是长表格在生成后突然被截断、丢失内容,或者整张表被挤到下一页空白处。
- 如果每条记录对应一行,且行数不确定,别依赖模板里一个固定表格+循环塞满——先在 Python 里按页面估算行数(比如每页最多 35 行),把
data_list拆成page_chunks,再用{% for chunk in page_chunks %}包一层 - 避免在循环内嵌套复杂格式(如合并单元格 + 循环),
docxtpl对colspan/rowspan的支持有限,容易错位;真需要合并,改用python-docx手动构建更稳 - 表格内有图片或段落样式?
docxtpl只能插占位符文字,图片得用substitute_picture单独处理,且路径必须是绝对路径或当前工作目录相对路径
导出大报表卡死或内存爆掉?关掉 autoescape 和慎用 RichText
默认开启的 HTML 转义(autoescape=True)会把所有字段过一遍正则,遇到含大量特殊字符的字段(比如日志片段、SQL 示例)会明显拖慢速度;而 RichText 对每个带样式的字符串都新建一个 Paragraph 对象,1000 条记录就建 1000 个,内存涨得飞快。
- 关闭转义:初始化时加参数
DocxTemplate('tpl.docx', autoescape=False),前提是确认数据不含恶意 HTML 片段 - 不用
RichText就别导入它;真需要加粗/颜色,优先用模板里已设好的样式名(如{{ user_name|style:'Heading2' }}),比运行时构造轻量得多 - 导出前调用
context.clear()清掉不用的中间变量,尤其在循环生成多个文件时,避免上一轮数据污染下一轮
Windows 上中文乱码、字体失效?不是编码问题,是 Word 模板没嵌入字体设置
生成的 Word 打开显示方块或宋体变雅黑,不是 Python 编码惹的祸,而是模板文档本身没指定中文字体,Word 用系统默认 fallback 字体去凑——不同机器表现不一。
立即学习“Python免费学习笔记(深入)”;
- 用 Word 打开模板 → 全选(Ctrl+A)→ 字体设为“微软雅黑”或“等线”,再设字号、段落间距,保存。这一步必须做,
docxtpl不修改字体定义,只填内容 - 不要在模板里用“华文仿宋”“方正小标宋”这类非系统自带字体,用户没装就必然回退,且无法预测回退成什么
- Linux/macOS 服务器上生成时,如果用 headless LibreOffice 预览,记得装好
fonts-wqy-zenhei等中文字体包,否则 PDF 导出也会丢字
None,这两处不出错也埋雷。










