微信小程序 实现蓝牙打印条形码,文字等

测试设备:得力DL-720W条码标签打印机
效果图:

具体代码如下:

1、搜索连接蓝牙

connect.wxml

<view class="main">
  <van-button block type="info" bindtap="startSearch" loading='{{isScanning}}'>开始搜索</van-button>
  <scroll-view class="device-list" scroll-y scroll-with-animation>
    <view class="connect-name">已发现{{list.length}}个外围设备</view>
    <view
      wx:for="{{list}}" 
      wx:for-item="item" 
      data-title="{{item.deviceId}}" 
      data-name="{{item.name}}" 
      data-advertisData="{{item.advertisServiceUUIDs}}" 
      data-item="{{item}}"
      wx:key="{{item.deviceId}}"
      bindtap="bindViewTap"
    >
        <view  class="device-item">
          <view class="name">{{item.name}}</view>
          <view class="device-id">UUID: {{item.deviceId}}</view>
      </view>    
    </view>
  </scroll-view>
  <view wx:if="{{lastDevice}}">
    <view class="connect-name">最近连接的设备{{lastDevice.name}}</view>
    <view class="btn-area">
      <van-button block type="info" data-deviceId="{{lastDevice.deviceId}}" data-item="{{lastDevice}}" bindtap="createBLEConnectionWithDeviceId">直接连接</van-button>
    </view>
  </view>
</view>
    
 

connect.scss

.main{
  padding: 20rpx;

  .device-list{
    height: 700rpx;
    margin: 10rpx;
    .device-item{
      padding: 20rpx 0;
      border-bottom: 2rpx solid #E6EBF1;
    }
    .name{
      font-size: 32rpx;
    }
    .device-id{
      font-size: 24rpx;
      color: #666;
    }
  }
  .connect-name{
    text-align: center;
    padding: 15rpx 0;
  }
}

connect.js

