微信小程序实现蓝牙打印(图片、二维码、文字)

小程序连接蓝牙打印机实现打印功能

  • 这真是一块超级难啃的骨头,我也是参考了很多文章才勉强理解,但是如果你啃动了,那你以后也有了拿得出手的资本了
    完整DEMO地址esc打印模式可直接下载下来使用
  • uniApp的cpcl打印模式DEMD地址 兼容性更好速度打印速度更快支持的文本模式更好,微信小程序与uniapp通用,可直接使用
  1. 搜索与连接蓝牙,这个我就不过多讲解了
 btn(){
    this.setData({
      list:[]
    })
    var that=this
    wx.startBluetoothDevicesDiscovery({
      success(res){
        //监听新设备
        wx.onBluetoothDeviceFound(function(res) {
          var devices = res.devices;
          if(devices[0].name!=''){
            // this.list.push(devices[0])
            var list=that.data.list
            list.push(devices[0])
            that.setData({
              list,
            })
          }
          // console.log('new device list has founded')
          // console.log(ab2hex(devices[0].advertisData))
        })
      },
      fail(res){
        console.log('搜索蓝牙失败',res)
      }
    })
  },
  //连接蓝牙
  connect(v){
    wx.showLoading({
        mask:true,
        title:'连接蓝牙中'
    })
    var that=this
    let {text} = v.currentTarget.dataset
    this.setData({
      id:text.deviceId
    })
    wx.createBLEConnection({
      deviceId:text.deviceId,
      timeout:9000,
      success(rse){
        console.log('连接蓝牙情况',rse)
        wx.getBLEDeviceServices({
          deviceId:text.deviceId,
          complete(rse){
            if(rse.errCode!=0){
              if(rse.errCode==10012){
                wx.showToast({
                  title: '连接蓝牙超时请重试',
                  icon: 'error',
                  duration: 1000
                })
              }else{
                wx.showToast({
                  title: '连接蓝牙异常',
                  icon: 'error',
                  duration: 1000
                })
              }
              return
            }
            //查询特征值
            that.setData({
              inactive:[]
            })
            for(var i in rse.services){
              wx.getBLEDeviceCharacteristics({
                deviceId:text.deviceId,
                serviceId:rse.services[i].uuid,
                complete(rse){
                  if(that.data.inactive[0]){
                    return
                  }
                  for(var j in rse.characteristics){
                    if(rse.characteristics[j].properties.write){
                          var arr=that.data.inactive
                          console.log(that.data.inactive,'查询值')
                          arr.push({
                            deviceId:rse.deviceId,
                            serviceId:rse.serviceId,
                            characteristicId:rse.characteristics[j].uuid,
                            name:text.name
                          })
                          wx.setStorageSync('bluetooth', v)
                          that.setData({
                            inactive:arr
                          })
                          wx.showToast({
                            title: '连接成功',
                            duration: 1000
                          })
                            that.data.status==1?that.print():that.data.status==2?that.receipt():''
                        //  that.speedUp(rse.deviceId)
                         break
                    }
                  }
                  if(!that.data.inactive[0]){
                    wx.showToast({
                      title: '获取蓝牙服务失败',
                      icon: 'error',
                      duration: 1000
                    })
                  }
                }
              })
            }
          }
        })
      },
      fail(rse){
        console.log('链接失败')
      },
      complete(){
        wx.stopBluetoothDevicesDiscovery({
          success(){
            console.log('停止搜索蓝牙')
          }
        })
      }
    })
    
  },

2.打印文字Github实例

 writeBLECharacteristicValue(n) {
    let printerJobs = new PrinterJobs();
        printerJobs
        .print()
        .setAlign('LT')
        .print(printerUtil.fillLine())
        .setAlign('ct')
        .print('回单联')
        .setAlign('LT')
        .setLineSpacing(40)
        .print(data.storename?printerUtil.inline(`门店:${data.storename}`, `${this.time()}`):printerUtil.inline(`车牌号:xxxx`, `区域:xxxx`))
        .print(printerUtil.inline(`快递线路:${data.shipping_name}`,`会员ID:${data.uid}`))
        .print(printerUtil.inline(`寄件人:${data.jijianren}`, `电话:${data.jijianmobile}`))
        // .print(printerUtil.fillAround(`时间: ${this.time()}`))
    let buffer = printerJobs.buffer();
    console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + ab2hex(buffer),buffer,'查看');
    // 1.并行调用多次会存在写失败的可能性
    // 2.建议每次写入不超过20字节
    // 分包处理,延时调用
    const maxChunk = 20;
    const delay = 20;
    for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
      let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
      setTimeout(this._writeBLECharacteristicValue, j * delay, subPackage);
    }
  },
  _writeBLECharacteristicValue(buffer) {
    let {deviceId,serviceId,characteristicId}=this.data.inactive[0]
    wx.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      value: buffer,
      success(res) {
        console.log('writeBLECharacteristicValue success', res)
      },
      fail(res) {
        console.log('writeBLECharacteristicValue fail', res)
      }
    })
  },

3.打印二维码

  • 二维码原理讲解(4和1、8和1 的由来)
  • 打印机指令讲解

根据订单号生成二维码,然后二维码可以打印出来,生成二维码的话,建议使用weapp.qrcode.js

