来自 Web前端 2020-05-07 05:42 的文章
当前位置: 网上澳门金莎娱乐 > Web前端 > 正文

微信小程序连接蓝牙打印机采坑之旅网上澳门金莎娱乐

时间: 2019-09-01阅读: 1115标签: 蓝牙

在iOS app中连接蓝牙打印机打印商品小票,在没有电脑只有手机的情况下,感觉非常实用,而且最近经常最近公司正好也在做这个功能,所以就研究了下。这一篇主要讲一下打印机的一些命令,以便下一篇文章中使用。

目前小程序生态越来越丰富,微信给予了小程序一定的硬件通信能力这是之前 Web 很少尝试的事情。关于蓝牙,常见的就下面几个 API:

在蓝牙打印中,比较麻烦的不是搜索,连接蓝牙设备,而是小票的排版。而要弄出好看的小票排版,就得先熟知蓝牙打印机的各种命令。我是在demo基本完成之后,才找到了详细的命令表,如果我先搜索到这份较详细的命令的话,肯定会节省不少时间。现在写出来,希望能帮助其他在做这个功能的人。其实每个品牌的打印机,在官网的下载里都有完整的打印机指令文档,记得去下载哦。

startBluetoothDevicesDiscovery 开始搜寻附近的蓝牙外围设备openBluetoothAdapter 初始化蓝牙模块wx.onBluetoothDeviceFound 监听寻找到新设备的事件wx.writeBLECharacteristicValue 向低功耗蓝牙设备特征值中写入二进制数据wx.onBLEConnectionStateChange 监听低功耗蓝牙连接状态的改变事件wx.createBLEConnection 连接低功耗蓝牙设备

打印机分了很多型号,不同的打印机所使用的指令集可能不同,比如Star打印机和Epson打印机,他们的所使用的指令集就不太一样。这里有篇文章,有几个常用的指令对比: 这是地址

不过实际我们在实现过程中,我们可能还会遇到一些本身 API 在不同平台上 BUG。

我就只记录一种命令集:ESC/POS打印命令集。而一般的打印机支持三种格式:ASCII、十进制、十六进制。

中文乱码

这里有一份PDF文件说明了各个命令的作用和对应的三种格式:地址

打印的时候,第一个发现的问题便是打印机无法正常打印中文字符串。在向蓝牙写数据的时候,我们实际上市向蓝牙发送的 buffer ,因此我们需要将对应的字符串转换成设备可支持的中文转码,比如 GBK GB2312,网上有一些现成的库,安利一个简单的 github:-encoding

表中都是用ASCII码格式,不要急,下面会介绍每一个命令的十进制和十六进制格式和说明。

这样的话,我们只需要进行引用,然后

网上澳门金莎娱乐 1一览表.png

// text-encoding 为引用的代码目录import { TextEncoder } from '../text-encoding'; this._encoder = new TextEncoder("gb2312", {NONSTANDARD_allowLegacyEncoding: true});// content 需要打印的字符串const uint8Array = this._encoder.encode(content);

等会每个命令会按照如下格式贴出:

由于小程序包大小的限制,可以手动将encoding-indexs.js转换成 JSON 放到远程,然后动态 request 下来。

网上澳门金莎娱乐 2说明.png网上澳门金莎娱乐 3初始化命令.png

设置格式

打印命令有两种:

我们在打印的时候,往往不是简单的一串串字符串,而是需要进行大小,对齐方式的跳转。打印机是能够接受ESC/POS

网上澳门金莎娱乐 4打印命令.png网上澳门金莎娱乐 5行间距设置命令.png网上澳门金莎娱乐 6对齐方式设置.png

其中有一些我么需要用到的指令。

说明:对齐方式有两种,对应的十六进制 {0x1B,0x61,0x00}、{0x1B,0x61,0x01}、{0x1B,0x61,0x02}或者 {0x1B,0x61,0x30}、{0x1B,0x61,0x31}、{0x1B,0x61,0x32}。

ASCII码 ESC a n 十进制码 27 97 n

网上澳门金莎娱乐 7字符设置命令1.png网上澳门金莎娱乐 8字符设置命令2.png网上澳门金莎娱乐 9字符设置命令3.png网上澳门金莎娱乐 10字符设置命令4.png网上澳门金莎娱乐 11钱箱控制命令.png网上澳门金莎娱乐 12按键控制命令.png网上澳门金莎娱乐 13设定点图命令.png网上澳门金莎娱乐 14打印下装点图.png网上澳门金莎娱乐 15向主机传送打印机状态.png网上澳门金莎娱乐 16状态传输命令.png网上澳门金莎娱乐 17条码命令网上澳门金莎娱乐 18条码打印网上澳门金莎娱乐 19位置和页模式命令1网上澳门金莎娱乐 20位置和页模式命令2网上澳门金莎娱乐 21位置和页模式命令3网上澳门金莎娱乐 22切纸模式命令

其中 n 的值表示不同的对齐方式:

以上是我找到的比较完整的命令集合说明,希望能帮到他人。

0 左对齐

这里有其他简友伊布林提供的另一份打印机指令集的文档地址:打印机指令集文档

1 中间对齐

这里有我最初用最原始的指令集拼接出来的NSData代码片段,供大家参考:

2 由对齐

