背景:由于项目紧急,入职第一天就开需求评审会,需求方要求系统需要在发货流程静默打印PDF采购清单,不能使用先预览PDF再打印的方式。其实,主流的电商也有相应的场景应用,特别是对接商家、供应商等系统,我对此项做了一天的技术可行性分析,大家如果有类似的需求也可以作为参考。
结论先行
得根据不同场景实现打印——
场景一:直接打印现成的PDF文件
- 后端获取PDF文件的CDN地址,加载到内存
- 后端转base64串返回前端
- 前端读取base64串,通过pdfjs转储到隐藏的canvas控件
- 前端通过lodop控件,以图片方式直接打印到打印机
场景二:后端返回数据直接打印
- 后端提供需要打印的数据字段
- 前端使用html2canvas把数据转储到隐藏的canvas控件
- 前端通过lodop控件,以图片方式直接打印到打印机
场景三:前端下载PDF文件(有打印场景一般也会包括下载的场景)
- 后端提供需要下载的数据字段
- 前端通过html2canvas把dom转成canvas
- 前端通过jspdf生成PDF文件
分析过程
首先,需求是打印PDF,打印PDF有很多技术,首先对比各技术优缺点。对比维度:是否能直接打印PDF、生产环境稳定性、运行环境、集成方式、商业版费用、浏览器兼容性等。列了个二维表横向分析一下各种技术的特性,最后无疑lodop胜出,费用是970(普票)购买顶级域名永久商业版(免费版直接打印会有水印),作为一个生产软件,这个价格也能接受(lodop官网有不同规格的商业版报价)。
其次,lodop没有能根据PDF下载的URL作为入参直接打印PDF,翻阅了github某个lodop的demo发现:可以通过PDF的base64解码,结合pdfjs画到canvas组件,再通过lodop传canvas作为入参实现直接打印,所以问题变成了后端返回PDF资源的base64串。
最后撸完代码才发现,先有系统的逻辑是通过后端直接返回数据,前端使用html2canvas直接画canvas再下载。看到这里,想必大家心里也有了答案:返回后端数据 -> (html2canvas)生成隐藏的canvas -> (lodop)直接打印PDF,问题得以解决。
一些心得
作为一位技术爱好者,需要时刻保持一颗探索的心,做好技术选型、找出最优解,才能体现自己的技术价值。
关注我,一起学习探讨生产落地方案~