4

Project technology stack: umi3+react17+antd pro5

The project needs printing function and needs to be able to customize the printing template. I found a plug-in called hiprint in a very short time

Official address: hiprint plugin

The plug-in is based on Jquery, so jquery needs to be introduced in the react project, so uncomfortable

First download the corresponding file from the official website to get the hiprint file package.

official example to see the source code, you can use the right mouse button -> view source

Starting from the introduction of plug-ins, you first need to introduce jQuery-related configurations, and jQuery settings are configured globally, but they do not take effect. Finally, they have no choice but to import them globally.

import $ from 'jquery';

In the source code, you can customize the drag-and-drop component through html. I tried it in practice, and there was a problem. The original drag-and-drop component was used as a compromise.

biggest shortcoming of : The code has been compiled, and the source code design cannot be read accurately (researched for several days)

1. Introduce the corresponding file package in the hiprint.bundle.js file

// 打印设计面板的样式
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) { ...
When the project is running, there will be an error report if the object does not exist, just change the xxx.xxx of the corresponding place to xxx?.xxx.

After doing this, I carefully studied the compiled code. The printing function is not difficult to implement, which is the window.print and document.execCommand('print', false, null) two methods used. Interested can go to MDN search

2. What is defined in the hiprint.config.js file is a drag-and-drop component block configuration item, which is finally packaged into hiprint.bundle.js

3. Define /Print/PrintSetting/index.tsx under pages

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

For other functions, please refer to the official information

4. Create /Print/PrintSetting/printConf.ts

The parameters inside are all things on the left drag panel, which can be customized, please refer to the official example for more

/* 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. Problems encountered

1. The minimum font size of the browser cannot be lower than 12px, and you can use the zoom-in and zoom-out style control, but it cannot guarantee that the printing effect is good, and some configuration of the printer needs to be adjusted. It is best to follow 12px, choose bold font, and set 2 options for the font in the plug-in. You can add the font style supported by the browser by yourself. In the hiprint.bundle.js file, search for put in the font options supported by the browser found in Baidu.

2. The imported global hiprint component is loaded repeatedly, because the corresponding hinnn object will be generated under the window when the project is generated.

1). You can delete this hinnn object when you uninstall the component, delete window.hinnn ;

2). It can also be initialized and introduced once on the unchanged component, such as the head component RightContent

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

3. If you encounter a style check problem, .eslinignore file corresponding to your print-related file in the 060ab873adf42d file.

4. Multi-template preview printing cannot generate a callback function, use a custom template to render the preview (except for this method, this function seems to have no solution)

5. The printer cannot be selected for direct printing with multiple templates (unknown solution)

6. The direct printing function cannot be used and the connection fails. Download the installation package of the official website and run it after installation.

7. Printer settings, later update

8. The back-end storage configuration item must use the original data type, and the number cannot be changed to a string. hiprintTemplate.getJson() Get configuration item information

9. Quick preview has no effect, add a delay function

10. The width and height of the panel is calculated in cm, and the font size is calculated in pt. You must convert it to px, and set the corresponding width and font size.

11. When printing, the designed style is different from our preset style, and the printer configuration has not been adjusted. Introduce the corresponding link in the document.ejs file

// 文件一定要按照路径匹配放到public文件夹下
<link media="print" href="<%= context.config.publicPath +'css/hiprint.css'%>" />
<link media="print" href="<%= context.config.publicPath +'css/print-lock.css'%>" />

12. The image cannot be displayed on the panel, and the static file is placed in the image path corresponding to the above problem. Dynamic files (including http absolute path) need to be imported before use


万年打野易大师
1.5k 声望1.1k 粉丝