hiprint自定義前端打印組件

項目技術棧:umi3+react17+antd pro5css

項目須要打印功能,須要能自定義打印模版,極短的時間找到了一個叫hiprint的插件html

官方地址:hiprint插件react

該插件基於Jquery,因此在react項目中須要引入jquery,好難受哇jquery

先從官網下載對應的文件,獲得hiprint文件包。json

官方示例看源代碼能夠用鼠標右鍵->查看源碼canvas

踩坑從引入插件開始,首先須要引入jQuery相關的配置,在全局配置了jQuery的設置,不生效,最後無奈全局引入後端

import $ from 'jquery';瀏覽器

源碼中能夠經過html自定義拖拽組件,我在實踐中試了,有問題,折中使用了他本來的拖拽組件antd

最大的缺點:代碼被編譯過,沒法準確讀取源碼的設計(研究了好幾天)socket

1.在hiprint.bundle.js文件中引入相應的文件包

// 打印設計面板的樣式
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搜搜

2.hiprint.config.js文件中定義的是一個拖拽組件塊的配置項,最後都被打包到hiprint.bundle.js中去了

3.在pages下定義/Print/PrintSetting/index.tsx

// 引入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);
  });
}, []);

其餘功能參考官方的資料就行

4.建立/Print/PrintSetting/printConf.ts

裏面的參數都是左側拖拽面板的東西,能夠自定義,更多請參考官方示例

/* 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絕對路徑)須要按照先引入再使用

相關文章
相關標籤/搜索