在前端開發中,除了將資料呈現後,我們往往需要為使用者提供,列印,匯出等能力,匯出是為了存檔或是二次分析,而列印則因為很多單據需要列印出來作為主要的單據來進行下一環節的票據支撐, 而前端列印可以說是非常令人頭疼的一件事。
為什麼令大家頭疼呢?
因為前端列印,要強依賴與瀏覽器的預覽列印頁面,會天然存在以下弊端:
每一次列印都要彈出來預覽列印對話方塊,如果前端需要批次列印,那麼意味著客戶要點選無數個關閉按鈕,才能實現批次列印,如果一次性列印幾百張上千張的報表,則會成為「NightMare」。
前端列印強依賴於瀏覽器,主流的思路是先將內容轉換為PDF檔案,再呼叫瀏覽器的列印功能進行列印,而生成PDF檔案是依賴於瀏覽器對於字型,邊線等的處理,因此瀏覽器的異同則直接導致列印出來的效果差距很大,有的邊線加粗,有的1頁資料,列印出來呈現2頁,也是讓開發者十分苦惱的事情,對於一些列印要求比較高的行業,這就是災難。
因此如何在前端實現無預覽列印,也就是使用者點選列印之後直接就使用預設印表機列印出來。針對這個需求,我們驗證了一個解決該問題的方案,本貼就來介紹該方案如何實現。
實現思路如下:
後端實現一個介面,接收Blob型別PDF流,然後呼叫系統預設印表機,將PDF進行靜默列印。
前端利用ACTIVEREPORTSJS自帶的匯出PDF,匯出Blob型別,然後通過POST請求呼叫後端介面將Blob流傳給後端進行列印。
具體實現步驟:
前端實現方法:
前端利用ActivereportsJS的PDF.exportDocument無預覽匯出PDF,該介面返回的result包含data屬性和download方法,然後呼叫後端介面,將result.data傳遞給後端。
function printPDF() {
var ACTIVEREPORTSJS = GC.ActiveReports.Core;
var PDF = GC.ActiveReports.PdfExport;
var settings = {
info: {
title: "test",
author: "GrapeCity inc.",
},
pdfVersion: "1.7",
};
var pageReport = new ACTIVEREPORTSJS.PageReport();
pageReport
.load("1.rdlx-json")
.then(function () {
return pageReport.run();
})
.then(function (pageDocument) {
return PDF.exportDocument(pageDocument, settings);
})
.then(function (result) {
let formData = new FormData();
formData.append("file", result.data);
fetch("http://localhost:8088/print", {
method: 'POST',
mode: 'cors',
body: formData
})
});
}
具體PDF.exportDocument可以參考檔案:
https://demo.grapecity.com.cn/activereportsjs/demos/api/export/purejs
後端實現方式:
我這邊是採用python實現了一個介面,接收前端傳遞的Blob檔案流,然後呼叫後端部署的伺服器預設印表機直接進行靜默列印。
後端程式可以部署到伺服器上,如果是windows伺服器,可以直接下載exe,在伺服器上執行。
下載下來是2個exe程式,需要放在同一個資料夾,然後執行PrintAgent.exe,切記這兩個程式需要放在同一個資料夾。
注意:如果exe只給伺服器上部署,那麼前端在列印時呼叫伺服器地址介面列印,最終都會從伺服器上連線的印表機打出來。
如果exe給使用者端部署了,那麼前端列印就可以程式碼呼叫localhost地址去列印,最終就會從使用者端所連線的預設印表機列印出來;
切換印表機的話,就調整windows的預設印表機就可以。
Linux伺服器的話需要將原始碼拷貝到伺服器去執行。
原始碼如下,也可以根據自己需要進行調整和修改:
另附 前端100張資料視覺化大屏模板,按需取用: