vue-plugin-hiprint 从装环境到落地:3 步跑通可视化打印设计
2026/8/22 17:47:35 网站建设 项目流程

vue-plugin-hiprint 从装环境到落地:3 步跑通可视化打印设计

【免费下载链接】vue-plugin-hiprinthiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑项目地址: https://gitcode.com/gh_mirrors/vu/vue-plugin-hiprint

做业务系统的人大概都踩过同一个坑:前端页面调得漂漂亮亮,一到打印就原形毕露。表格错位、分页乱跳,只能硬凑 HTML 和 CSS。vue-plugin-hiprint 把打印模板做成了可视化设计器:左侧拖拽组件、中间画模板、右侧调属性,设计完直接拿到模板 JSON,接上数据就能打。Vue2 和 Vue3 项目都能用,适合单据、标签、报表这类打印场景。

装好环境,10 分钟看到第一个打印模板

环境只有一个硬性要求:Node.js 16.x,项目 package.json 里写的是>=16。确认版本后装包:

node -v # 应为 v16.x npm install vue-plugin-hiprint

还有一个容易漏掉的前置动作:在项目的 index.html 里引入打印专用样式,文件名必须是 print-lock.css,且 media="print":

<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" />

这行是后面排障部分要讲的头号坑的来源,现在加上就省事了。

接下来在组件里搭最简设计器。设计器是 jQuery 风格 API,页面里先要准备三块容器:可拖拽元素列表(节点带 tid 属性)、属性面板容器、模板容器。初始化四步走,这段代码直接决定你能不能看到效果:

import { hiprint, defaultElementTypeProvider } from "vue-plugin-hiprint"; hiprint.init({ providers: [new defaultElementTypeProvider()], lang: "cn" }); // 把页面上的拖拽元素注册进来,tid 需与 provider 对应 hiprint.PrintElementTypeManager.buildByHtml($(".ep-draggable-item")); const hiprintTemplate = new hiprint.PrintTemplate({ template: {}, // 空模板,从零开始拖 settingContainer: "#PrintElementOptionSetting", // 右侧属性面板容器 paginationContainer: ".hiprint-printPagination" // 多页签容器,可省略 }); hiprintTemplate.design("#hiprint-printTemplate"); // 渲染设计器

两个关键点:design传入的容器就是画板,模板最终画在里面;buildByHtml必须在design之前执行,拖拽列表才有内容。跑起来之后,从左侧把文本、图片、表格拖进中间区域,右侧面板会实时出现属性编辑项,就是下面这个效果:

打印设计器已经跑起来:左侧是拖拽组件列表,中间是模板画板,右侧是对应元素的属性面板

四个真正用得上的能力

上面只是把架子立起来,下面逐个拆它解决的具体问题。

拖拽即所见即所得

设计器的价值在于布局不用写一行 CSS。元素拖进来后,选中它,右侧面板可以直接改字体、字号、对齐、边框、背景色,尺寸用鼠标拉。所有改动都落在模板 JSON 里,随时可回滚(开启history: true后有撤销重做)。

