uni-app 中 navigator.print 仅 H5 可用,App 和小程序不支持;需通过截图转 canvas 或 ESC/POS 指令直连蓝牙打印机实现跨端打印,注意平台权限、协议格式及原生插件集成。

uni-app 里调用系统打印 API 失效?别硬试 navigator.print
uni-app 的 navigator.print 在 H5 端可能触发,但 App 和小程序端完全不生效——这不是你配置错,是平台根本不支持。真要局部打印,得绕开浏览器原生打印,走「生成图片 → 调用原生能力」或「拼接指令 → 直连蓝牙打印机」两条路。
常见错误现象:Cannot read property 'print' of undefined(App 端)、点击无反应(小程序)、只打印白屏(H5 局部元素未正确转 canvas)。
- 优先确认目标平台:App(iOS/Android)需原生插件;微信小程序暂不支持蓝牙直连,只能走云打印或服务商中转;H5 只能靠截图 + 浏览器 print,且无法控制页眉页脚
- 局部打印 ≠ 选中某 div 后按 Ctrl+P:必须把目标区域先转成
canvas或base64图片,否则跨端必然失败 - 推荐用
dom-to-image(H5)或uni.canvasToTempFilePath(App)做截图,注意设置宽高比和像素密度,否则模糊
Android/iOS 连蓝牙打印机发指令,为什么连上了却不出纸?
连上设备不等于能通信——蓝牙打印机(如 ZJ-5890、SP-200)普遍要求特定协议(ESC/POS),且必须用原生层发送十六进制指令,JS 层直接写字符串大概率被截断或乱码。
使用场景:小票打印、标签补打、离线场景下绕过系统打印限制。
- uni-app 本身不提供蓝牙指令发送能力,必须通过
uni.requireNativePlugin引入封装好的原生插件(如BluetoothPrinter) - 关键参数不是「设备名」而是「MAC 地址」或「service UUID」,iOS 需提前在
info.plist加NSBluetoothAlwaysUsageDescription - 指令必须以十六进制数组形式传入,例如换行是
[0x0A],不是字符串"\n";中文需先用 GBK 编码再转字节数组 - 部分打印机要求首帧加初始化指令
[0x1B, 0x40],否则静默丢弃后续数据
ESC/POS 指令里字体放大、切纸、对齐怎么写?别查 PDF 手册了
不同品牌打印机对同一指令的支持程度差异极大,Zijiang 和 Star 的「居中」指令都是 [0x1B, 0x61, 0x01],但有些国产模块会吃掉第二个字节。
实操建议:
- 加粗:用
[0x1B, 0x45, 0x01]开启,[0x1B, 0x45, 0x00]关闭;别用 CSSfont-weight,那在指令流里无效 - 居中:确保前面没残留的「左对齐」指令,连续发两次
[0x1B, 0x61, 0x01]更稳妥 - 切纸:热敏打印机常用
[0x1D, 0x56, 0x00](完全切),但某些型号需改成[0x1D, 0x56, 0x01](留半张) - 空行别堆
[0x0A],用[0x1B, 0x33, 0x10](设置行高为 16px)再跟一个[0x0A],更省流量也更准
uni-app 打印插件报 bluetooth is not enabled 却明明开了蓝牙?
这是 Android 12+ 和 iOS 14+ 的权限链问题:光开蓝牙开关不够,APP 还得有位置权限(Android)或精确位置授权(iOS),因为蓝牙扫描被归类为定位行为。
容易踩的坑:
- Android 端未在
AndroidManifest.xml声明android.permission.ACCESS_FINE_LOCATION,或运行时没调用uni.authorize({scope: 'scope.location'}) - iOS 真机调试时 Xcode 里没勾选
Uses Bluetooth LE accessories和Location When In Use - 插件内部用的是
BluetoothAdapter而非BluetoothManager,导致低版本 Android(API - 首次连接后没缓存设备实例,下次调用
connect时传了旧的 deviceID,返回 success 但实际通道已断
复杂点在于:同一套 JS 逻辑,在 H5、微信、App 三个环境里要走三套完全不同的路径,而蓝牙状态监听、重连机制、指令队列这些,都得自己补全——官方 SDK 不管这部分。


















