
本文介绍如何在 frappe 框架的 jinja2 打印格式(print format)中,为“销售价格”列实时累加并展示总金额,通过定义局部变量、循环累加及最终输出实现精准汇总。
在 Frappe 的自定义打印模板中,若需对某列(如 Selling Price)进行行级汇总并显示合计值,不能依赖后台预计算字段(如 doc.total_selling_price),尤其当该值未被 DocType 显式存储或需基于动态查询(如实时获取 Item Price)时,推荐在模板内使用 Jinja2 原生逻辑完成累加。
以下是一个完整、可直接复用的打印模板片段示例,已优化结构与健壮性:
{%- set total = 0.0 -%}
Item Code
Item Name
Qty
Rate
Selling Price
{%- for row in doc.items -%}
{%- set rate = frappe.db.get_value("Item Price", {
"item_code": row.item_code,
"price_list": doc.price_list,
"selling": 1
}, "price_list_rate") or 0.0 -%}
{%- set selling_price = (rate * row.qty)|float -%}
{{ row.item_code }}
{{ row.item_name }}
{{ row.qty }}
{{ '%0.3f' | format(rate) }}
{{ '%0.3f' | format(selling_price) }}
{%- set total = total + selling_price -%}
{%- endfor -%}
Total: {{ '%0.3f' | format(total) }}✅ 关键说明:
- 使用 {%- set total = 0.0 -%} 初始化浮点型变量,避免整数累加导致精度丢失;
- frappe.db.get_value() 查询失败时返回 None,因此用 or 0.0 提供安全默认值,防止模板渲染报错;
- selling_price 独立计算并缓存,确保与显示值一致,避免重复表达式调用;
- 所有 {%- ... -%} 语法去除前后空白符,提升生成 PDF 的排版整洁度;
- 最终 Total 行统一保留三位小数,与各行列格式一致,符合财务打印规范。
⚠️ 注意事项:
- 此方式适用于数据量较小的单据(如销售发票、报价单),若 items 超过百行,频繁 DB 查询可能影响 PDF 渲染性能——建议将价格逻辑前置至 DocType 的 before_print 方法中预计算并挂载到 doc 对象;
- 若 row.selling_price 字段已在数据库中准确存储且可信,可直接使用 row.selling_price 替代动态计算,进一步提升效率;
- 所有自定义 Jinja 变量仅在当前模板作用域生效,不影响后台逻辑或其它视图。
通过以上方法,你无需修改 Python 代码或重新部署,即可快速增强打印格式的业务表达能力,实现专业、准确、可维护的金额汇总展示。