const tpl = new hiprint.PrintTemplate({ template: {}, history: true // 开启撤销重做 });

数据绑定:{{field}} 与表格 field

模板里文本元素填{{name}}这样的占位,表格元素绑定一个数组字段,打印时传入数据即可。这是"设计一次、数据 N 份"的核心。

const printData = { name: "张三", table: [ { id: "1", count: "120", amount: "9089元" }, { id: "2", count: "20", amount: "89元" } ] }; hiprintTemplate.print(printData, {}, { callback: () => console.log("打印窗口已打开") });

表格行的列定义写在元素的 options 里,格式是title#field,打印时按 field 取数。

模板就是 JSON,可存取可下发

设计好的模板随时能导出为 JSON,存数据库或 localStorage;下次用同样的 JSON 新建模板对象,画板原样还原。这意味着"设计"和"使用"可以分离:管理员设计一次,业务员只管点打印。

// 导出 const json = hiprintTemplate.getJson(); localStorage.setItem("tpl", JSON.stringify(json)); // 还原 const saved = JSON.parse(localStorage.getItem("tpl")); const tpl2 = new hiprint.PrintTemplate({ template: saved });

九种语言一个参数

界面文案在init时通过 lang 指定,支持 cn、en、de、es、fr、it、ja、ru、cn_tw 共 9 种,语言包就在仓库的 src/i18n 目录,想改文案可直接编辑后重新打包。

hiprint.init({ providers: [new defaultElementTypeProvider()], lang: "en" // 默认为 cn });

实战:把一张工程单模板做进业务系统

光会拖还不够,拿一个真实单据过一遍完整链路。场景是一家工厂要打印工程单:顶部公司名加订单编号和二维码,中间两张产品明细表格,底部制单人和打印时间。仓库自带的 template4 就是这种单子的效果:

目标效果:一张工程单,包含订单信息、两张产品明细表格、二维码与制单人签名区

分四步。第一步还是初始化,但这次模板 JSON 是现成的(比如存库后取出来),跳过拖拽直接渲染:

import { hiprint, defaultElementTypeProvider } from "vue-plugin-hiprint"; hiprint.init({ providers: [new defaultElementTypeProvider()] }); // 从接口拿到的模板 JSON const tplJson = await fetch("/api/template/engineer").then(r => r.json()); const tpl = new hiprint.PrintTemplate({ template: tplJson });

注意这里没有design——只打印、不编辑时,创建模板对象就够了,更省 DOM。

第二步,打印数据按模板里的字段名组织。明细表是数组,每张表的列名与表头一一对应:

const printData = { companyName: "XXXX有限公司", orderNo: "XY202304001", projectNo: "GLSW2023001", customer: "广州戈蓝生物科技有限公司", date: "2023-06-03", products: [ { type: "面纸", name: "350克冰白珠光纸", size: "787*830", qty: "1400", craft: "哑胶" }, { type: "内盒卡纸", name: "350克单铜", size: "787*830", qty: "2300", craft: "击凸" } ] };

第三步,先走浏览器预览,确认版式:

tpl.print(printData, {}, { callback: () => console.log("预览窗口已打开") });

预览无误后,接客户端就可以静默直接打印,不再弹出系统对话框。print2传数组就是批量:

// 打印机名从 hiwebSocket.printerList 里取 name tpl.print2(printData, { printer: "工程单打印机", title: "工程单打印" }); tpl.print2(batchData, { printer: "工程单打印机", copies: 2 }); tpl.on("printSuccess", res => console.log("完成", res)); tpl.on("printError", err => console.error("失败", err));

到这里,设计器负责"长什么样",业务代码只负责"喂数据",两边通过字段名解耦。改版式不用动业务代码,换数据不用重开设计器。

五个高频坑与修法

跑通之后,下面五个问题出现频率最高,按现象对号入座。

坑 1:打印时版式错乱、元素重叠。原因是 index.html 没引 print-lock.css,或忘了media="print"。浏览器打印只加载 print 媒体下的样式,缺了它模板定位全部失效。修复就是回到第一节那行 link,文件放 public 目录、文件名保持 print-lock.css。

坑 2:控制台持续刷 socket 连接报错。插件内置了 socket.io-client,加载即尝试连接客户端;没装客户端或客户端是官网老版本(socket.io 2.x)就会报错。本地不打印就关掉:

import { disAutoConnect } from "vue-plugin-hiprint"; disAutoConnect();

要打印则使用本仓库配套的 electron-hiprint 客户端(见 apiDoc.md),不要混用官网老客户端,模板格式对不上。

坑 3:拖拽列表是空的,组件拖不进去。buildByHtml靠 DOM 节点的 tid 属性识别元素,节点没写 tid、tid 与 provider 对不上、或者先调了 design 再调 buildByHtml,都会导致拖不出东西。检查顺序:tid 正确 → buildByHtml 在 design 之前。

坑 4:本地能连客户端,线上连不上。客户端默认监听 http://localhost:17521,线上页面是 https,浏览器直接拦截混合连接。两条路:站点升级 https 后直连内网地址;或挂 node-hiprint-transit 中转服务,此时 print2 必须额外传 client 指定客户端:

hiprint.init({ host: "https://your-transit:17521", token: "hiprint-xxx" }); tpl.print2(printData, { client: clientId, printer: "打印机名", title: "任务名" });

坑 5:print2 不报错但不出纸。先确认客户端已启动(主窗口显示"打印服务已启动"),再确认 printer 传的是hiwebSocket.printerList里真实的 name,手写名称差一个空格都会匹配失败。

改源码或加自定义元素,从这里入手

主分支就是把 hiprint 源码融进仓库的 npm 包源码,动手前先看这几个目录:

  • src/hiprint/hiprint.bundle.js:核心打印引擎,模板、分页、元素渲染都在这里
  • src/hiprint/etypes/default-etyps-provider.js:默认元素类型定义,加新元素从这仿一个
  • src/demo/design/:官方拖拽设计器 demo,页面结构、JSON 导入导出的完整参考
  • src/i18n/:9 种语言包

自定义元素走 provider 扩展,demo 里给了现成范式(src/demo/panels/providers.js):

class MyProvider extends defaultElementTypeProvider { getPrintElements() { const base = super.getPrintElements(); return [...base, { tid: "custom", title: "自定义", elements: [{ tid: "signature", title: "签字区", type: "text" }] }]; } }

注册进hiprint.init的 providers 即可在拖拽列表里看到"签字区"。

写在最后

  • 拖拽设计:组件拖进画板,布局零 CSS
  • 模板 JSON:设计一次,随数据批量复用
  • 静默打印:客户端直连,批量任务不弹窗
  • 多语言:9 种界面语言,一个参数切换
  • 双框架:Vue2 / Vue3 通用,纯 JS 引擎

仓库地址 https://gitcode.com/gh_mirrors/vu/vue-plugin-hiprint ,clone 下来npm i && npm run serve打开 demo,把今天这条链路自己再走一遍。

【免费下载链接】vue-plugin-hiprinthiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑项目地址: https://gitcode.com/gh_mirrors/vu/vue-plugin-hiprint

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询