微信蓝牙打印指令+数据
1、说明:微信蓝牙传递的数据格式是GBK编码的二进制格式,下面就说一下在小程序中是如何获取蓝牙打印的数据
2、普通文本的打印:
要转义GBK编码的话要用到GBK.js,库的网址:https://github.com/cnwhy/GBK.js
import GBK from './gbk.min'; GBK.encode('时顺地?abc地') // 解码GBK为一个字节数组 [ 202, 177, 203, 179, 181, 216, 63, 97, 98, 99, 181, 216 ] GBK.decode([ 202, 177, 203, 179, 181, 216, 63, 97, 98, 99, 181, 216 ]) //解码GBK编码的字节数组 返回字符串 时顺地?abc地;
然后是打印机指令
//打印机指令 使用的 ESC/POS指令, 十进制方式 const printCommand = { left: [27, 97, 0], //居左 center: [27, 97, 1], //居中 right: [27, 97, 2], //居右 clear: [27, 64], //初始化 enter: [10], //打印 };
对于那些多个数据一行的可以用一些方法调整打印位置,比如左右两个数据,左中右三个数据的
/*获取字符长度 */ function getBytesLength(val) { let str = new String(val); let bytesCount = 0; for (let i = 0, n = str.length; i < n; i++) { let c = str.charCodeAt(i); if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) { bytesCount += 1; } else { bytesCount += 2; } } return bytesCount; } //计算打印的位置 左右各两边 返回带空格的整行字符串 function printTwoData(leftText, rightText) { let sb = ''; let maxLen = 32; let leftTextLength = getBytesLength(leftText); let rightTextLength = getBytesLength(rightText); let spaceLen = maxLen - leftTextLength - rightTextLength; sb = sb + leftText; for (let i = 0; i < spaceLen; i++) { sb = sb + ' '; } sb = sb + rightText; return sb.toString(); } //计算打印的位置 左 中 右 返回带空格的整行字符串 function printThreeData(leftText, centerText, rightText) { let sb = ''; let maxLen = 32; let leftTextLength = getBytesLength(leftText); let centerTextLength = getBytesLength(centerText); let rightTextLength = getBytesLength(rightText); let spaceLeft = maxLen / 2 - leftTextLength - centerTextLength / 2; let spaceRight = maxLen / 2 - centerTextLength / 2 - rightTextLength; sb = sb + leftText; for (let i = 0; i < spaceLeft; i++) { sb = sb + ' '; } sb = sb + centerText; for (let i = 0; i < spaceRight; i++) { sb = sb + ' '; } sb = sb + rightText; return sb.toString(); } //计算打印的位置 根据数组平均分配 返回带空格的整行字符串 function printMoreData(arr) { let sb = ''; let maxLen = 32; let distance=0 let data=arr.map((e)=>{ let obj={} obj.text=e; obj.len=getBytesLength(e) distance+=obj.len return obj }) let num=arr.length-1 distance=Math.floor((maxLen-distance)/(num)) data.forEach((e,i) => { if(i!==num){ sb=sb+e.text for (let i = 0; i < distance; i++) { sb = sb + ' '; } }else{ sb=sb+e.text } }); return sb.toString(); }
然后还要通过new Uint8Array().buffer的方法转化成二进制的格式ArrayBuffer
let printData = new Uint8Array([...printCommand.clear, ...GBK.encode('我是要打印的字符串'), ...printCommand.enter]).buffer //单行正常的数据 每次打印调用clear清除打印的格式和打印机缓存,从新的一行开始 let printData = new Uint8Array([...printCommand.clear,...printCommand.right, ...GBK.encode('我是要打印的字符串'), ...printCommand.enter]).buffer //单行居右的数据 let printData = new Uint8Array([...printCommand.clear, ...GBK.encode(printTwoData('左边的数据','右边的数据')), ...printCommand.enter]).buffer //单行分左右的数据 let printData = new Uint8Array([...printCommand.clear, ...GBK.encode(printThreeData('左边的数据','中间的数据','右边的数据')), ...printCommand.enter]).buffer //单行分左中右的数据 //调用微信写数据的方法 传的数据大小控制在20 wx.writeBLECharacteristicValue({ deviceId, serviceId, characteristicId, value:printData, })
3、二维码的打印:
二维码的打印和普通文本打印的区别就在于指令的不同,打印指令需要的是二进制数据长度,可以通过new ArrayBuffer().byteLength获取
let instruct = [29, 107, 97, 7, 4, new Uint8Array(GBK.encode('https://www.baidu.com')).buffer.byteLength, 0] //二维码打印指令 需要打印二进制数组长度 let printData = new Uint8Array([...printCommand.clear,...instruct, ...GBK.encode('https://www.baidu.com'), ...printCommand.enter]).buffer //调用微信写数据的方法 传的数据大小控制在20 wx.writeBLECharacteristicValue({ deviceId, serviceId, characteristicId, value:printData, })
4、图片的打印:
5、蓝牙数据写入的递归方法
/*封装的微信的蓝牙api */ function wxAsyncPromise(name, options) { const fnName = wx[name]; return new Promise((resolve, reject) => { fnName({ ...(options ? options : {}), success: function (res) { resolve(res); }, fail: function (res) { reject(res); }, }); }); } /*发送数据 */ function sendData(obj) { //重新获取长度 let byteLength = obj.value.byteLength; //这里默认一次20个字发送 const speed = 20; if (byteLength > 0) { wxAsyncPromise('writeBLECharacteristicValue', { ...obj, value: obj.value.slice(0, byteLength > speed ? speed : byteLength), }) .then((res) => { if (byteLength > speed) { sendData({ ...obj, value: obj.value.slice(speed, byteLength), }); } else { console.log('打印完成') } }) .catch((err) => { console.log('发送失败', err) }); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」