1个二维码干掉2000灵点?多维表格自定义打印的3小时血泪史

Lv.4 核心创作者
1个二维码干掉2000灵点?多维表格自定义打印的3小时血泪史
📌
先问个问题
你在多维表格里做过自定义打印吗?
就是那种:数据填好了,点一下按钮,自动生成一张带二维码的PDF,保存到附件字段里。
听起来很常规对吧?我之前也这么想。
结果呢?一个二维码图片,折腾了3小时,9轮调试,差点烧掉2000灵点。 最后发现解决方案简单到让人无语。
需求其实很简单
XB-ERP系统里有个"销售下单"表,每条订单需要生成一张PDF,上面要有全部字段信息,右上角还要有个生产单号二维码,打印出来扫码就能查。
流程就是:
读取记录 → 填XLSX模板 → 插入二维码 → 导出PDF → 存到附件字段中间那个"插入二维码"四个字,就是3小时噩梦的开始。
第1板斧:HTTP.get——扑了个空
第一反应,用 HTTP.get 下载二维码图片,转base64,用 InsertImage 插进模板。
var imgResp = HTTP.get('二维码API');
var base64Data = 'data:image/png;base64,' + imgResp.body;结果呢?
HTTP状态: 200 body类型: undefinedHTTP.get 返回的对象长这样:{msg, readDone, limit}。没有body属性。 msg 是一个Node.js流对象,根本读不出来。
这就好比快递到了,快递员站在门口,但你打不开门。
第2板斧:换API——换汤不换药
以为是二维码API的问题,换了好几个——api.qrserver.com、api.2dcode.biz。结果一样,body始终是undefined。
跟API无关,AirScript的HTTP.get就是拿不到二进制数据。
第3板斧:IMAGE公式——CoreCrash
既然下载不了,那就换个思路:不下载图片,直接写=IMAGE("二维码URL")公式,让ET自己加载。
sheet.Range('D4').Value = '=IMAGE("二维码URL")';写进去了。然后 Save(),准备导出PDF。
CoreCrash。
服务端ET引擎一执行IMAGE公式就崩溃。公式能写,但导出就挂。
三条路,全堵死。 这时候已经过去快1小时了。
第4板斧:曲线救国——走通了但不敢用
既然AirScript搞不定图片,那就换方案:Python生成二维码,openpyxl嵌入XLSX,上传云文档,AirScript只负责导出。
Python(qrcode + openpyxl)
→ 生成带二维码的XLSX
→ 上传云文档
→ AirScript打开 → 导出PDF → 写附件走通了,PDF里二维码正常显示。
但问题来了:每次新增订单,都得找我跑一次Python。 一次按2000灵点算,一天10个新订单就是2万灵点。一个月下来,光这个功能就烧掉几十万灵点。
用户问了一句:"那以后新增记录还消耗灵点吗?"
我不能说"是"。
第5板斧:转机来了
回头重新研究AirScript的HTTP API。HTTP.get 不行,那 HTTP.fetch 呢?
var resp = HTTP.fetch(url);
var str = resp.text();
console.log(str); // "PNG IHDRddX..."能读到数据了! HTTP.fetch(url).text() 返回了响应体字符串。
当时还高兴了一下,但马上发现不对劲。
第6板斧:UTF-8的陷阱
拿到字符串后,转base64,插入图片,报错:
Error: InvalidArgument查了一下原因:
实际PNG文件227字节
text() 返回223字符
第一个字节 0x89 被替换成了 0xFFFD(Unicode替换字符)
91个字符的编码值大于255
text() 默认把二进制数据当UTF-8文本解码。多字节序列被合并了,原始数据已经丢了。base64出来的图片是坏的。
HTTP.fetch能拿到数据,但拿回来的数据是坏的。
第7板斧:setEncoding——直接崩了
那能不能在读取之前设置编码为binary?
resp.msg.setEncoding('binary');直接崩溃。
uncaughtTypeError: chunk.copy is not a functionAirScript的stream实现不完整,不支持setEncoding。
第8板斧:确认问题出在哪
这时候已经有点怀疑人生了。用Python生成一个正确的二维码base64,直接硬编码到脚本里测试:
// 正确的base64
InsertImage('data:image/png;base64,iVBORw0KGgo...') → 成功!
InsertImage('iVBORw0KGgo...') → 也成功!InsertImage本身没问题。 问题100%出在 text() 的UTF-8解码上。
第9板斧:换个思路,让API返回文本
既然 text() 只能处理文本,那就找一个返回base64文本的二维码API。
找到了:quickchart.io/qr?text=xxx&format=base64
Content-Type: text/plain
返回值是纯ASCII字符串
text() 不会损坏验证:
返回948字符的base64字符串
解码后709字节,PNG文件头正确
InsertImage → 成功
导出PDF → 成功
最终链路,简单到离谱:
HTTP.fetch('quickchart.io/qr?text=xxx&format=base64')
→ .text() → 纯base64文本
→ data:image/png;base64,xxx
→ InsertImage → 导出PDF → 写附件📌
这句话值2000灵点
AirScript的HTTP.get没有body,只能用HTTP.fetch的text()。但text()默认UTF-8解码,会损坏二进制数据。所以不能用返回二进制PNG的二维码API,得用返回纯文本base64的API。
说白了就是:HTTP.fetch().text()只能读文本。那就让API返回文本——base64字符串就是文本。
最终成果
指标 | 数据 |
调试轮次 | 9轮 |
耗时 | 3小时 |
灵点消耗 | 0(最终方案全在AirScript内完成) |
新增记录 | 直接运行脚本,零额外成本 |
现在新增订单,直接打开脚本编辑器点运行,PDF自动生成,二维码自动插入,附件自动写入。不消耗灵点,全自动。
一个脚本,9轮调试,搞定。
📌
古老师(古哥计划)|中小制造数字化专家|金山 KVP(金山办公最有价值专家)|金山多维表格应用场景专家|金山 WPS 社区优秀创作者
深耕中小制造业数字化落地,擅长用 WPS 多维表格 + AI 低代码方案,帮工厂快速搭建进销存、生产计划、质量追溯等轻量化系统。不用复杂 IT,低成本落地,已服务数百家制造企业,实战经验丰富。
#多维表格 #AirScript #工厂管理 #AI应用 #二维码
Lv.1 新人创作者
Lv.4 核心创作者
Lv.4 核心创作者