VUE2连接USB打印机
在 Vue 2 项目里用 USB 打印机,按场景选用:浏览器内 web → window.print()
或 QZ Tray / WebUSB(限制多);桌面/自托管终端 → 用 Electron / 本地服务 最稳定。下面按优先级与场景分开讲并给出 Vue2 示例。
核心选项比较(快速)
window.print()
:最简单,适合打印页面/票据样式 HTML。优点:无需驱动、跨浏览器;缺点:用户需手动选择打印机、不能发 ESC/POS 原始指令。QZ Tray(推荐用于 POS / 小票机):在客户端运行一个本地 agent(QZ Tray),浏览器 JS 调用它可以发送原始 ESC/POS、ZPL 等指令到任意本地打印机。优点:功能强、广泛支持;缺点:需用户安装 QZ Tray 客户端、HTTPS 配置。
WebUSB:浏览器直接访问 USB 设备(需浏览器支持 & HTTPS & 用户授权)。优点:不需要额外客户端;缺点:支持有限、实现较复杂、驱动/协议需自行实现。
Electron / Node 后端:如果你能做成桌面应用或有后端,可在服务器/本地进程直接调用打印驱动(node-printer、escpos 等)。最稳定、最灵活,但不是纯前端方案。
方案 A — 最简单:生成 HTML 用 window.print()
(适合发票/票据)
不涉及 USB 原始指令,用户可选打印机。
Vue2 示例(SFC):
<template><div><div id="print-area" ref="printArea"><!-- 需要打印的票据 HTML --><h2>收据</h2><p>订单编号: 12345</p><p>金额: NT$100</p></div><button @click="print">打印</button></div>
</template><script>
export default {methods: {print() {// 简单方式:新开窗口并调用 print(可更好控制样式)const printContents = this.$refs.printArea.innerHTML;const w = window.open('', '_blank');w.document.write(`<html><head><title>打印</title><style>/* 在这里放打印样式 @media print {...} */</style></head><body>${printContents}</body></html>`);w.document.close();w.focus();w.print();w.close();}}
}
</script>
优点:部署快;缺点:需要用户手动选择打印机与选项,不能发送 ESC/POS。
方案 B — 推荐:使用 QZ Tray 发送原始命令(适合小票机、esc/pos)
流程概览:
客户端安装 QZ Tray(对应系统的可执行程序)。
在网页中引入
qz-tray.js
(或用 npm 包)。在 Vue 中通过 qz API 连接、查找打印机并发送 raw data(plain/hex/escpos)。
示例 Vue2 组件(关键片段):
<template><div><button @click="connect">连接 QZ</button><button @click="printText">打印文本</button><button @click="printEscPos">打印 ESC/POS</button><div>选择打印机: {{ printerName }}</div></div>
</template><script>
// 假设你在 index.html 用 <script src="https://yourcdn/qz-tray.js"></script>
// 或者通过 npm 安装并 import qz from 'qz-tray'(按 qz 提示)
export default {data() {return {printerName: null};},methods: {async connect() {try {await qz.websocket.connect();const printer = await qz.printers.find(); // 默认打印机this.printerName = printer;alert('已连接 QZ,打印机: ' + printer);} catch (e) {console.error(e);alert('连接 QZ 失败: ' + e);}},async printText() {try {const cfg = qz.configs.create(this.printerName);const data = [{ type: 'raw', format: 'plain', data: 'Hello from Vue2\n\n' }];await qz.print(cfg, data);alert('打印文本已发送');} catch (e) {console.error(e);alert('打印失败: ' + e);}},async printEscPos() {try {const cfg = qz.configs.create(this.printerName);// 示例: ESC/POS init + 打印并换纸const hex = '1B40' // 初始化+ '1B6101' // 居中+ this.stringToHex('小票測試\n\n')+ '1D5601'; // 切纸(视打印机支持)const data = [{ type: 'raw', format: 'hex', data: hex }];await qz.print(cfg, data);alert('ESC/POS 指令已发送');} catch (e) {console.error(e);alert('打印失败: ' + e);}},stringToHex(str) {return Array.from(str).map(ch => ch.charCodeAt(0).toString(16).padStart(2, '0')).join('');}},beforeDestroy() {try { qz.websocket.disconnect(); } catch(e) {}}
};
</script>
注意事项与配置:
QZ Tray 要在用户客户端安装并运行(Windows/macOS/Linux)。
出于安全,网页必须走 HTTPS(localhost/127.0.0.1 在多数浏览器可例外)。
QZ 文档有关于证书签名、许可和 API 的详细说明(请参考 QZ 官网)。
qz.printers.find()
可传入字符串或查找特定打印机。
方案 C — WebUSB(实验性,浏览器限制多)
仅当你能控制客户端浏览器并接受兼容性限制时使用。流程:使用 navigator.usb
选择设备、打开、claimInterface、transferOut 发送 bytes(ESC/POS 二进制)。
示例(仅示意):
async function webusbPrint() {// 需要已知厂商/产品 id 或允许用户选择const device = await navigator.usb.requestDevice({ filters: [] }); // 空数组会让用户选择await device.open();if (device.configuration === null) await device.selectConfiguration(1);await device.claimInterface(0);// 构造 ESC/POS bytesconst encoder = new TextEncoder();const data = encoder.encode('Hello WebUSB\n\n');// endpoint number 2 只是示意,实际需查看设备接口描述await device.transferOut(2, data);await device.close();
}
限制:仅部分 Chromium 浏览器支持;需要 HTTPS;需要开发者对 USB 协议/接口有研究;打印机可能不是直接 USB Bulk endpoint(有些需要自定义驱动)。
方案 D — Electron / 后端打印(最稳定,适合 kiosk / 自托管)
如果是内网设备或你能打包成桌面应用,Electron 结合 node-printer
、node-escpos
、printers
等库可以直接访问系统打印机与串口/USB。示例思路:
主进程使用
node-escpos
打印 ESC/POS 到 USB/串口。渲染进程(Vue)向主进程发送 IPC 请求触发打印。
简短示例(伪):
// 主进程
const escpos = require('escpos');
escpos.USB = require('escpos-usb');
ipcMain.handle('print-receipt', async (event, text) => {const device = new escpos.USB();const printer = new escpos.Printer(device);device.open(() => {printer.text(text);printer.cut();printer.close();});
});
实践建议
只是网页式发票/单据 → 用
window.print()
(最快);若要自动选择打印机或发送原始 ESC/POS 指令 → 用 QZ Tray。小票机 / POS 场景 → 强烈推荐 QZ Tray 或 Electron(QZ 更适合浏览器端部署)。
完全浏览器并想免安装 → 尝试 WebUSB(有兼容性与实现复杂度,通常不是首选)。
若用户设备受控(公司内部) → 可以配合本地服务(如小的 Node 服务)或 Electron,部署最可控可靠。