当前位置: 首页 > news >正文

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)

流程概览:

  1. 客户端安装 QZ Tray(对应系统的可执行程序)。

  2. 在网页中引入 qz-tray.js(或用 npm 包)。

  3. 在 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-printernode-escposprinters 等库可以直接访问系统打印机与串口/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();});
});

实践建议

  1. 只是网页式发票/单据 → 用 window.print()(最快);若要自动选择打印机或发送原始 ESC/POS 指令 → 用 QZ Tray。

  2. 小票机 / POS 场景 → 强烈推荐 QZ Tray 或 Electron(QZ 更适合浏览器端部署)。

  3. 完全浏览器并想免安装 → 尝试 WebUSB(有兼容性与实现复杂度,通常不是首选)。

  4. 若用户设备受控(公司内部) → 可以配合本地服务(如小的 Node 服务)或 Electron,部署最可控可靠。


http://www.lryc.cn/news/619269.html

相关文章:

  • Pytorch FSDP权重分片保存与合并
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day3
  • 【Qt开发】常用控件(三) -> geometry
  • 疏老师-python训练营-Day44预训练模型
  • php7 太空船运算符
  • Linux 软件编程:文件IO、目录IO、时间函数
  • 适配安卓15(对应的sdk是35)
  • RxJava 在 Android 中的深入解析:使用、原理与最佳实践
  • 大牌点餐接口api对接全流程
  • 《吃透 C++ 类和对象(中):构造函数与析构函数的核心逻辑》
  • Ubuntu22.04轻松安装Qt与OpenCV库
  • 药房智能盘库系统的Python编程分析与实现—基于计算机视觉与时间序列预测的智能库存管理方案
  • 基于大数据spark的医用消耗选品采集数据可视化分析系统【Hadoop、spark、python】
  • 分段锁和限流的间接实现
  • 通信中间件 Fast DDS(一) :编译、安装和测试
  • 机器学习—— TF-IDF文本特征提取评估权重 + Jieba 库进行分词(以《红楼梦》为例)
  • CMake进阶: 使用FetchContent方法基于gTest的C++单元测试
  • LINUX812 shell脚本:if else,for 判断素数,创建用户
  • 【GESP】C++一级知识点之【集成开发环境】
  • TF-IDF:信息检索与文本挖掘的统计权重基石
  • [SC]如何使用sc_semaphore实现对共享资源的访问控制
  • 初识神经网络04——构建神经网络2
  • 【从零开始java学习|第四篇】IntelliJ IDEA 入门指南
  • Redis序列化配置类
  • uni-app实战教程 从0到1开发 画图软件 (学会画图)
  • 基于STC8单片机的RTC时钟实现:从原理到实践
  • 聚合搜索中的设计模式
  • 数据结构:中缀到后缀的转换(Infix to Postfix Conversion)
  • 开发避坑指南(23):Tomcat高版本URL特殊字符限制问题解决方案(RFC 7230 RFC 3986)
  • 一键设置 NTP 时区的脚本(亲测,适用于部署 K8S 的前置环境)