printImgT(device, text,n) {//二维码
    let tthis = this;
		const ctx = wx.createCanvasContext('canvas');
		ctx.clearRect(0, 0, 200, 200);
		drawQrcode({
			canvasId: 'canvas',
			text: String(text),
			width: 200,
			height: 200,
			callback(e) {
      // wxbarcode.barcode('barcode', tthis.data.code, 680, 160,function(){
				setTimeout(() => {
					// 获取图片数据
					wx.canvasGetImageData({
						canvasId: 'canvas',
						x: 0,
						y: 0,
						width: 200,
						height: 200,
						success(res) {
							let arr = tthis.convert4to2(res.data);
              let data = tthis.convert8to1(arr);                  //宽除8 //高本值
              const cmds = [].concat([27, 97,1], [29, 118, 48, 0, 25, 0, 200, 0], data, [27, 74, 3], [27, 64]);
							const buffer = toArrayBuffer(Buffer.from(cmds, 'gb2312'));
							let arrPrint = [];
							arrPrint.push(util.sendDirective([0x1B, 0x40]));
							arrPrint.push(util.sendDirective([0x1B, 0x61, 0x01])); //居中
							for (let i = 0; i < buffer.byteLength; i = i + 20) {   //限制输入数据
								arrPrint.push(buffer.slice(i, i + 20));
							}
              // arrPrint.push(util.sendDirective([0x1B, 0x61, 0x01])); //居中
                arrPrint.push(util.hexStringToBuff(`扫码识别单号\n`));
							// arrPrint.push(util.hexStringToBuff("\n"));
              tthis.printInfo(device, arrPrint);
              
						}
					})
        }, 1000);
      // }());
			}
		});
  },
  
  • 在将值传输时因为每次只能传输20字节的数据,二维码打印会很慢,于是我想法将每次输入更改为异步操作提高了一些打印速度
printInfo: function(device, arr, callback) {
    let tthis = this;
    if (arr.length > 0) {
      arr.shift();
      setTimeout(tthis.sendStr, 10,  arr[0]);		//将同步更改为异步
      tthis.printInfo(device, arr, callback);
    } else {
      // callback ? callback() : '';
    }
  },

  sendStr: function(bufferstr) {
    let {deviceId,serviceId,characteristicId}=this.data.inactive[0]
    let tthis = this;
		wx.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: serviceId,
			characteristicId: characteristicId,
			value: bufferstr,
			success: function(res) {
				console.log('发送成功', res)
			},
			failed: function(res) {
				console.log("数据发送失败:" + JSON.stringify(res))
			},
			// complete: function(res) {
			// 	console.log("发送完成:" + JSON.stringify(res))
			// }
		})
	},
  • 4合1,8合1
//4合1
    convert4to2(res) {
      let arr=[]
      for (let i = 0; i < res.length; i++) {
        if (i % 4 == 0) {
          let rule = 0.29900 * res[i] + 0.58700 * res[i + 1] + 0.11400 * res[i + 2];
            if (rule > 200) {
              res[i] = 0;
            } else {
              res[i] = 1;
            }
            arr.push(res[i]);
        }
      }
      return arr;
    },
    //8合1
    convert8to1(arr) {
      let data = [];
      for (let k = 0; k < arr.length; k += 8) {
        let temp = arr[k] * 128 + arr[k + 1] * 64 + arr[k + 2] * 32 + arr[k + 3] * 16 + arr[k + 4] * 8 + arr[k + 5] * 4 + arr[k + 6] * 2 + arr[k + 7] * 1
        data.push(temp);
      }
      return data;
    }

4.图片的打印

  • 与二维码打印相似将网络图片通过wx.getImageInfo转换为能识别的进制
printImg() {
    let tthis = this;
    wx.getImageInfo({
      src: 'http://zdht-it618jifen.oss-cn-beijing.aliyuncs.com/images/161932136004239.png',
      success: function (ret) {
        setTimeout(() => {
          var path = ret.path;
          var canvas = wx.createCanvasContext('shareCanvas')
          canvas.drawImage(path, 0, 0, 280, 100);
          canvas.draw()
          wx.canvasGetImageData({
            canvasId: 'shareCanvas',
            x: 0,
            y: 0,
            width: 280,
            height: 100,
            success(res) {
              let arr = tthis.convert4to1(res.data);
              let data = tthis.convert8to1(arr);
              const cmds = [].concat([27, 97, 1], [29, 118, 48, 0, 35, 0, 100, 0], data, [27, 74, 3], [27, 64]);
              const buffer = toArrayBuffer(Buffer.from(cmds, 'gb2312'));
              let arrPrint = [];
              arrPrint.push(util.sendDirective([0x1B, 0x40]));
              for (let i = 0; i < buffer.byteLength; i = i + 20) {
                arrPrint.push(buffer.slice(i, i + 20));
              }
              tthis.printInfo('xfz',arrPrint,stat,'3');
            },
            fail: function (error) {
              console.log("error:" + error);
            }
          })
        }, 200);
      },
    })
  },
  • 打印出来效果图微信小程序实现蓝牙打印(图片、二维码、文字)_第1张图片
  • 如果不喜欢黑色背景,可将4和1 的 0 1 打印参的条件进行反转
convert4to1(res) {
		let arr = [];
		for (let i = 0; i < res.length; i++) {
			if (i % 4 == 0) {
				let rule = 0.29900 * res[i] + 0.58700 * res[i + 1] + 0.11400 * res[i + 2];
				if (rule > 200) {
					res[i] = 0;
				} else {
					res[i] = 1;
				}
				arr.push(res[i]);
			}
		}
		return arr;
	},

微信小程序实现蓝牙打印(图片、二维码、文字)_第2张图片

5.整体打印效果如图
微信小程序实现蓝牙打印(图片、二维码、文字)_第3张图片

微信小程序实现蓝牙打印(图片、二维码、文字)_第4张图片

你可能感兴趣的:(小程序,蓝牙,uni-app,微信小程序)