You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Frappe(ERPNext)框架下销售发票二维码显示与打印问题咨询

解决方案

问题1:ERPNext预存渲染后的二维码方案(优先推荐)

该方案完全规避前端渲染的兼容性问题,表单、打印场景都可直接调用,无需重复生成二维码。
操作步骤:

  • 进入自定义DocType编辑页,给「销售发票(Sales Invoice)」新增一个类型为Image的自定义字段,字段API名可设为custom_qr_image,权限设为只读,可隐藏在非必要视图中。
  • 服务端安装Python二维码生成依赖:pip install qrcode[pil]
  • 在自定义APP的Sales Invoice控制器钩子中加入生成逻辑,示例代码如下:
import qrcode
import io
import frappe
from frappe.model.document import Document

class SalesInvoice(Document):
    def before_save(self):
        # 替换为你需要编码进二维码的业务字符串
        qr_encode_value = f"INVOICE|{self.name}|{self.grand_total}|{self.posting_date}"
        # 生成二维码对象
        qr_img = qrcode.make(qr_encode_value)
        # 转PNG字节流
        img_byte_io = io.BytesIO()
        qr_img.save(img_byte_io, format="PNG")
        img_content = img_byte_io.getvalue()
        qr_file_name = f"qr_sales_invoice_{self.name}.png"
        # 删除历史旧二维码文件
        frappe.db.delete("File", {
            "attached_to_doctype": "Sales Invoice",
            "attached_to_name": self.name,
            "file_name": qr_file_name
        })
        # 写入新二维码到File文档
        qr_file = frappe.get_doc({
            "doctype": "File",
            "file_name": qr_file_name,
            "attached_to_doctype": "Sales Invoice",
            "attached_to_name": self.name,
            "content": img_content,
            "is_private": 0 # 设为公开可避免打印时权限校验问题
        })
        qr_file.save(ignore_permissions=True)
        # 关联到自定义图片字段
        self.custom_qr_image = qr_file.file_url
  • 打印格式中直接拖入custom_qr_image字段即可正常显示二维码,无需额外逻辑。

问题2:不预存图片,打印页渲染二维码方案

如果不需要持久化存储二维码,可通过自定义打印格式实现渲染:
操作步骤:

  • 提前将QRious库的JS文件上传到ERPNext站点的public/js目录下。
  • 进入「打印格式(Print Format)」新建页面,选择销售发票DocType,类型选「HTML」。
  • 在打印格式模板中写入如下代码:
<!-- 二维码渲染容器 -->
<canvas id="qr_code_container" width="200" height="200"></canvas>
<!-- 引入本地QRious库 -->
<script src="/js/qrious.min.js"></script>
<script>
// 页面加载完成后渲染二维码
document.addEventListener("DOMContentLoaded", () => {
  new QRious({
    element: document.getElementById("qr_code_container"),
    size: 200,
    // 替换为你存储编码字符串的自定义字段API名,Jinja会直接渲染当前发票的对应值
    value: "{{ doc.custom_qr_encode_str }}",
    foreground: "black"
  })
})
</script>

如果使用系统标准打印格式,也可以在销售发票的客户端脚本中监听before_print钩子,提前生成二维码base64写入自定义HTML字段后再触发打印。


内容的提问来源于stack exchange,提问作者Taimur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:54:02