在前端开发中,除了将数据呈现后,我们往往需要为用户提供,打印,导出等能力,导出是为了存档或是二次分析,而打印则因为很多单据需要打印出来作为主要的单据来进行下一环节的票据支撑, 而前端打印可以说是非常令人头疼的一件事。为什么令大家头疼呢?因为前端打印,要强依赖与浏览器的打印预览页面,会天然存在以下弊端:
- 每一次打印都要弹出来打印预览对话框,如果前端需要批量打印,那么意味着客户要点击无数个关闭按钮,才能实现批量打印,如果一次性打印几百张上千张的报表,则会成为“NightMare”。
- 前端打印强依赖于浏览器,主流的思路是先将内容转换为 PDF 文件,再调用浏览器的打印功能进行打印,而生成 PDF 文件是依赖于浏览器对于字体,边线等的处理,因此浏览器的异同则直接导致打印出来的效果差距很大,有的边线加粗,有的 1 页数据,打印出来呈现 2 页,也是让开发者十分苦恼的事情,对于一些打印要求比较高的行业,这就是灾难。
因此如何在前端实现无预览打印,也就是用户点击打印之后直接就使用默认打印机打印出来。针对这个需求,我们验证了一个解决该问题的方案,本贴就来介绍该方案如何实现。
实现思路如下:
后端实现一个接口,接收 Blob 类型 PDF 流,然后调用系统默认打印机,将PDF 进行静默打印。前端利用 ACTIVEREPORTSJS 自带的导出 PDF,导出 Blob 类型,然后通过POST 请求调用后端接口将 Blob 流传给后端进行打印。
具体实现步骤:
前端实现方法:
前端利用 ActivereportsJS 的 PDF.exportDocument 无预览导出 PDF,该接口返回的 result 包含 data 属性和 download 方法,然后调用后端接口,将result.data 传递给后端。
1. function printPDF() {
2. var ACTIVEREPORTSJS = GC.ActiveReports.Core;
3. var PDF = GC.ActiveReports.PdfExport;
4.
5. var settings = {
6. info: {
7. title: "test",
8. author: "GrapeCity inc.",
9. },
10. pdfVersion: "1.7",
11. };
12.
13. var pageReport = new ACTIVEREPORTSJS.PageReport();
14. pageReport
15. .load("1.rdlx-json")
16. .then(function () {
17. return pageReport.run();
18. })
19. .then(function (pageDocument) {
20. return PDF.exportDocument(pageDocument, settings);
21. })
22. .then(function (result) {
23. let formData = new FormData();
24. formData.append("file", result.data);
25. fetch("http://localhost:8088/print", {
26. method: 'POST',
27. mode: 'cors',
28. body: formData
29. })
30. });
31. }
具体 PDF.exportDocument 可以参考文档:
https://demo.grapecity.com.cn...
后端实现方式:
我这边是采用 python 实现了一个接口,接收前端传递的 Blob 文件流,然后调用后端部署的服务器默认打印机直接进行静默打印。
后端程序可以部署到服务器上,如果是 windows 服务器,可以直接下载 exe,在服务器上运行。
• 下载链接: https://pan.baidu.com/s/1De2V... 提取码: 569c
下载下来是 2 个 exe 程序,需要放在同一个文件夹,然后运行 PrintAgent.exe,切记这两个程序需要放在同一个文件夹。
注意:如果 exe 只给服务器上部署,那么前端在打印时调用服务器地址接口打印,最终都会从服务器上连接的打印机打出来。
如果 exe 给客户端部署了,那么前端打印就可以代码调用 localhost 地址去打印,最终就会从客户端所连接的默认打印机打印出来;切换打印机的话,就调整 windows 的默认打印机就可以。
Linux 服务器的话需要将源码拷贝到服务器去运行。源码如下,也可以根据自己需要进行调整和修改:
https://gcdn.grapecity.com.cn...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。