let app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list: [],
    services: [],
    serviceId: 0,
    writeCharacter: false,
    readCharacter: false,
    notifyCharacter: false,
    isScanning:false
  },
  // 开始搜索
  startSearch: function () {
    let that = this;
    if (!wx.openBluetoothAdapter) {
      wx.showModal({
        title: '提示',
        content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
      })
      return
    }
    // 初始化蓝牙设备
    wx.openBluetoothAdapter({
      success: function (res) {
        console.log('第一步,蓝牙初始化成功', res)
        // 获取本机蓝牙适配器状态
        wx.getBluetoothAdapterState({
          success: function (res) {
            // 蓝牙适配器是否可用
            if (res.available) {
              // 是否正在搜索设备
              if (res.discovering) {
                // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
                wx.stopBluetoothDevicesDiscovery({
                  success: function (res) {
                    console.log(res)
                  }
                })
              }
              that.checkPemission()
            } else {
              wx.showModal({
                title: '提示',
                content: '本机蓝牙不可用',
              })
            }
          },
        })
      }, fail: function () {
        wx.showModal({
          title: '提示',
          content: '蓝牙初始化失败,请打开蓝牙后重试',
        })
      }
    })
  },
  checkPemission: function () {  //android 6.0以上需授权地理位置权限
    let that = this;
    let platform = app.BLEInformation.platform;
    if (platform == 'ios') {
      app.globalData.platform = 'ios';
      that.getBluetoothDevices()
    } else if (platform == 'android') {
      app.globalData.platform = 'android'
      console.log(app.getSystem().substring(app.getSystem().length - (app.getSystem().length - 8), app.getSystem().length - (app.getSystem().length - 8) + 1))
      if (app.getSystem().substring(app.getSystem().length - (app.getSystem().length - 8), app.getSystem().length - (app.getSystem().length - 8) + 1) > 5) {
        wx.getSetting({
          success: function (res) {
            console.log(res)
            if (!res.authSetting['scope.userLocation']) {
              wx.authorize({
                scope: 'scope.userLocation',
                complete: function (res) {
                  that.getBluetoothDevices()
                }
              })
            } else {
              that.getBluetoothDevices()
            }
          }
        })
      }else{
        that.getBluetoothDevices()
      }
    }
  },
  getBluetoothDevices: function () {  //获取蓝牙设备信息
    let that = this;
    wx.showLoading({ title: '正在加载'})
    that.setData({
      isScanning:true
    })
    // 开始搜寻附近的蓝牙外围设备。
    wx.startBluetoothDevicesDiscovery({
      success: function (res) {
        console.log(res)
        setTimeout(function () {
          wx.getBluetoothDevices({
            success: function (res) {
              let devices = []
              let num = 0
              for (let i = 0; i < res.devices.length; ++i) {
                if (res.devices[i].name != '未知设备') {
                  devices[num] = res.devices[i]
                  num++
                }
              }
              that.setData({
                list: devices,
                isScanning:false
              })
              wx.hideLoading()
              wx.stopPullDownRefresh()
            },
          })
        }, 3000)
      },
    })
  },
  // 连接蓝牙设备
  bindViewTap: function (e) {
    // 先清除之前已连接蓝牙设备数据缓存
    wx.removeStorageSync('bleItem');
    wx.removeStorageSync('bleWriteInfo');
    wx.removeStorageSync('bleNotifyInfo');

    let that = this;
    // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索
    wx.stopBluetoothDevicesDiscovery({
      success: function (res) { console.log(res) },
    })

    that.setData({
      serviceId: 0,
      writeCharacter: false,
      readCharacter: false,
      notifyCharacter: false
    })
    
    wx.showLoading({ title: '正在连接' })
    
    
    const { title,item } = e.currentTarget.dataset;
    this._createBLEConnection(title,item)
  },
  // 连接蓝牙低功耗设备。
  // 若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作。
  _createBLEConnection(deviceId,item){
    const that = this;
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        console.log(res)
        app.BLEInformation.deviceId = deviceId;
        // 把已连接的蓝牙设备存入缓存
        wx.setStorageSync('bleItem', item);
        that.getSeviceId()

      }, fail: function (e) {
        console.log(e,'连接失败')
        // wx.showModal({
        //   title: '提示',
        //   content: '连接失败',
        // })
        console.log(e)
      }, complete: function (e) {
        console.log(e)
        wx.hideLoading()
      }
    })
  },
  // 获取蓝牙低功耗设备所有服务 (service)。
  getSeviceId: function () {
    let that = this
    let platform = app.BLEInformation.platform;
    wx.getBLEDeviceServices({
      deviceId: app.BLEInformation.deviceId,
      success: function (res) {
        console.log(res)
        that.setData({ services: res.services })

        that.getCharacteristics()
      }, fail: function (e) {
        console.log(e)
      }, complete: function (e) {
        console.log(e)
      }
    })
  },
  getCharacteristics: function () {
    let that = this;
    let list = that.data.services;
    let num = that.data.serviceId;
    let write = that.data.writeCharacter;
    let read = that.data.readCharacter;
    let notify = that.data.notifyCharacter;
    // 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)。
    wx.getBLEDeviceCharacteristics({
      deviceId: app.BLEInformation.deviceId,
      serviceId: list[num].uuid,
      success: function (res) {
        console.log(res)
        for (let i = 0; i < res.characteristics.length; ++i) {
          let properties = res.characteristics[i].properties;
          let item = res.characteristics[i].uuid;
          if (!notify) {
            if (properties.notify) {
              app.BLEInformation.notifyCharaterId = item
              app.BLEInformation.notifyServiceId = list[num].uuid;
              const bleNotifyInfo = {
                notifyCharaterId: item,
                notifyServiceId: list[num].uuid
              }
              wx.setStorageSync('bleNotifyInfo', bleNotifyInfo);
              notify = true
            }
          }
          if (!write) {
            if (properties.write) {
              app.BLEInformation.writeCharaterId = item;
              app.BLEInformation.writeServiceId = list[num].uuid;
              const bleWriteInfo = {
                writeCharaterId: item,
                writeServiceId: list[num].uuid
              }
              wx.setStorageSync('bleWriteInfo', bleWriteInfo);
              write = true;
            }
          }
          if (!read) {
            if (properties.read) {
              app.BLEInformation.readCharaterId = item;
              app.BLEInformation.readServiceId = list[num].uuid;
              read = true
            }
          }
        }
        if (!write || !notify || !read) {
          num++
          that.setData({
            writeCharacter: write,
            readCharacter: read,
            notifyCharacter: notify,
            serviceId: num
          })
         if(num == list.length){
           wx.showModal({
             title: '提示',
             content: '找不到该读写的特征值',
           })
         }else{
           that.getCharacteristics()
         }
        } else {
          that.openControl()
        }
      }, fail: function (e) {
        console.log(e)
      }, complete: function (e) {
        console.log('write:'+app.BLEInformation.writeCharaterId)
        console.log('read:'+app.BLEInformation.readCharaterId)
        console.log('notify:'+app.BLEInformation.notifyCharaterId)
      }
    })
  },
  openControl: function () {
    wx.showToast({
      title: '连接成功',
      icon: 'success',
      duration: 2000
    })
    wx.navigateBack({
      delta: 1
    })
  },
  createBLEConnectionWithDeviceId(e) {
    // 小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备
    const device = this.data.lastDevice;
    if (!device) { return }
    const deviceId = device.deviceId;
    console.log('createBLEConnectionWithDeviceId', deviceId)
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this._createBLEConnection(deviceId, device)
      },
      fail: (res) => {
        console.log('openBluetoothAdapter fail', res)
        if (res.errCode === 10001) {
          wx.showModal({
            title: '错误',
            content: '未找到蓝牙设备, 请打开蓝牙后重试。',
            showCancel: false
          })
          wx.onBluetoothAdapterStateChange((res) => {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              // 取消监听
              wx.onBluetoothAdapterStateChange(() => {
              });
              this._createBLEConnection(deviceId, device)
            }
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    app.BLEInformation.platform = app.getPlatform();
    wx.setStorageSync('platform', app.getPlatform());

    const lastDevice = wx.getStorageSync('bleItem');
    this.setData({
      lastDevice: lastDevice
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
      let that = this
      wx.startPullDownRefresh({})
      that.startSearch()
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

效果图

2、打印功能(单独写在了mixins里)

send-command.js

/**
 * 此Demo仅供参考,可打印数字,英文,符号,中文,条形码
 * 小程序支持的蓝牙为低功耗蓝牙(BLE),数据量大需分包发送
 */
const app = getApp();

export default {
  data: {
    looptime: 0,
    currentTime: 1,
    lastData: 0,
    buffSize: [],
    buffIndex: 0,
    printNum: [],
    printNumIndex: 0,
    printerNum: 1,
    currentPrint: 1,
    isReceiptSend: false,
    isLabelSend: false,
    canvasWidth: 180,
    canvasHeight: 180,
    imageSrc: '../../../images/mine/user-free.png',
    isBleConnect: false // 是否已连接蓝牙设备
  },
  //准备发送,根据每次发送字节数来处理分包数量
  prepareSend: function(buff) {
    console.log(buff)
    let that = this;
    let time = that.data.oneTimeData;
    let looptime = parseInt(buff.length / time);
    let lastData = parseInt(buff.length % time);
    console.log(looptime + '---' + lastData)
    that.setData({
      looptime: looptime + 1,
      lastData: lastData,
      currentTime: 1,
    })
    that.Send(buff)
  },
  //分包发送
  Send: function(buff) {
    let that = this;
    let currentTime = that.data.currentTime;
    let loopTime = that.data.looptime;
    let lastData = that.data.lastData;
    let onTimeData = that.data.oneTimeData;
    let printNum = that.data.printerNum;
    let currentPrint = that.data.currentPrint;
    let buf;
    let dataView;
    if (currentTime < loopTime) {
      buf = new ArrayBuffer(onTimeData)
      dataView = new DataView(buf)
      for (let i = 0; i < onTimeData; ++i) {
        dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
      }
    } else {
      buf = new ArrayBuffer(lastData)
      dataView = new DataView(buf)
      for (let i = 0; i < lastData; ++i) {
        dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
      }
    }

    const bleWriteInfo = wx.getStorageSync('bleWriteInfo');
    console.log(bleWriteInfo,'bleWriteInfo=====')
    wx.writeBLECharacteristicValue({
      deviceId: this.data.bleInfo.deviceId,
      serviceId: bleWriteInfo.writeServiceId,
      characteristicId: bleWriteInfo.writeCharaterId,
      value: buf,
      success: function(res) {
        console.log(res)
      },
      fail: function(e) {
        console.log(e)
      },
      complete: function() {
        currentTime++
        if (currentTime <= loopTime) {
          that.setData({
            currentTime: currentTime
          })
          that.Send(buff)
        } else {
          wx.showToast({
            title: '已打印第' + currentPrint + '张',
          })
          if (currentPrint == printNum) {
            that.setData({
              looptime: 0,
              lastData: 0,
              currentTime: 1,
              isReceiptSend: false,
              isLabelSend: false,
              currentPrint: 1
            })
          } else {
            currentPrint++
            that.setData({
              currentPrint: currentPrint,
              currentTime: 1,
            })
            that.Send(buff)
          }
        }
      }
    })

  },
  // 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征
  enableBle(deviceId){
    const bleNotifyInfo = wx.getStorageSync('bleNotifyInfo');
    wx.notifyBLECharacteristicValueChange({
      deviceId: deviceId,
      serviceId: bleNotifyInfo.notifyServiceId,
      characteristicId: bleNotifyInfo.notifyCharaterId,
      state: true,
      success: function(res) {
        wx.onBLECharacteristicValueChange(function(r) {
          console.log(`characteristic ${r.characteristicId} has changed, now is ${r}`)
        })
      },
      fail: function(e) {
        console.log(e)
      },
      complete: function(e) {
        console.log(e)
      }
    })
  },
  drawCanvas(){
    let that = this;
    let width;
    let height;
    wx.getImageInfo({
      src: that.data.imageSrc,
      success(res) {
        width = res.width
        height = res.height
        that.setData({
          canvasWidth: res.width,
          canvasHeight: res.height
        })
      }
    })

    const ctx = wx.createCanvasContext('edit_area_canvas', this);
    ctx.drawImage(this.data.imageSrc, 0, 0, width, height);
    ctx.draw();
  },
  // 创建连接
  _createBLEConnection(deviceId,item){
    const that = this;
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        console.log(res)
        wx.setStorageSync('bleItem', item);
        // that.getSeviceId(deviceId)
      }, fail: function (e) {
        console.log('createBLEConnection fail', res)
      }, complete: function (e) {
        wx.hideLoading()
      }
    })
  },
  // 创建蓝牙连接
  // 小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备
  createBLEConnectionWithDeviceId() {
    const device = this.data.bleInfo;
    if (!device) { return; }
    const deviceId = device.deviceId;
    console.log('createBLEConnectionWithDeviceId', deviceId)
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this._createBLEConnection(deviceId, device)
      },
      fail: (res) => {
        console.log('openBluetoothAdapter fail', res)
        if (res.errCode === 10001) {
          wx.showModal({
            title: '错误',
            content: '未找到蓝牙设备, 请打开蓝牙后重试。',
            showCancel: false
          })
          wx.onBluetoothAdapterStateChange((res) => {
            console.log('onBluetoothAdapterStateChange', res)
            // 蓝牙适配器是否可用
            if (res.available) {
              // 取消监听,否则stopBluetoothDevicesDiscovery后仍会继续触发onBluetoothAdapterStateChange,
              // 导致再次调用startBluetoothDevicesDiscovery
              wx.onBluetoothAdapterStateChange(() => {});
              this._createBLEConnection(deviceId, device)
            }
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function () {
    this.enableBle()
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {
    let list = [];
    let numList = [];
    let j = 0;
    for (let i = 20; i < 200; i += 10) {
      list[j] = i;
      j++
    }
    for (let i = 1; i < 10; i++) {
      numList[i - 1] = i
    }
    this.setData({
      buffSize: list,
      oneTimeData: list[0],
      printNum: numList,
      printerNum: numList[0]
    })
  },
  onShow() {
    this.drawCanvas();
    // 获取已经连接过得蓝牙设备
    const bleInfo = wx.getStorageSync('bleItem');
    this.setData({
      bleInfo: bleInfo ? bleInfo : {}
    })
    
    // 如果已经有连接的蓝牙设备,直接连接
    if(Object.keys(this.data.bleInfo).length !== 0){
      this.setData({
        isBleConnect: true
      })
      this.createBLEConnectionWithDeviceId()
      // this.enableBle(this.data.bleInfo.deviceId);
    }
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {
    
    // 断开与蓝牙低功耗设备的连接
    wx.closeBLEConnection({
      deviceId: this.data.bleInfo.deviceId,
      success: function(res) {
        console.log("关闭蓝牙成功")
      },
    })
  }
}

3、业务中打印逻辑

wxml

<van-button wx:if="{{detailBase.state <= 3}}" color="#0A7DFE" loading="{{btnLoading}}" block round bind:tap="labelPrint">打印</van-button>

js

import sendCommand from '@/mixins/modules/send-command.js';

let tsc = require('../../../utils/tsc.js');
Page({

  mixins: [sendCommand],

  // 标签打印
  labelPrint(){
    // 如果未连接打印机,跳转到连接打印机页面
    if(Object.keys(this.data.bleInfo).length === 0){
      wx.navigateTo({
        url: '/pages/tabbar-pages/mine/bleConnect/bleConnect'
      })
      return;
    }
    
    let that = this;
    let canvasWidth = that.data.canvasWidth;
    let canvasHeight = that.data.canvasHeight;
    let command = tsc.jpPrinter.createNew();
    command.setSize(65, 48);
    command.setGap(0);
    command.setCls();
    command.setText(220, 10, 'TSS24.BF2', 1, 1, '暂存单');
    command.setBarCode(95, 50, '128', 65, 1, 2, 2, `${that.data.detailBase.id}`);
    command.setText(190, 120, 'TSS24.BF2', 1, 1, `${that.data.detailBase.id}`);
    command.setText(30, 160, 'TSS24.BF2', 1, 1, `姓名:${that.data.detailBase.name}`);
    command.setText(240, 160, 'TSS24.BF2', 1, 1, `手机号:${that.data.detailBase.mobile}`);
    that.data.goodsInfo.forEach((item,index)=>{
      if(index < 3){
        command.setText(30, 200 + index * 40, 'TSS24.BF2', 1, 1, `物品${index+1}:${item.goodsName}/${item.goodsAmount}/${item.goodsStatus}`);
      }
    })
    // 获取 canvas 区域隐含的像素数据。
    wx.canvasGetImageData({
      canvasId: 'edit_area_canvas',
      x: 0,
      y: 0,
      width: canvasWidth,
      height: canvasHeight,
      success: function(res) {
        command.setBitmap(60, 0, 1, res)
        
      },
      complete: function() {
        command.setPagePrint()
        that.setData({ isLabelSend: true })
        that.prepareSend(command.getData())
        
      }
    })
    setTimeout(()=>{
      that.onPrint()
    },500)
  }
})

打印需要的插件

 encoding.js和encoding-indexes.js 下载地址text-encoding - npmPolyfill for the Encoding Living Standard's API.. Latest version: 0.7.0, last published: 6 years ago. Start using text-encoding in your project by running `npm i text-encoding`. There are 764 other projects in the npm registry using text-encoding.icon-default.png?t=N7T8https://www.npmjs.com/package/text-encoding?activeTab=code

tsc.js 见下篇

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值