項目技術棧:umi3+react17+antd pro5css
項目須要打印功能,須要能自定義打印模版,極短的時間找到了一個叫hiprint的插件html
官方地址:hiprint插件react
該插件基於Jquery,因此在react項目中須要引入jquery,好難受哇jquery
先從官網下載對應的文件,獲得hiprint文件包。json
官方示例看源代碼能夠用鼠標右鍵->查看源碼canvas
踩坑從引入插件開始,首先須要引入jQuery相關的配置,在全局配置了jQuery的設置,不生效,最後無奈全局引入後端
import $ from 'jquery';
瀏覽器
源碼中能夠經過html自定義拖拽組件,我在實踐中試了,有問題,折中使用了他本來的拖拽組件antd
最大的缺點:代碼被編譯過,沒法準確讀取源碼的設計(研究了好幾天)socket
// 打印設計面板的樣式 import './css/hiprint.css'; // 打印機預覽和直接打印的樣式 import './css/print-lock.css'; // 二維碼插件 import QRCode from 'qrcodejs2'; // 條形碼插件 import JsBarcode from 'jsbarcode'; import jQuery from 'jquery'; // 兼容IE import './polyfill.min.js'; import hiwprint from './plugins/jquery.hiwprint.js'; import './plugins/jquery.minicolors.min.js'; // 直接打印功能須要用到的socket.io插件 import io from './plugins/socket.io.js'; // 這些是對應的文件包內的插件 import jsPDF from './plugins/jspdf/jspdf.min.js'; import './plugins/jspdf/canvas2image.js'; import canvg from './plugins/jspdf/canvg.min.js'; import html2canvas from './plugins/jspdf/html2canvas.min.js'; import $ from 'jquery'; // window在調用IO判斷的時候須要有值 window.io = io; // 傳遞jquery到打印預覽的iframe彈窗 hiwprint(jQuery); ... // 修改此處代碼爲導出,以便在界面中使用 export const hiprint = (function (t) { ...
在項目運行時會有對象不存在報錯,直接把對應地方的xxx.xxx改成xxx?.xxx就好了
後面作完了認真研究了一下這個被編譯後的代碼,打印功能實現並不難,就是使用的window.print和document.execCommand('print', false, null)這兩個方法。感興趣的能夠去MDN搜搜
// 引入hiprint import { hiprint } from '@/plugins/hiprint/hiprint.bundle'; import $ from 'jquery'; // 防止ts報類型錯誤 type Win = Window & { hinnn?: any; [key: string]: any; }; ... // 點擊畫布中的元素,右側元素設置欄打開 const elementAddEventListen = () => { const win: Win = window; win.hinnn.event.on(hiprintTemplate.getPrintElementSelectEventKey(), function (t: any) { setParamsDrawerTitle(t.printElement.printElementType.title); setVisible(true); }); }; // 基礎的模版配置,默認是A4紙 const baseConf = { panels: [ { index: 0, paperType: 'A4', height: 297, width: 210, paperHeader: 0, paperFooter: 0, printElements: [], paperNumberLeft: 565, paperNumberTop: 819, paperNumberDisabled: true, }, ], }; useEffect(() => { // eslint-disable-next-line func-names $(async function () { /** * 配置打印模版參數 * @param template: 生成的panel面板配置json數據 * @param settingContainer: 組件屬性設置的html容器 * @param paginationContainer: 當前面板的分頁設置容器,能夠不加 */ hiprintTemplate = await new hiprint.PrintTemplate({ template: baseConf, settingContainer: '#PrintElementOptionSetting', paginationContainer: '.hiprint-printPagination', }); // 設置左側拖拽事件 hiprint.PrintElementTypeManager.build('.hiprintEpContainer', 'defaultModule'); // hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item')); // 打印設計面板 hiprintTemplate.design('#hiprint-printTemplate'); // 設置右側參數設置模版 elementAddEventListen(); // 獲取本地打印機信息,可能有BUG setTimeout(() => { const printerList = hiprintTemplate.getPrinterList(); }, 1500); }); }, []);
其餘功能參考官方的資料就行
裏面的參數都是左側拖拽面板的東西,能夠自定義,更多請參考官方示例
/* eslint-disable */ import { hiprint } from '@/plugins/hiprint/hiprint.bundle.js'; export const DefaultElementTypeProvider = (() => { return function (options: any) { let addElementTypes = function (context: any) { context.addPrintElementTypes('defaultModule', [ // 每個PrintElementTypeGroup是一個組件分類塊 new hiprint.PrintElementTypeGroup('常規組件', [ { tid: 'defaultModule.text', title: '文本', data: '', type: 'text', }, { tid: 'defaultModule.image', title: '圖片', data: '/images/shuixi.png', type: 'image', }, { tid: 'defaultModule.longText', title: '長文', data: '155123456789', type: 'longText', }, { tid: 'defaultModule.table', field: 'table', title: '自定義表格', type: 'table', groupFields: ['name'], groupFooterFormatter: function (group: any, option: any) { console.log(group); console.log(option); return '這裏自定義統計腳信息'; }, columns: [ [ { title: '行號', fixed: true, rowspan: 2, field: 'id', width: 70, }, { title: '人員信息', colspan: 2 }, { title: '銷售統計', colspan: 2 }, ], [ { title: '姓名', align: 'left', field: 'name', width: 100, }, { title: '性別', field: 'gender', width: 100 }, { title: '銷售數量', field: 'count', width: 100, }, { title: '銷售金額', field: 'amount', width: 100, }, ], ], }, { tid: 'defaultModule.tableCustom', title: '表格', type: 'tableCustom', }, { tid: 'defaultModule.customText', title: '自定義文本', customText: '自定義文本', custom: true, type: 'text', }, ]), new hiprint.PrintElementTypeGroup('輔助', [ { tid: 'defaultModule.hline', title: '橫線', type: 'hline', }, { tid: 'defaultModule.vline', title: '豎線', type: 'vline', }, { tid: 'defaultModule.rect', title: '矩形', type: 'rect', }, { tid: 'defaultModule.oval', title: '橢圓', type: 'oval', }, ]), ]); }; return { addElementTypes, }; }; })();
5.遇到的問題
一、瀏覽器最小字體大小不能低於12px,可使用放大縮小樣式控制,不過不能保證打印出來效果很好,須要調整打印機的一些配置。最好仍是按照12px來,字體選擇黑體,字體在插件就設置了2個選項,能夠本身取添加瀏覽器支持的字體樣式。在hiprint.bundle.js
文件中ctrl+f搜索 宋體
把在百度搜到的瀏覽器支持的字體選項放進去便可
二、引入的全局hiprint組件重複加載,由於在生成項目的時候會在window下生成對應的hinnn對象,
1).能夠在卸載組件的時候去刪除這個hinnn對象,delete window.hinnn
;
2).也能夠在不變更的組件上去初始化引入一次,例如頭部組件RightContent
// DefaultElementTypeProvider是上述printConf.js文件中引入的 hiprint.init({ providers: [DefaultElementTypeProvider({})], });
三、遇到樣式檢查問題,千萬記得把這個文件夾屏蔽了,.eslinignore
文件裏添加對應你print相關文件路勁下的文件
四、多模版預覽打印沒法產生回調函數,使用自定義模版渲染預覽(除了此方法,此功能貌似無解)
五、多模版直接打印沒法選擇打印機(未知解決)
六、直接打印功能沒法使用,顯示鏈接失敗,下載官網的安裝包,安裝好後運行就行了
七、打印機設置,後更
八、後端存配置項,必定要用原數據類型,數字不能改爲字符串。hiprintTemplate.getJson()
獲取配置項信息
九、快速預覽沒有效果,加個延遲函數
十、面板寬高計算是按cm計算的,字體大小是按pt計算的,都要換算一遍成px,設置對應的寬度大小,和字體大小
十一、打印的時候設計的樣式跟咱們預設樣式不同,打印機配置也沒調整,在document.ejs文件引入對應的link
// 文件必定要按照路徑匹配放到public文件夾下 <link media="print" href="<%= context.config.publicPath +'css/hiprint.css'%>" /> <link media="print" href="<%= context.config.publicPath +'css/print-lock.css'%>" />
十二、圖片沒法顯示在面板上,靜態文件就放在上述問題對應的image路徑下。動態文件(含http絕對路徑)須要按照先引入再使用