项目技术栈: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绝对路径)须要按照先引入再使用