// 打印机支持的文字编码 NSLog(@"goodsArray:%@",goodsArray);// 用到的goodsArray跟github中的商品数组是一样的。 NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString *title = @"测试电商"; NSString *str1 = @"测试电商服务中心"; NSString *line = @"- - - - - - - - - - - - - - - -"; NSString *time = @"时间:2016-04-27 10:01:50"; NSString *orderNum = @"订单编号:4000020160427100150"; NSString *address = @"地址:深圳市南山区学府路东科技园店"; //初始化打印机 Byte initBytes[] = {0x1B,0x40}; NSData *initData = [NSData dataWithBytes:initBytes length:sizeof(initBytes)]; //换行 Byte nextRowBytes[] = {0x0A}; NSData *nextRowData = [NSData dataWithBytes:nextRowBytes length:sizeof(nextRowBytes)]; //居中 Byte centerBytes[] = {0x1B,0x61,1}; NSData *centerData= [NSData dataWithBytes:centerBytes length:sizeof(centerBytes)]; //居左 Byte leftBytes[] = {0x1B,0x61,0}; NSData *leftdata= [NSData dataWithBytes:leftBytes length:sizeof(leftBytes)]; NSMutableData *mainData = [[NSMutableData alloc]init]; //初始化打印机 [mainData appendData:initData]; //设置文字居中/居左 [mainData appendData:centerData]; [mainData appendData:[title dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[str1 dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; // UIImage *qrImage =[MMQRCode createBarImageWithOrderStr:@"RN3456789012"];// UIImage *qrImage =[MMQRCode qrCodeWithString:@"http://www.sina.com" logoName:nil size:400];// qrImage = [self scaleCurrentImage:qrImage];// // NSData *data = [IGThermalSupport imageToThermalData:qrImage];// [mainData appendData:centerData];// [mainData appendData:data];// [mainData appendData:nextRowData]; [mainData appendData:leftdata]; [mainData appendData:[line dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[time dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[orderNum dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[address dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[line dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; NSString *name = @"商品"; NSString *number = @"数量"; NSString *price = @"单价"; [mainData appendData:leftdata]; [mainData appendData:[name dataUsingEncoding:enc]]; Byte spaceBytes1[] = {0x1B, 0x24, 150 % 256, 0}; NSData *spaceData1 = [NSData dataWithBytes:spaceBytes1 length:sizeof(spaceBytes1)]; [mainData appendData:spaceData1]; [mainData appendData:[number dataUsingEncoding:enc]]; Byte spaceBytes2[] = {0x1B, 0x24, 300 % 256, 1}; NSData *spaceData2 = [NSData dataWithBytes:spaceBytes2 length:sizeof(spaceBytes2)]; [mainData appendData:spaceData2]; [mainData appendData:[price dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; CGFloat total = 0.0; for (NSDictionary *dict in goodsArray) { [mainData appendData:[dict[@"name"] dataUsingEncoding:enc]]; Byte spaceBytes1[] = {0x1B, 0x24, 150 % 256, 0}; NSData *spaceData1 = [NSData dataWithBytes:spaceBytes1 length:sizeof(spaceBytes1)]; [mainData appendData:spaceData1]; [mainData appendData:[dict[@"amount"] dataUsingEncoding:enc]]; Byte spaceBytes2[] = {0x1B, 0x24, 300 % 256, 1}; NSData *spaceData2 = [NSData dataWithBytes:spaceBytes2 length:sizeof(spaceBytes2)]; [mainData appendData:spaceData2]; [mainData appendData:[dict[@"price"] dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; total += [dict[@"price"] floatValue] * [dict[@"amount"] intValue]; } [mainData appendData:[line dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[@"总计:" dataUsingEncoding:enc]]; Byte spaceBytes[] = {0x1B, 0x24, 300 % 256, 1}; NSData *spaceData = [NSData dataWithBytes:spaceBytes length:sizeof(spaceBytes)]; [mainData appendData:spaceData]; NSString *totalStr = [NSString stringWithFormat:@"%.2f",total]; [mainData appendData:[totalStr dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:[line dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [mainData appendData:centerData]; [mainData appendData:[@"谢谢惠顾,欢迎下次光临!" dataUsingEncoding:enc]]; [mainData appendData:nextRowData]; [self.peripheral writeValue:mainData forCharacteristic:self.chatacter type:CBCharacteristicWriteWithoutResponse];

我们则在发给打印机的 buffer 数据里需要包含对应的命令

如果你连接成功,但是发出打印指令后,打印机没反应,很有可能是因为你的打印机一次发送的数据长度小于146,你把146改的更小一点试试看。我测试的两台佳博打印机,一台没有长度限制,一台最多每次只能发送146个字节,否则会出现打印没反应的情况,需要重启打印机。不同的打印机,可能对长度的限制不太一样,据群友反应有的打印机只能支持一次发送20个字节,所以你需要将宏里面的146改的更小一点。

[[27, 97,1], [....]]

Have Fun!

打印接下来按照中间对齐进行打印。

当然除了对齐,我们还能对字体大小和粗细进行调整。

字体加粗ASCII码 ESC ! n 十进制码 27 33 n

0 取消加粗

8 加粗

字体大小ASCII码 ESC ! n 十进制码 27 33 n

0 正常

16 倍高

32 倍宽

当然,我们其实不用太详细的去了解这些指令,推荐一个打印库,它类似翻译了这些指令,可以按照前端的方式进行打印。-bluetoothprinter/tree/master/printer

本文由网上澳门金莎娱乐发布于Web前端,转载请注明出处:微信小程序连接蓝牙打印机采坑之旅网上澳门金莎娱乐

关键词: