
本文详解如何在 frappe 的 jinja2 打印格式(print format)中,为「selling price」列实时累加求和,并在表格底部准确展示总计值,避免硬编码或数据库重复查询。
在 Frappe 的自定义打印模板中,若需对某列(如 Selling Price)进行行级汇总并展示总金额,不能依赖前端 JavaScript(因打印模板纯服务端渲染),而应使用 Jinja2 的变量声明与累加逻辑。关键在于:在循环外初始化累计变量,在循环内持续更新,循环结束后输出结果。
以下是一个完整、健壮的实现示例(兼容标准 Sales Invoice 或类似含 items 子表的 DocType):
{%- set total = 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 -%}
{{ row.item_code }} | {{ row.item_name }} | {{ row.qty }} | {{ '%0.2f'|format(rate) }} | {{ '%0.2f'|format(row.selling_price) }}
{%- set total = total + (row.selling_price|float) -%}
{%- endfor -%}
**Total Selling Amount:** {{ '%0.2f'|format(total) }}✅ 注意事项与最佳实践:
- 使用 {%- ... -%} 语法消除 Jinja2 输出中的多余空白与换行,提升打印排版整洁度;
- frappe.db.get_value 查询应添加 or 0 防止空值导致模板报错(尤其当价格未配置时);
- 建议优先使用 row.selling_price(若字段已存在且已计算好),而非重复执行 rate * qty,既保证与业务逻辑一致,又减少 DB 查询压力;
- 若 selling_price 字段不可靠,可改用 rate * row.qty|float 计算单行金额,但务必确保 rate 和 qty 均为数值类型(建议加 |float 转换);
- 总金额务必通过 '%0.2f'|format(total) 格式化,避免浮点精度问题(如 199.999999 显示为 200.00)。
? 进阶提示: 如需同时显示含税总额、折扣合计等,可按相同模式声明多个变量(如 total_tax, total_discount),并在循环中同步累加,保持逻辑清晰、可维护性强。











