更新记录

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 通讯。

✨ 核心优势

  1. 绝对防卡死 (Anti-ANR):所有的 USB 硬件读写都在独立的后台子线程运行,带有严格的 1000ms 熔断和 5000ms 传输超时机制。哪怕打印机物理损坏、断电,收银机页面也绝对不会卡死
  2. 瞬间缺纸检测:每次打印前通过 DLE EOT 4 实时回读传感器状态,缺纸瞬间极速拦截,真正做到 0 延迟提示报错。
  3. 极高兼容性:底层 API 向下兼容至 Android 3.1,完美适配市面上老旧的 Android 6.0/7.0/8.0 收银机,向上兼容至 Android 14(已通过 PendingIntent 和 RECEIVER_EXPORTED 安全适配)。
  4. 纯净无依赖:不引入任何外部 .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);
  }
}

⚠️ 注意事项

  1. 测试基座:修改或首次引入此插件后,必须通过 HBuilderX 打包自定义调试基座才能生效,标准基座无法运行本地的 Kotlin 原生代码。
  2. 缺纸测试:测试缺纸断电等场景时,不需要再像过去一样傻等卡死,现在是毫秒级瞬间报错。
  3. USB 权限:首次连接打印机时,Android 系统会弹出 USB 授权弹窗,用户需要勾选“总是允许”,否则插件会报“系统未授权访问USB打印机”。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<uses‑feature android:name="android.hardware.usb.host"/>

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

不收集

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

不包含