JavaScript SDK
JavaScript SDK 适用于微信小程序、UniApp、Taro 等前端框架开发,通过 BLE(低功耗蓝牙)连接打印机设备。
所有包均发布至 npm,以 @psdk/ 为前缀。
npm install @psdk/frame-father @psdk/cpcl @psdk/device-ble-uniapp| 包名 | 说明 |
|---|---|
@psdk/frame-father | 核心框架 |
| 包名 | 说明 |
|---|---|
@psdk/cpcl | CPCL 指令 |
@psdk/esc | ESC 指令 |
@psdk/tspl | TSPL 指令 |
| 包名 | 说明 |
|---|---|
@psdk/device-ble-uniapp | UniApp BLE |
@psdk/device-ble-wechat | 微信小程序 BLE |
@psdk/device-ble-taro | Taro BLE |
1. 引入依赖
Section titled “1. 引入依赖”import { UniappBleBluetooth } from "@psdk/device-ble-uniapp";import { ConnectedDevice, Lifecycle, Raw } from '@psdk/frame-father';2. 初始化蓝牙
Section titled “2. 初始化蓝牙”const bluetooth = new UniappBleBluetooth({ allowNoName: false, // 是否允许无名称设备});3. 搜索设备
Section titled “3. 搜索设备”// 监听发现的设备bluetooth.discovered(async (devices) => { if (!devices.length) return;
console.log('发现设备:', devices);
// 找到目标设备后连接 const targetDevice = devices.find(d => d.name.includes('Printer')); if (targetDevice) { await connectDevice(targetDevice); }});
// 开始搜索await bluetooth.startDiscovery();4. 连接设备
Section titled “4. 连接设备”let connectedDevice;
async function connectDevice(device) { try { connectedDevice = await bluetooth.connect(device); console.log('连接成功:', connectedDevice.name); } catch (error) { console.error('连接失败:', error); }}5. 断开连接
Section titled “5. 断开连接”await bluetooth.disconnect();CPCL 指令使用
Section titled “CPCL 指令使用”CPCL 指令用于便携式标签打印机。详细指令说明请参考 CPCL 指令文档。
import { CPCL } from '@psdk/cpcl';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const cpcl = CPCL.generic(lifecycle);
const reporter = await cpcl .page({ width: 576, height: 400 }) .text({ x: 50, y: 50, content: '商品标签' }) .barcode({ x: 50, y: 150, content: '1234567890' }) .print() .write({ chunkSize: 512 });
console.log('打印结果:', reporter);完整标签示例
Section titled “完整标签示例”import { CPCL } from '@psdk/cpcl';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const cpcl = CPCL.generic(lifecycle);
await cpcl .page({ width: 576, height: 400 }) // 标题 .center() .text({ x: 0, y: 30, font: 4, size: 2, content: '商品标签', }) // 商品信息 .left() .text({ x: 30, y: 100, content: '名称: 有机苹果' }) .text({ x: 30, y: 140, content: '规格: 500g/袋' }) .text({ x: 30, y: 180, content: '价格: ¥25.90' }) // 条码 .barcode({ x: 100, y: 230, type: '128', height: 60, content: '6901234567890', }) // 二维码 .qrcode({ x: 400, y: 100, content: 'https://example.com', }) .print() .write({ chunkSize: 512 });ESC 指令使用
Section titled “ESC 指令使用”ESC 指令广泛用于热敏小票打印机。详细指令说明请参考 ESC 指令文档。
import { ESC } from '@psdk/esc';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const esc = ESC.generic(lifecycle);
await esc .initialize() .align('center') .text('收银小票') .align('left') .text('商品A x1 ¥29.90') .cut() .write({ chunkSize: 512 });打印小票示例
Section titled “打印小票示例”import { ESC } from '@psdk/esc';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const esc = ESC.generic(lifecycle);
await esc .initialize() // 标题 .align('center') .textSize({ width: 2, height: 2 }) .bold(true) .text('XX 便利店') .bold(false) .textSize({ width: 1, height: 1 }) .text('订单号: 20240115001') .text('================================') // 商品列表 .align('left') .text('可乐 500ml x2 ¥6.00') .text('薯片 大包 x1 ¥8.50') .text('--------------------------------') // 合计 .textSize({ width: 1, height: 2 }) .text('合计: ¥14.50') .textSize({ width: 1, height: 1 }) // 二维码 .align('center') .qrcode({ content: 'https://shop.example.com', size: 5 }) .text('扫码关注店铺') .feed(3) .cut() .write({ chunkSize: 512 });TSPL 指令使用
Section titled “TSPL 指令使用”TSPL 指令用于标签条码打印机。详细指令说明请参考 TSPL 指令文档。
import { TSPL } from '@psdk/tspl';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const tspl = TSPL.generic(lifecycle);
await tspl .page({ width: 60, height: 40 }) .cls() .text({ x: 50, y: 50, content: '标签内容' }) .print(1) .write({ chunkSize: 512 });完整标签示例
Section titled “完整标签示例”import { TSPL } from '@psdk/tspl';import { Lifecycle } from '@psdk/frame-father';
const lifecycle = new Lifecycle(connectedDevice);const tspl = TSPL.generic(lifecycle);
await tspl .page({ width: 60, height: 40 }) .gap(3) .direction('up') .cls() // 标题 .text({ x: 180, y: 30, font: 'TSS24.BF2', xMulti: 2, yMulti: 2, content: '商品标签', }) // 分隔线 .bar({ x: 30, y: 80, width: 420, height: 2 }) // 商品信息 .text({ x: 30, y: 100, content: '品名: 有机苹果' }) .text({ x: 30, y: 140, content: '规格: 500g/袋' }) .text({ x: 30, y: 180, content: '价格: ¥25.90' }) // 条码 .barcode({ x: 100, y: 220, type: '128', height: 60, content: '6901234567890', }) // 二维码 .qrcode({ x: 350, y: 100, cellWidth: 4, content: 'https://example.com', }) .print(1) .write({ chunkSize: 512 });发送原始指令
Section titled “发送原始指令”import { Raw } from '@psdk/frame-father';
// 发送原始二进制指令const reporter = await cpcl .raw(Raw.binary(new Uint8Array([0x10, 0xff, 0xbf]))) .write({ chunkSize: 512 });微信小程序示例
Section titled “微信小程序示例”import { WechatBleBluetooth } from "@psdk/device-ble-wechat";import { CPCL } from '@psdk/cpcl';import { Lifecycle } from '@psdk/frame-father';
Page({ data: { deviceList: [], connectedDevice: null, },
onLoad() { this.bluetooth = new WechatBleBluetooth();
// 监听设备 this.bluetooth.discovered((devices) => { this.setData({ deviceList: devices }); }); },
// 开始搜索 async startScan() { await this.bluetooth.startDiscovery(); },
// 连接设备 async connectDevice(e) { const device = e.currentTarget.dataset.device; try { const connectedDevice = await this.bluetooth.connect(device); this.setData({ connectedDevice }); wx.showToast({ title: '连接成功' }); } catch (error) { wx.showToast({ title: '连接失败', icon: 'error' }); } },
// 打印 async print() { const { connectedDevice } = this.data; if (!connectedDevice) return;
const lifecycle = new Lifecycle(connectedDevice); const cpcl = CPCL.generic(lifecycle);
await cpcl .page({ width: 576, height: 400 }) .text({ x: 50, y: 50, content: '小程序打印测试' }) .print() .write({ chunkSize: 512 });
wx.showToast({ title: '打印完成' }); },});Taro 示例
Section titled “Taro 示例”import { TaroBleBluetooth } from "@psdk/device-ble-taro";import { CPCL } from '@psdk/cpcl';import { Lifecycle } from '@psdk/frame-father';
// 初始化方式与 UniApp 相同const bluetooth = new TaroBleBluetooth();
// 搜索设备bluetooth.discovered((devices) => { console.log('发现设备:', devices);});
await bluetooth.startDiscovery();
// 连接设备const connectedDevice = await bluetooth.connect(device);
// 打印const lifecycle = new Lifecycle(connectedDevice);const cpcl = CPCL.generic(lifecycle);
await cpcl .page({ width: 576, height: 400 }) .text({ x: 50, y: 50, content: 'Taro 打印测试' }) .print() .write({ chunkSize: 512 });try { await cpcl.write({ chunkSize: 512 }); console.log('打印成功');} catch (error) { if (error.code === 'BLE_DISCONNECTED') { console.error('蓝牙断开连接'); } else if (error.code === 'BLE_TIMEOUT') { console.error('蓝牙超时'); } else { console.error('打印失败:', error.message); }}完整示例请参考: