更新记录
1.0.0(2026-08-28)
新发布
平台兼容性
uni-app(3.8.12)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| √ | × | √ |
dlq-escpos 原生 USB 打印机驱动插件
本插件是为 Android POS 收银设备量身定制的纯原生 ESC/POS USB 打印机驱动插件。完全摒弃了不可控的第三方 .jar 黑盒 SDK,直接使用 Android 底层 UsbManager 通讯。
✨ 核心优势
- 绝对防卡死 (Anti-ANR):所有的 USB 硬件读写都在独立的后台子线程运行,带有严格的 1000ms 熔断和 5000ms 传输超时机制。哪怕打印机物理损坏、断电,收银机页面也绝对不会卡死。
- 瞬间缺纸检测:每次打印前通过
DLE EOT 4实时回读传感器状态,缺纸瞬间极速拦截,真正做到 0 延迟提示报错。 - 极高兼容性:底层 API 向下兼容至 Android 3.1,完美适配市面上老旧的 Android 6.0/7.0/8.0 收银机,向上兼容至 Android 14(已通过 PendingIntent 和 RECEIVER_EXPORTED 安全适配)。
- 纯净无依赖:不引入任何外部
.jar或.aar,使用纯 Kotlin 编写,彻底告别编译冲突和内存泄漏。
🛠️ API 接口说明
所有接口均支持同步或异步(Promise)调用。
1. 获取设备列表 listUsbDevices()
扫描收银机上插着的所有 USB 打印机。自动过滤鼠标、键盘等无关设备,同时兼容便宜的 Vendor Specific (255) 杂牌打印机。
- 返回值:
Array<string>,USB 设备名称数组(如[/dev/bus/usb/001/002])
2. 连接打印机 connectUsbAsync(deviceName: string)
连接指定的打印机并自动申请 USB 权限。
- 参数:
deviceName(必填) - 从设备列表里选中的设备名称。 - 返回值:
Promise<{ success: boolean, message: string }>
3. 断开连接 disconnect()
释放 USB 通道接口,断开与当前打印机的连接。
- 返回值:
{ success: boolean, message: string }>
4. 检查连接状态 isConnected()
实时物理级检测。不仅检查软件变量,还会瞬间扫描 Android 系统底层设备列表,线被拔出瞬间即刻返回 false。
- 返回值:
boolean
5. 打印文本小票 printTextReceiptAsync(title, subtitle, lines)
打印标准的排版小票(自带 GBK 中文编码转换,自带走纸)。
- 参数:
title: 主标题(居中,字体放大一倍)subtitle: 副标题(居中,正常字体,可为空)lines: 明细行数组(左对齐,正常字体)
- 返回值:
Promise<{ success: boolean, message: string }>
6. 打印二维码图片 printQrImageAsync(imagePath)
将本地的图片文件转化为黑白单色位图矩阵,并发送给打印机(支持极速大图切片传输)。
- 参数:
imagePath- 本地图片绝对路径(支持_www/或直接绝对路径) - 返回值:
Promise<{ success: boolean, message: string }>
📖 最佳实践示例
在 Vue 或 TS 文件中,强烈推荐先判断是否需要连接,再执行打印的流程。
完整打印流程示例:
import {
listUsbDevices,
isConnected,
connectUsbAsync,
printTextReceiptAsync,
printQrImageAsync
} from "@/uni_modules/dlq-escpos";
async function doPrintReceipt() {
try {
// 1. 获取设备并检查连接状态
const devices = listUsbDevices();
if (devices.length === 0) {
uni.showToast({ title: "未检测到插有USB打印机", icon: "none" });
return;
}
// 2. 如果当前没连接物理设备,自动连接第一个设备
if (!isConnected()) {
const connectResult = await connectUsbAsync(devices[0]);
if (!connectResult.success) {
uni.showToast({ title: connectResult.message, icon: "none" });
return; // 连接失败(可能是未授权、离线等),提前中止
}
}
// 3. 组装打印数据并发送
const lines: string[] = [];
const divider = "================================";
// 模拟真实的业务数据
const orderData = {
tableName: "V1 豪华包间",
startTime: "2026-08-28 14:00:00",
endTime: "2026-08-28 16:00:00",
duration: "120分钟",
tableFee: "¥150.00",
goods: [
{ name: "冰镇西瓜汁", quantity: 2, price: "¥50.00" }
],
totalAmount: "¥200.00"
};
// 动态构建打印行
lines.push(divider);
lines.push(`台桌名称: ${orderData.tableName}`);
lines.push(`开始时间: ${orderData.startTime}`);
lines.push(`结束时间: ${orderData.endTime}`);
lines.push(`消费时长: ${orderData.duration}`);
lines.push(`台桌费用: ${orderData.tableFee}`);
lines.push(divider);
lines.push("商品名称 数量 费用");
orderData.goods.forEach(item => {
// 简单模拟左右对齐排版
lines.push(`${item.name} ${item.quantity}件 ${item.price}`);
});
lines.push(divider);
lines.push(`应付金额: ${orderData.totalAmount}`);
const printResult = await printTextReceiptAsync("休娱有伴Plus", "欢迎光临", lines);
// 4. 结果处理
if (printResult.success) {
uni.showToast({ title: "打印成功!", icon: "success" });
} else {
// 这里的错误信息非常精准,比如:“打印机缺纸,请补充打印纸” 或 “打印机失去响应或已断开”
uni.showToast({ title: printResult.message, icon: "none" });
}
// 5. 如果需要打印底部二维码
// const qrResult = await printQrImageAsync("/storage/emulated/0/xxx.jpg");
} catch (error) {
console.error("打印出现异常", error);
}
}
⚠️ 注意事项
- 测试基座:修改或首次引入此插件后,必须通过 HBuilderX 打包自定义调试基座才能生效,标准基座无法运行本地的 Kotlin 原生代码。
- 缺纸测试:测试缺纸断电等场景时,不需要再像过去一样傻等卡死,现在是毫秒级瞬间报错。
- USB 权限:首次连接打印机时,Android 系统会弹出 USB 授权弹窗,用户需要勾选“总是允许”,否则插件会报“系统未授权访问USB打印机”。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 11
赞赏 0
下载 12541443
赞赏 1947
赞赏
京公网安备:11010802035340号