hiprint自定义前端打印组件

Posted 万年打野易大师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hiprint自定义前端打印组件相关的知识,希望对你有一定的参考价值。

项目技术栈:umi3+react17+antd pro5

项目需要打印功能,需要能自定义打印模版,极短的时间找到了一个叫hiprint的插件

官方地址:hiprint插件

该插件基于Jquery,所以在react项目中需要引入jquery,好难受哇

先从官网下载对应的文件,得到hiprint文件包。

官方示例看源代码可以用鼠标右键->查看源码

踩坑从引入插件开始,首先需要引入jQuery相关的配置,在全局配置了jQuery的设置,不生效,最后无奈全局引入

import $ from \'jquery\';

源码中可以通过html自定义拖拽组件,我在实践中试了,有问题,折中使用了他原本的拖拽组件

最大的缺点:代码被编译过,无法准确读取源码的设计(研究了好几天)

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.遇到的问题

1、浏览器最小字体大小不能低于12px,可以使用放大缩小样式控制,不过不能保证打印出来效果很好,需要调整打印机的一些配置。最好还是按照12px来,字体选择黑体,字体在插件就设置了2个选项,可以自己取添加浏览器支持的字体样式。在hiprint.bundle.js文件中ctrl+f搜索 宋体 把在百度搜到的浏览器支持的字体选项放进去即可

2、引入的全局hiprint组件重复加载,因为在生成项目的时候会在window下生成对应的hinnn对象,

1).可以在卸载组件的时候去删除这个hinnn对象,delete window.hinnn

2).也可以在不变动的组件上去初始化引入一次,例如头部组件RightContent

// DefaultElementTypeProvider是上述printConf.js文件中引入的
hiprint.init({
  providers: [DefaultElementTypeProvider({})],
});

3、遇到样式检查问题,千万记得把这个文件夹屏蔽了,.eslinignore 文件里添加对应你print相关文件路劲下的文件

4、多模版预览打印无法产生回调函数,使用自定义模版渲染预览(除了此方法,此功能貌似无解)

5、多模版直接打印无法选择打印机(未知解决)

6、直接打印功能无法使用,显示连接失败,下载官网的安装包,安装好后运行就好了

7、打印机设置,后更

8、后端存配置项,一定要用原数据类型,数字不能改成字符串。hiprintTemplate.getJson()获取配置项信息

9、快速预览没有效果,加个延迟函数

10、面板宽高计算是按cm计算的,字体大小是按pt计算的,都要换算一遍成px,设置对应的宽度大小,和字体大小

11、打印的时候设计的样式跟我们预设样式不一样,打印机配置也没调整,在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\'%>" />

12、图片无法显示在面板上,静态文件就放在上述问题对应的image路径下。动态文件(含http绝对路径)需要按照先引入再使用

以上是关于hiprint自定义前端打印组件的主要内容,如果未能解决你的问题,请参考以下文章

Hiprint打印模板table表格拖动合并BUG

Hiprint打印模板table表格拖动合并BUG

Hiprint打印模板table表格拖动合并BUG

Hiprint打印模板table表格拖动合并BUG

HiPrint打印多层table表头渲染数据bug修复

HiPrint打印多层table表头渲染数据bug修复