寫在前面
寫這篇文章的源頭,要從公司的快遞面單打印提及。最近指定了我來主要負責這一塊內容。能夠說之前對打印是一無所知,對打印暴露出來的問題簡直就是小白啊,問題分析不清楚、緣由找不到、猜都沒有方向。。。javascript
先說一下以前前端 web
打印咱們使用的方案吧,一直是用部門本身封裝的打印npm
包,封裝的不復雜,就是對瀏覽器 window.print()
沒有的兩個功能進行補充:自動分頁和頁面指定內容區域打印。由於咱們知道直接調用window.print()
只能進行整個網頁內容的打印。css
可是這個打印方案最近暴露出來比較多的問題,一樣的紙張換了打印機以後就不行了,一樣的內容樣式在不一樣打印機上面結果相差大等等。html
因此這就有問題了:
一、是打印機對樣式屬性的支持狀況良莠不齊?
二、是否有一套打印執行標準是咱們不知道的?
三、選了不一樣紙張以後預覽頁面的不一樣程度拉伸收縮是咱們寫樣式的問題嗎?
四、不一樣的打印機型號會對打印有什麼影響?
五、打印是否會對頁面內容作拉伸?
六、打印對單位的支持?
七、打印識別紙張?是否能夠提早獲取打印機的型號?
前端
帶着這些疑問,小白開啓了一輪打印知識的瘋狂充電🔋。vue
打印相關常識
這一部分見小白的上一片文章:瀏覽器打印知識掃盲java
當前 web 前端打印方案調研
一、瀏覽器的右鍵菜單打印功能
這是最簡單的,只需點擊頁面上的打印菜單,可是也是問題最多的,基本上是不能知足用戶須要。react
💣好比:jquery
- 不能精確分頁,有出現打出半行字的風險;
- 改變紙型後打印出的格式和頁面顯示的格式相差太大;
- 頁眉頁腳也須要從菜單中去設置,等等。
這種方案最大的優點就是不須要作任何代碼,點擊打印就能夠了。linux
window.print() // or document.execCommand('print') 複製代碼
這實際上,是瀏覽器打印功能菜單的一種程序調用。與點擊打印功能菜單同樣,不能精確分頁,不能設置紙型,套打的問題更加無從談起,只不過,可讓用戶不用去點菜單,直接點擊網頁中的一個按鈕,或一個連接裏面調用罷了。git
須要指出的是這種方法提供一個打印前和打印後的事件 onbeforeprint
、onafterprint
。能夠在打印前的時候從新編輯一些格式,專門送去打印,打印後又處理回來。
function .onbeforeprint() {} function .onafterprint() { //放開隱藏的元素 } 複製代碼
事實上,不少用戶都是採用這種方式打印,window.print()
方法很是不方便的地方是沒法經過傳參的方式對打印操做進行設置,須要在 css 中進行設置。
二、使用 print css
使用print css
,對要打印的頁面書寫兩套 css
,一套用於瀏覽器頁面顯示,一套用於紙張打印。
這種方法經過在 html
文檔中,嵌入打印相關的 css
樣式,來實現對html文檔輸出打印的控制,好比設置紙張大小,紙張縱橫方向,打印邊距,分頁等。
這一種比第一種直接調用瀏覽器的打印功能打印好一點,等於說是加了一些打印的樣式以後,再傳遞給打印機打印。
🍒優勢:
- 這種方式成本小,不須要下載任何插件,並且跨平臺性很是好;
- 可能能適配
90%
以上的打印,但不敢說100%
;
💣缺點:
print css
推出已經有些時日,但遺憾的是,至今沒有一個廠商的瀏覽器很好地實現了這些標準,這使得程序員目前還不能利用print css
進行實際的開發。
ps:這其實就是咱們如今使用的打印方案,可是咱們作的比較差勁。
- 咱們的樣式單位使用的都是相對單位px,這在打印中很容易出問題;
- 是由於咱們的有紙張適配需求,可是咱們的紙張打印樣式都是隻寫了一套,並無針對不一樣的紙張尺寸去寫一套樣式,因此咱們的打印始終脫離不了打印機,始終不能真正作到只適配打印紙張。
🌟結論:就是若是咱們最後仍是使用這種打印的話,須要注意:
- 最好是針對每一種打印紙張寫一份打印樣式,不要再採用原來一份樣式兼容二者這種;
- 使用 print css,單位都是用絕對單位;
- 不要使用浮動定位;
- 。。。
✅hiprint
🌟🌟🌟這裏調研到有一個使用 print css
實現 web
端打印的免費的 js
庫,依賴於 jquery
實現。官網:hiprint.io/。
hiprint
是一個web 打印的js組件,無需安裝軟件。支持windows
,macOS
,linux
系統,支持移動端,PC
端瀏覽器,angular
,vue
,react
等 分頁預覽,打印,操做簡單,運行快速。預覽界面爲 css+html
。支持數據分組,批量預覽。生成 pdf
,圖片更方便。
🍒優勢:
- 可以
cover
如今咱們的頁面打印元素的要求; - 批量打印也支持;
- 將咱們以前寫
html + css
的方式 改成寫json
模板和 打印數據json
的方式; - 使用的是絕對定位和絕對單位,這都是很是古老的
css
,基本沒有打印機會不支持; - 免費;
💣缺點:
- 須要引入
jquery
; - 配置項比較多,可是寫過一個面板以後其實就還好。
結論:hiprint
可使用,可以解決目前咱們打印的問題和需求。
三、導出 excel 導出 pdf 文件的打印
這種方案是經過從服務端返回文件流,將打印的數據導出成 excel
文檔或者 pdf
文件,而後在客戶端打開文件進行打印。
🍒優勢:
- 可以實現精確的打印;
- 套打也能實現;
💣缺點:
- 須要客戶端配合安裝 excel 後者 adobe 軟件;
- 處處的 excel 可能會被從新修改編輯,不安全;
- 須要服務端配合,代價也是有的;
四、applet
方式
採用 applet
方式,分頁或精確打印,均可以作到完美,但缺點也很明顯,表如今:
- 安裝
applet
成本巨大。須要下載十幾 MB 的文件。 applet
自己可能並不大,但運行applet
所需的jre
通常>10m
。用戶須要極大的耐心,來進行打印。- 打印報表時,須要從新向服務器檢索數據,效率低。
- 由於
applet
方案,通常採用html
方式呈現數據,打印時applet
必須向服務器檢索同一張票據的數據,看上去,是打印了當前頁的票據,實際上,applet
根本不會用當前html
頁的數據來打印,而是向服務器下載數據到applet
中來打印。也就是說,打印的話,必須兩次請求,一次html
呈現,一次用來打印。 - 市場上
java
類的報表工具,通常推薦applet
方式來實現打印。
PS:這一種技術感受沒看懂也不知道咋用用😂。
五、純 activex
控件
這種方案其實就是編寫一個 c/s
的打印控件,而後經過 <object>
標籤內嵌入到頁面裏面,將要打印的數據裝入到控件中,而後打印。
🍒優勢:打印精度高,分頁,設置打印參數等等都能實現。
💣缺點:也是很明顯的,嵌入
activex
控件破壞了web
應用的總體html
風格,且這樣的控件一般都比較大,通常都超過 1m,下載很慢。
六、輕量級的-activex-插件+-dhtml-+-javascript-+後臺代碼(動態獲取數據)
輕量級的 activex 插件:可以設置打印參數,好比預約義紙型、設置打印方向、打印邊距、指定打印機、靜默打印等等。
Dhtml + javaScript:富文本編輯,支持編輯打印數據的展示格式,實現格式的自定義。
後臺代碼:能夠實現打印數據的動態獲取,好比 websocket 協議鏈接等等。
下面是業界主流的幾種輕量級的 activex 插件。
- Lodop:有免費和收費兩種,免費的有水印,免費提供的功能已經差很少夠用;
- jatoolsPrinter:收費。
- ScriptX:收費,提供的免費功能比較少,免費的功能主要有頁面邊距設置等,咱們的需求使用免費版本應該就能夠了。
- PAZU:PAZU 我的或者商業使用均真正免費受權,無IP或者域名限制。可是須要申請綁定IP或域名和4Fang網站。??? 可是申請時,必須有肯定的IP地址或者域名(主機名),PAZU是綁定IP或者域名的,IP或域名還沒有肯定的咱們不能頒發受權,另外,受權一經頒發就不能修改綁定。 綁定的IP和域名必須是最終用戶的,因此,最終用戶的應用網站必須和4Fang網站作好連接,不然 PAZU會由於沒法驗證受權的合法性而不能正常工做(內網應用除外)。
🌟結論:Lodop這個用的比較多,提供的免費功能不少,自定義紙張、頁面邊距、批量打印等等,須要客戶端配合提早安裝軟件使用。
調研結論
綜合上面對瀏覽器打印的調研,咱們最後仍是決定使用hiprint這個js庫作咱們的打印,可以解決咱們如今遇到的問題:
- 🍒批量打印;
- 🍒自定義分頁;
- 🍒個性化打印內容;
- 🍒打印內容樣式屏蔽打印機差別;
- 🍒免費
哈哈哈哈哈哈。真香!!!!!
easy-print 破殼🐣
如今npm包的大成之勢,爲了方便 hiprint 在項目中引入和使用,小白在 hiprint 的基礎上面進行了封裝,發佈了npm包 easy-print 目前已發佈,附帶詳細的使用demo。
🍒🍒easy-print 的github地址: easy-print
👏👏👏�歡迎感興趣的小夥伴多多star!!!!