更新记录
1.0.0(2026-09-24)
- 首次发布,支持 uni-app Android 5.0+ 和 iOS 12.0+ App 真机运行。
- 支持 Android 经典蓝牙、Wi-Fi(RAW TCP)和 USB Host(OTG)连接;支持 iOS BLE 蓝牙和 Wi-Fi(RAW TCP)连接。
- 支持 ESC/POS、TSPL、CPCL、ZPL 打印协议,以及文本、图片、一维码、二维码、PDF417 和线框等常用打印内容。
- 支持连接状态、原始数据、打印机状态、设备信息和打印结果回调,并提供常用打印参数设置接口。
- 提供蓝牙扫描、设备连接及各打印协议的完整 Demo 和接入文档。
平台兼容性
uni-app(4.87)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | - | 5.0 | 12 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | - | × | × |
uni-app x(4.87)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | - | - | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | √ | √ |
xl-hanyinPrinter
汉印 UxPrint 打印机 UTS 插件,面向 uni-app 的 App 端,提供打印机连接、指令生成、数据发送和状态查询能力。
- Android:经典蓝牙、Wi-Fi(RAW TCP)和 USB Host(OTG)
- iOS:BLE 蓝牙和 Wi-Fi(RAW TCP)
- 打印协议:ESC/POS、TSPL、CPCL、ZPL
- 打印内容:文本、图片、一维码、二维码、PDF417、线框等
- 设备能力:状态查询、设备信息、打印结果和常用参数设置
插件包含原生 SDK,只支持 App 真机运行,不支持 H5 和各类小程序。USB 连接目前仅支持 Android。
运行要求
| 项目 | 要求 |
|---|---|
| HBuilderX | 3.6.8 及以上 |
| 项目类型 | uni-app App 项目;本 Demo 使用 Vue 3 |
| Android | Android 5.0(API 21)及以上 |
| iOS | iOS 12 及以上 |
| 调试设备 | 真实 Android/iOS 设备及支持相应协议的打印机 |
首次运行带原生插件的项目时,请使用包含本插件的自定义调试基座,或直接云打包安装到真机。普通浏览器和小程序开发工具无法验证打印功能。
先运行 Demo
- 用 HBuilderX 打开本项目。
- 在
manifest.json中确认 App 标识、Android 权限和 iOS 隐私描述。 - 制作包含
xl-hanyinPrinter的自定义调试基座,并运行到真机。 - 打开打印机,并根据需要准备蓝牙、局域网或 OTG 数据线。
- 在首页选择连接方式。连接成功后进入 ESC/POS、TSPL、CPCL、ZPL 或“通用”页面测试。
Demo 已包含以下完整流程,可直接作为业务代码参考:
pages/index/index.vue:连接、断开和连接状态监听pages/bluetooth/bluetooth.vue:蓝牙扫描与设备选择pages/esc/esc.vue:票据、图片、条码、页模式和设备查询pages/tspl/tspl.vue:标签、内置字体、文本块和状态查询pages/cpcl/cpcl.vue:便携标签和打印结果查询pages/zpl/zpl.vue:工业标签打印pages/common/common.vue:设备信息查询和通用参数设置
接入自己的项目
将插件目录放到项目的 uni_modules/xl-hanyinPrinter 下,然后从模块路径按需导入:
import {
connectBlue,
connectWifi,
connectUsb,
disconnect,
isConnect,
onConnectStateChange
} from '@/uni_modules/xl-hanyinPrinter'
权限配置
Android 端需要蓝牙扫描/连接、旧系统定位兼容和网络权限。插件的 AndroidManifest.xml 已声明必要权限,扫描时也会按系统版本申请运行时权限。若主项目自行维护权限列表,请参考本 Demo 的 manifest.json,至少保留:
- Android 12 及以上:
BLUETOOTH_SCAN、BLUETOOTH_CONNECT - Android 11 及以下:
BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION - Wi-Fi:
INTERNET、ACCESS_NETWORK_STATE
iOS 主项目需要在 manifest.json 的“App 权限配置”中填写蓝牙和本地网络用途说明:
{
"NSBluetoothAlwaysUsageDescription": "用于搜索并连接蓝牙打印机",
"NSBluetoothPeripheralUsageDescription": "用于搜索并连接蓝牙打印机",
"NSLocalNetworkUsageDescription": "用于通过局域网连接并使用 WiFi 打印机"
}
发布前请根据应用实际用途调整文案。用户拒绝权限后,蓝牙扫描或局域网连接会失败。
连接打印机
所有连接方式都通过 onConnectStateChange() 异步返回结果。建议在发起连接前注册监听,并根据 state 更新页面状态。
import {
onConnectStateChange,
disconnect,
isConnect
} from '@/uni_modules/xl-hanyinPrinter'
onConnectStateChange((result) => {
if (result.state === 'connectSuccess') {
console.log('连接成功', result.device)
} else if (result.state === 'connectFail') {
console.error('连接失败', result.message)
} else if (result.state === 'disconnect') {
console.log('连接已断开', result.message)
}
})
console.log('当前是否已连接:', isConnect())
// 页面销毁或不再使用打印机时主动断开
disconnect()
result.state 的值为:
| 值 | 含义 |
|---|---|
connectSuccess |
连接成功,可以发送打印或查询指令 |
connectFail |
连接失败,原因见 message |
disconnect |
主动断开、连接丢失或设备被拔出 |
蓝牙连接
Android 扫描经典蓝牙打印机,iOS 扫描 BLE 打印机。发现设备后,把回调中的 deviceId 原样传给 connectBlue()。
import {
scanBlue,
stopScanBlue,
connectBlue
} from '@/uni_modules/xl-hanyinPrinter'
scanBlue((device) => {
console.log(device.name, device.deviceId, device.paired)
// 用户选中设备后:
// stopScanBlue()
// connectBlue(device.deviceId)
})
// 页面退出或扫描超时后必须停止扫描
setTimeout(() => stopScanBlue(), 12000)
注意:
- 连接前请确认系统蓝牙已开启,打印机处于可发现状态。
- Android 低版本的蓝牙扫描依赖定位权限;部分系统还要求开启定位服务。
- 不要写死
deviceId。iOS 返回的是系统生成的标识,应使用本次扫描结果。
Wi-Fi 连接
手机和打印机需要处于可互通的局域网中。RAW 打印端口通常为 9100,也可按打印机配置传入其他端口。
import { connectWifi } from '@/uni_modules/xl-hanyinPrinter'
connectWifi('192.168.1.100')
// 指定端口
connectWifi('192.168.1.100', 9100)
如果连接失败,请先确认手机能访问打印机 IP、打印机已启用 RAW TCP 服务,并检查 AP 隔离、防火墙和端口配置。
USB 连接(仅 Android)
通过 OTG 接入 USB 打印机后调用 connectUsb()。插件会自动选择第一个包含 USB Printer Class 接口的设备,并在首次使用时弹出系统授权。
import { connectUsb } from '@/uni_modules/xl-hanyinPrinter'
connectUsb()
USB 打印机需提供 Printer Class 接口及 Bulk IN/OUT 端点。若提示未找到设备,请检查手机是否支持 USB Host、OTG 是否开启,以及数据线是否支持数据传输。
第一次打印
先理解指令缓冲区
大多数打印和设置方法只会把指令加入内存缓冲区,并不会立即发给打印机。标准流程是:
- 用
clearCommands()清理上一次未发送的内容。 - 按顺序调用协议方法生成一批指令。
- 调用一次
writeData()发送整批指令。
writeData() 完成后会清空缓冲区。连接断开时不要继续生成或发送指令。
import {
clearCommands,
escInitializePrinter,
escText,
escPrintAndFeedLines,
writeData
} from '@/uni_modules/xl-hanyinPrinter'
clearCommands()
escInitializePrinter()
escText('Hello, UxPrint!', {
align: 'center',
bold: true,
fontSize: 32,
encoding: 'GB18030'
})
escPrintAndFeedLines(3)
writeData((result) => {
if (result.complete) {
console.log('指令发送成功')
} else {
console.error('发送失败:', result.message)
}
})
writeData().complete 表示数据是否完整写入连接通道,不等同于纸张已经打印完成。需要确认物理打印结果时,请使用打印结果相关接口,并确保打印机型号支持结果上报。
TSPL 标签
import {
clearCommands,
tsplSize,
tsplCls,
tsplText,
tsplQRCode,
tsplPrint,
writeData
} from '@/uni_modules/xl-hanyinPrinter'
clearCommands()
tsplSize({ width: 60, height: 40 }) // TSPL 通常使用毫米
tsplCls()
tsplText({ content: '商品标签', x: 20, y: 20, fontSize: 24 })
tsplQRCode({ content: 'SKU-10001', x: 20, y: 70, size: 5, errorLevel: 'M' })
tsplPrint(1)
writeData((result) => console.log(result))
CPCL 标签
import {
clearCommands,
cpclSize,
cpclText,
cpclBarCode,
cpclPrint,
writeData
} from '@/uni_modules/xl-hanyinPrinter'
clearCommands()
cpclSize({ width: 576, height: 400, copies: 1 })
cpclText({ content: '订单号:A10001', x: 20, y: 30, fontSize: 24 })
cpclBarCode({ content: 'A10001', x: 20, y: 100, width: 2, height: 80, type: '128' })
cpclPrint()
writeData((result) => console.log(result))
ZPL 标签
import {
clearCommands,
zplStart,
zplPrintWidth,
zplLabelLength,
zplText,
zplQRCode,
zplPrint,
writeData
} from '@/uni_modules/xl-hanyinPrinter'
clearCommands()
zplStart()
zplPrintWidth(576)
zplLabelLength(360)
zplText({ content: 'UxPrint ZPL', x: 40, y: 30, fontName: '0', fontSize: 40 })
zplQRCode({ content: 'https://example.com', x: 40, y: 100, size: 6 })
zplPrint(1)
writeData((result) => console.log(result))
查询打印机
状态、设备信息、通用参数和打印结果属于查询操作。这些方法会直接发送请求并读取响应,不需要调用 writeData()。
import { escGetStatus, escGetDeviceInfo } from '@/uni_modules/xl-hanyinPrinter'
escGetStatus((result) => {
if (!result.complete || !result.status) {
console.error(result.message)
return
}
console.log('在线:', result.status.isOnline)
console.log('缺纸:', result.status.isPaperOut)
console.log('开盖:', result.status.isCoverOpen)
console.log('过热:', result.status.isOverheating)
})
escGetDeviceInfo((result) => {
if (result.complete && result.info) {
console.log(result.info.model, result.info.firmware, result.info.serialNumber)
}
})
同一时间只允许一个查询等待打印机响应。请等待当前查询回调后再发起下一次查询;超时、解析失败或断开连接时,回调中的 complete 为 false,具体原因见 message。
打印图片
四种协议的图片接口都接收 ImageCommand:
{
base64: 'data:image/png;base64,...', // 也可以只传纯 Base64
x: 0,
y: 0,
width: 384, // 打印宽度,单位 dot
height: 200, // 打印高度,单位 dot
dithering: true, // 扩散抖动转黑白图
compress: false // LZO 压缩,需要打印机支持
}
请在传入前按打印机有效宽度缩放图片。203 dpi 机型常见纸宽对应关系约为:58 mm 纸使用 384 dot,80 mm 纸使用 576 dot,实际可打印宽度以机型为准。图片过大时会增加处理时间和传输失败概率。
API 速查
| 分类 | 常用接口 |
|---|---|
| 连接与监听 | scanBlue、stopScanBlue、connectBlue、connectWifi、connectUsb、disconnect、isConnect、onConnectStateChange、onBlueStateChange、onDataReceive |
| 缓冲与发送 | clearCommands、writeData |
| ESC/POS | escText、escImage、escBarCode、escQRCode、escPDF417、escPrintTableRow、escGetStatus、escGetDeviceInfo、escGetPrintResult |
| TSPL | tsplSize、tsplCls、tsplText、tsplTextWithFont、tsplTextBlock、tsplImage、tsplBarCode、tsplQRCode、tsplPrint、tsplGetStatus |
| CPCL | cpclSize、cpclText、cpclImage、cpclBarCode、cpclQRCode、cpclForm、cpclPrint、cpclGetStatus、cpclGetPrintResult |
| ZPL | zplStart、zplText、zplImage、zplBarCode、zplQRCode、zplPrint、zplGetStatus |
| 通用查询与设置 | getPrinterModel、getSerialNumber、getFirmwareVersion、getBatteryLevel、getPaperType、setPaperType、getPrintWidth、setPrintWidth、setPrintDensity、resetPrinter |
| 原始指令 | escStringCommand / escBytesCommand,以及对应的 tspl*、cpcl*、zpl* 方法 |
完整方法签名、参数类型、默认值和字段说明见 utssdk/interface.uts。
哪些方法需要 writeData()
需要调用 writeData():
- 文本、图片、条码、二维码、走纸、切纸、自检页等打印和设备控制方法
setPaperType()、setPrintWidth()、setPrintDensity()等通用设置方法*StringCommand()和*BytesCommand()原始指令方法
不需要调用 writeData():
escGetStatus()、escGetDeviceInfo()、tsplGetStatus()、cpclGetStatus()、zplGetStatus()getPrinterModel()、getSerialNumber()、getFirmwareVersion()等通用查询escGetPrintResult()、cpclGetPrintResult()、cpclGetPrintResultWithoutId()等结果查询
打印结果查询有一个例外:打印任务本身仍需调用 writeData() 发送,结果查询接口负责等待该任务的打印机响应。完整时序请参考 Demo 中的 ESC/POS 和 CPCL 页面。
常见问题
扫描不到蓝牙打印机
- 确认打印机已开机、蓝牙可发现,且没有被其他手机占用。
- Android 请授予“附近的设备”权限;Android 11 及以下同时检查定位权限和定位服务。
- iOS 请在系统设置中允许应用使用蓝牙。
- 停止旧扫描后重新调用
scanBlue(),不要同时启动多次扫描。
已连接但没有出纸
- 确认使用的协议与打印机当前仿真模式一致。
- 检查生成指令后是否调用了
writeData()。 - 查看
writeData()的complete和message,并用对应协议的*GetStatus()检查缺纸、开盖或过热。 - 标签协议通常还需要结束指令:TSPL 使用
tsplPrint(),CPCL 使用cpclPrint(),ZPL 使用zplPrint()。
中文乱码
- ESC/POS 文本默认使用
GB18030,也可以通过encoding显式指定。 - 确认打印机固件支持相同字符编码、代码页或中文字体。
- TSPL/ZPL 内置字体不一定包含中文;需要时可使用 SDK 栅格化文字接口或改为图片打印。
Wi-Fi 连接超时
- 确认手机和打印机处于同一局域网,且网段可互通。
- 检查打印机 IP 是否变化、RAW TCP 端口是否为
9100。 - 关闭路由器的客户端/AP 隔离,检查防火墙是否拦截端口。
- iOS 首次使用时允许“本地网络”权限。
查询一直超时
- 并非所有机型都支持所有状态和设备信息指令,请先核对型号协议手册。
- 同一时刻只执行一个查询,并等待回调后再发起下一个。
- 确保当前没有其他页面或业务同时读写打印机。

收藏人数:
购买普通授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 873
赞赏 8
下载 12638854
赞赏 1950
赞赏
京公网安备:11010802035340号