更新记录
1.0.0(2026-10-26)
首个版本:SPP 连接管理、Android 12+ 权限适配、打印任务队列与超时保护、TSPL 指令生成(五种标签元素、六种条码)、JSON 模板体系、内置固定资产与仓库货位模板、指令预览调试、Demo 工程、43 项指令生成自动化测试。
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | - | - | √ | × | √ | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
szhzy-labelprint 蓝牙 TSPL 工业标签打印插件
面向固定资产管理、仓库管理、设备管理、生产制造与零售系统的 Android 蓝牙标签打印 UTS 插件。
通过 Bluetooth Classic SPP(串口) 通道向 TSPL / TSPL2 协议标签打印机发送指令,提供从权限检测、设备连接到任务队列的完整打印链路,以及 JSON 标签模板体系(文本 / 条码 / 二维码 / 直线 / 方框)与指令预览调试能力。
内置固定资产标签与仓库货位标签两套开箱即用的模板,Demo 工程包含设备配对连接、模板选择、打印参数设置、打印日志四个完整页面。
⚠️ 购买前必读
- 本插件仅支持 Android App 平台(面向传统 uni-app Vue3 项目开发与验证;uni-app x 端按兼容模式编写但未实测)。iOS、鸿蒙、Web、小程序均不支持,请确认你的业务平台后再购买。
- 仅支持 TSPL / TSPL2 协议 + 蓝牙 Classic SPP 的打印机。不支持 ESC/POS(小票)、CPCL、ZPL 协议,不支持 BLE(低功耗蓝牙)-only 设备。常见适配目标见插件内《设备兼容说明》。
- 打印中文需要打印机内置中文字库(如 TSS24.BF2)。绝大多数中国市场主流 TSPL 桌面机内置简体中文字库,但部分海外版机型没有,购买前建议先用 Demo 工程在你的打印机上实测。
- 诚实的验证状态:指令生成核心逻辑已经过 43 项自动化测试(含两套内置模板的完整输出比对);但蓝牙通道与设备端物理打印未经本插件作者真机验证(开发期无打印机),购买后请先在 Demo 工程中完成真机自测,若有不适配可联系作者处理。
- 付费版授权与打包规则(DCloud 市场机制):本插件为付费插件,由插件市场自动加密——普通授权版买家不可见插件源码,需要阅读或修改源码请购买源码授权版;加密插件仅支持云端传统打包,不支持离线打包与安心打包;试用版仅可用于打包自定义基座调试,不能用于正式发布;授权绑定 AppID 与包名,购买后更换任一信息需重新购买授权。
环境要求
| 项 | 要求 |
|---|---|
| HBuilderX | 3.99+(建议使用最新 4.x 版本) |
| 项目类型 | uni-app(Vue3,主要支持目标);uni-app x(兼容模式编写,未实测) |
| Android 最低版本 | 6.0(API 23) |
| 打印机 | 支持蓝牙 SPP 的 TSPL/TSPL2 协议标签打印机(203/300/600 dpi) |
| 其他 | 无第三方原生 SDK 依赖,无需申请任何厂商授权 |
真机运行提示:UTS 插件不能在 HBuilderX 标准基座上直接运行。导入插件后,请在 HBuilderX 中执行「运行 → 运行到手机或模拟器 → 制作自定义基座」,基座制作完成后选择「使用自定义基座运行」;正式打包请使用云打包。Android 编译环境配置见 DCloud 官方文档《uts插件Android运行配置》。
快速开始
1. 安装与权限
通过 HBuilderX 导入插件到项目的 uni_modules 目录。插件已自带 utssdk/app-android/AndroidManifest.xml 声明蓝牙权限,云打包时自动合并;如你的项目需要显式管理权限,也可在 manifest.json -> app-plus -> distribute -> android -> permissions 中添加:
"permissions": [
"<uses-permission android:name=\"android.permission.BLUETOOTH\" android:maxSdkVersion=\"30\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" android:maxSdkVersion=\"30\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\"/>"
]
Android 12+ 的
BLUETOOTH_CONNECT为运行时权限,插件内部会在连接前检查并引导申请(见requestBluetoothPermission())。
2. 连接打印机并打印
import {
requestBluetoothPermission, getPairedDevices, connect,
getTemplates, printTemplate, getConnectionInfo
} from '@/uni_modules/szhzy-labelprint'
// ① 确保蓝牙权限(Android 12+ 需要;打印机需先在系统蓝牙设置中完成配对)
const perm = await requestBluetoothPermission()
if (!perm.ok) {
uni.showToast({ title: perm.message, icon: 'none' })
return
}
// ② 获取已配对设备并连接(SPP)
const devices = await getPairedDevices()
if (!devices.ok) {
uni.showToast({ title: devices.message, icon: 'none' })
return
}
const printer = devices.devices[0] // { name, address }
const conn = await connect({ address: printer.address, timeout: 8000, secure: true })
if (!conn.ok) {
uni.showToast({ title: conn.message, icon: 'none' })
return
}
// ③ 使用内置固定资产模板打印
const tplRes = getTemplates()
const asset = tplRes.templates.find(t => t.id === 'asset')
const template = JSON.parse(asset.json)
const result = await printTemplate(template, {
company: 'XX科技有限公司',
assetCode: 'ZC-2026-0001',
assetName: '贴片机 SM-482',
spec: 'YSM-482/V2',
dept: '生产一部',
date: '2026-01-15'
}, { copies: 1, density: 8 })
if (result.ok) {
// ok 仅代表指令字节流已写入蓝牙连接(详见下文「结果语义」)
console.log(`已写入 ${result.bytes} 字节,耗时 ${result.elapsed}ms`)
} else {
console.error(`[${result.code}] ${result.message}`)
}
也可用
printLabel(label)直接按标签描述对象打印,或用printCommand(command)发送你自行拼接的原始 TSPL 指令。
API 参考
所有异步 API 返回 Promise<UTSJSONObject>,统一信封结构,不通过 reject 抛业务错误:
{ ok: boolean, code: string, message: string, ...业务字段 }
权限与系统
| API | 说明 | 返回 |
|---|---|---|
checkBluetoothPermission() |
同步检查蓝牙权限状态 | { granted, needRequest, message } |
requestBluetoothPermission() |
申请 Android 12+ 运行时权限 | { ok, code, message, granted, doNotAskAgain? } |
openBluetoothSettings() |
跳转系统蓝牙设置页(配对入口) | 无 |
getAdapterState() |
蓝牙适配器状态 | { state: "on" / "off" / "unavailable" } |
设备与连接
| API | 说明 | 返回 |
|---|---|---|
getPairedDevices() |
已配对蓝牙设备列表(需权限) | { ok, code, message, devices: [{ name, address }] } |
connect(options) |
建立 SPP 连接 | { ok, code, message, address?, deviceName?, elapsed? } |
disconnect() |
断开连接(幂等) | { ok, code, message } |
getConnectionInfo() |
当前连接信息(同步) | { state, address, deviceName } |
connect 参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| address | string | 是 | 已配对设备的 MAC 地址 |
| timeout | number | 否 | 连接超时毫秒,默认 8000,范围 1000-60000 |
| secure | boolean | 否 | 是否使用加密 RFCOMM,默认 true;部分入门机型连接失败时可尝试 false |
连接语义:重复 connect 同一地址且当前已连接时幂等返回成功;连接其他地址时会先断开旧连接再连接新设备。
模板与指令生成
| API | 说明 | 返回 |
|---|---|---|
getTemplates() |
内置模板元信息 + 完整 JSON | { ok, code, message, templates: [...] } |
getTemplateJson(id) |
按 ID 取模板 JSON 文本 | string \| null |
buildLabelCommand(label, vars?) |
按标签描述生成指令(不发送) | { ok, code, message, command, warnings, encoding } |
renderTemplateCommand(template, vars?, overrides?) |
渲染模板生成指令(不发送) | 同上 |
inspectTemplateText(text) |
校验模板 JSON 文本并返回元信息 | { ok, code, message, template? } |
打印与队列
| API | 说明 | 返回 |
|---|---|---|
printTemplate(template, vars?, overrides?) |
渲染模板并打印(入队) | PrintResult |
printLabel(label, vars?, options?) |
按标签描述打印(入队) | PrintResult |
printCommand(command, options?) |
发送原始 TSPL 指令(入队) | PrintResult |
getQueueInfo() |
队列与连接信息(同步) | { pending, connection } |
cancelPendingTasks() |
取消全部待执行任务(同步) | { cancelled } |
PrintResult:
{
ok: boolean, // true = 指令字节流已完整写入蓝牙连接
code: string,
message: string,
taskId: string, // 任务 ID
bytes: number, // 写入字节数
elapsed: number, // 耗时 ms
pending: number, // 执行后队列剩余任务数
physicalPrintConfirmed: false // 恒为 false,见「结果语义」
}
错误码
| code | 含义 | 建议处理 |
|---|---|---|
| SUCCESS | 成功 | - |
| INVALID_PARAM | 参数缺失或非法 | 检查调用参数 |
| INVALID_TEMPLATE | 标签/模板结构校验失败 | 查看 message 中的具体字段提示 |
| PERMISSION_DENIED | 蓝牙权限被拒绝 | 引导用户授权或前往系统设置 |
| BLUETOOTH_OFF | 系统蓝牙未开启 | 引导开启蓝牙 |
| BLUETOOTH_UNAVAILABLE | 蓝牙适配器不可用 | 设备不支持或系统异常 |
| NO_ACTIVITY | 无法获取当前 Activity | 环境异常,重启页面 |
| CONNECT_TIMEOUT | 连接超时 | 检查打印机开机/距离,或调大 timeout |
| CONNECT_FAILED | 连接失败 | 尝试 secure:false、重新配对 |
| NOT_CONNECTED | 没有可用连接 | 先调用 connect() |
| WRITE_TIMEOUT | 写入超时(连接已断开) | 重新连接后重试 |
| WRITE_FAILED | 写入失败(连接已断开) | 重新连接后重试 |
| TASK_CANCELLED | 任务执行前被取消 | - |
JSON 标签模板规范
模板即数据,业务系统可以下发任意符合规范的模板 JSON。
{
"id": "asset",
"name": "固定资产标签",
"width": 60, "height": 40, "gap": 2, "dpi": 203,
"density": 8, "speed": 3, "direction": 1, "encoding": "gbk",
"vars": [ { "key": "assetCode", "label": "资产编号", "sample": "ZC-2026-0001" } ],
"elements": [
{ "type": "box", "x": 1, "y": 1, "width": 58, "height": 38, "thickness": 2 },
{ "type": "text", "x": 3, "y": 3, "content": "{{company}}", "font": "TSS24.BF2" },
{ "type": "barcode", "x": 3, "y": 20.6, "barcodeType": "CODE128", "height": 7, "readable": 0, "content": "{{assetCode}}" },
{ "type": "qrcode", "x": 36, "y": 2.2, "content": "{{qrData}}", "ecc": "H", "cellSize": 4 }
]
}
标签级字段
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| width / height | number | 必填 | 标签宽高(毫米),范围 1-300 / 1-600 |
| gap | number | 2 | 标签间隙(毫米) |
| dpi | number | 203 | 打印机分辨率:203 / 300 / 600(换算 8 / 12 / 24 点每毫米) |
| density | number | 8 | 打印浓度 0-15 |
| speed | number | 3 | 打印速度 1-5(英寸/秒;部分入门机型仅支持 1-4) |
| copies | number | 1 | 打印张数 1-999 |
| direction | number | 1 | 打印方向 0 / 1 |
| encoding | string | gbk | 指令文本编码:gbk / utf8 / ascii |
| vars | array | - | 变量元信息(供业务系统渲染表单),打印逻辑只认 {{key}} 占位符 |
| elements | array | 必填 | 标签元素,至少 1 个 |
元素字段
单位约定:坐标与几何尺寸用毫米(按 dpi 换算为打印点);字高、条码宽窄、二维码单元、方框线宽用打印点。
| type | 字段 |
|---|---|
| text | x, y(毫米);content(必填,支持 {{var}});font(默认 "TSS24.BF2",可缩放字体用 "0");fontHeight(font 为 "0" 时的字高,打印点,默认 24);rotation(0/90/180/270);xmul, ymul(放大倍数 1-8) |
| barcode | x, y;content(必填);barcodeType(CODE128/CODE39/EAN13/EAN8/UPCA/UPCE,默认 CODE128);height(毫米,默认 10);readable(0/1 或 true/false,人眼可读);rotation;narrow, wide(打印点,CODE39 默认 2/5,其余 2/2) |
| qrcode | x, y;content(必填);ecc(L/M/Q/H,默认 H);cellSize(1-10,默认 4);rotation;model(M1/M2,默认 M2);mask(S0-S8,默认 S7) |
| line | x, y, width(毫米);height(毫米,即线宽,最小 1 个打印点) |
| box | x, y, width, height(毫米);thickness(打印点,默认 2,范围 1-20) |
校验行为
- 报错(
INVALID_TEMPLATE):必填字段缺失、数值越界超限、条码字符集/长度/校验位不符、dpi/编码非法等,错误信息会指明elements[i].字段位置; - 警告(
warnings,不阻断):可选字段越界自动收敛(如 density 超出 0-15)、变量缺失替换为空串、坐标超出标签范围等; - 内容中的双引号、回车、换行、制表符会被替换为空格,防止破坏 TSPL 指令结构;变量值中的
{{ }}不会二次展开(单趟替换,防注入)。
printTemplate 的 overrides
density / speed / copies / gap / direction / encoding / timeout 可在调用时覆盖模板定义;width / height / dpi 属于版式定义不允许覆盖(会得到警告并被忽略),避免坐标体系与标签尺寸不匹配的错版输出。
打印任务队列
- 所有连接与写入操作在单一后台线程串行执行,多个打印请求并发提交时按 FIFO 顺序写同一条连接,不会出现交叉写坏的指令流;
- 每个任务有写入超时保护(默认 10000ms),超时后强制关闭 socket,任务以
WRITE_TIMEOUT失败返回,不会卡死队列; - 已入队未执行的任务可通过
cancelPendingTasks()取消;正在执行中的任务不可中断; - 写入失败(超时或异常)会立即释放连接资源,后续任务返回
NOT_CONNECTED,避免在半开连接上无效重试。
重要:结果语义(请务必阅读)
TSPL 协议在 SPP 蓝牙通道上是单向指令流:打印机收到指令后开始打印,但不会回传“物理打印完成”状态(这也是市面同类插件的通行情况)。
因此本插件的打印结果做了严格区分:
ok = true的含义是指令字节流已完整写入蓝牙连接(含 flush);physicalPrintConfirmed恒为false——本插件不会虚报物理打印成功;- 缺纸、打印头开盖、碳带耗尽等发生在“写入成功之后”的异常无法通过本协议感知,需要业务方通过实物核对或后续校验流程兜底。
如果你的业务必须确认物理打印结果,建议的落地做法:打印后人工/扫码核对标签,或在流程上采用「打印 → 贴标 → 扫码确认」闭环。
指令预览与调试
renderTemplateCommand / buildLabelCommand 返回完整 TSPL 指令文本(不发送),可用于:
- 业务系统在界面上展示指令(Demo 的「预览 TSPL 指令」弹层即此用法);
- 离线排查模板问题(配合
warnings逐条修正); - 把指令交由其他通道发送(如串口、网络打印机网关),
printCommand(command)支持直发原始指令。
常见问题
Q:连接报 CONNECT_FAILED / read failed, socket might closed?
先确认打印机已开机、已与手机在系统蓝牙设置中完成配对;再尝试 secure: false(部分入门机型蓝牙模块协商不稳定);仍失败则删除配对后重新配对。
Q:中文打印乱码或空白?
打印机缺少中文字库(TSS24.BF2 等)或编码不匹配。中国市场主流 TSPL 桌面机一般内置简体中文字库并按 GBK 解码(插件默认 encoding: gbk);若你的机型字库为 UTF-8 解码,将模板 encoding 设为 utf8。无中文字库的机型请把中文内容改为 ASCII(如拼音/编号),或反馈作者评估位图方案。
Q:条码打印出来了但扫不出来?
检查内容是否符合编码规则(EAN13 需 12/13 位且校验位正确,CODE39 仅支持大写字母数字与 -. $/+%,CODE128 仅支持 ASCII 32-126);条码高度建议不低于 7mm;CODE39 保持默认宽窄比 2:5。
Q:打印速度设置 4/5 没生效? 部分入门机型 SPEED 仅支持 1-4,超出范围会被打印机按自身上限处理,请按机型说明书设置。
Q:Android 12 以下还需要申请权限吗?
不需要。Android 11 及以下蓝牙为安装即授予的普通权限;Android 12+ 才需要运行时申请 BLUETOOTH_CONNECT,插件已内置检测与申请。
Q:支持 uni-app x 吗?
插件 API 统一以 UTSJSONObject 交互,代码按 uni-app 与 uni-app x 的兼容模式编写;但当前仅在传统 uni-app(Vue3)上完成设计与指令级验证,uni-app x 端未实测(市场平台声明中标注为不确定)。在 x 项目中使用请先自行评估,其他平台端请用条件编译包裹导入。
技术支持
- 使用问题与机型适配反馈请通过插件市场页面联系作者;
- 反馈时请提供:机型与打印机型号、HBuilderX 版本、调用代码片段、
code/message与完整日志。
更新记录
见 changelog.md。设备兼容范围见《设备兼容说明.md》,授权条款见 license.md。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 13
赞赏 0
下载 12715951
赞赏 1958
赞赏
京公网安备:11010802035340号