更新记录

1.5.0(2024-11-19)

1:增加usb连接 2:增加wifi连接

1.4.0(2024-11-12)

1:修改模板解析方式,加速打印速度。简化模板打印数据传输方式。 2:模板编辑器优化,增加条码、二维码预览等功能。

1.3.4(2024-11-01)

1:修复BLE连接时,ESC打印没有反应

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:4.4 - 14.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 ×

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


通用安卓蓝牙、USB打印

1. 简介

本插件为仅支持安卓平台的蓝牙\USB打印原生插件,已经基于标准ESC、CPCL、TSPL、ZPL指令进行了指令二次封装。采用json数据交互简单易用,可打印文本、图片、二维码、一维码、表格等。
插件也支持其它格式的打印指令,如tsc等,但是除了ESC、CPCL、TSPL、ZPL外的指令没有提供二次封装,需要开发者使用原始指令(参考厂商提供指令文档)。
插件可以配合可视化模板编辑器进行标签创作,然后使用模板数据进行标签打印,
请先使用测试程序按照下图进行测试:

下载测试程序地址:http://47.107.85.113:81/testPrint.apk

注意:测试程序上面“商米小票打印”、“商米标签打印”仅针对商米一体打印机,如sunmi v2s plus

2. 使用流程

  1. 确定打印机支持的打印指令,可以查看产品说明书或者跟厂商技术支持咨询
  2. 获取设备列表(蓝牙连接需要先在安卓系统设置里面进行蓝牙配对,USB连接需要在AndroidManifest.xml文件中增加
  3. 连接设备
  4. 发送数据(需要根据打印机使用不同的打印指令)
  5. 打印机打印
  6. 如果无法获取蓝牙设备列表,可能是高版本安卓导致,需要增加对应蓝牙附近设备权限, 并把APP的“附近设备”权限”打开-关闭-打开”,刷新一遍
  7. 如果无法获取USB设备列表,可能是没有在AndroidManifest.xml文件中增加
  8. 连接WIFI设备需要在AndroidManifest.xml文件中增加

3. 示例代码

3.1 cpcl方式打印

<template>
<div>
    <button type="primary" @click="refresh(1)">刷新已配对蓝牙设备</button>
    <button type="primary" @click="refresh(2)">刷新USB设备列表</button>
    <button type="primary" @click="connect">连接</button>
    <button type="primary" @click="disconnect">断开连接</button>
    <button type="primary" @click="print">打印</button>
    <button type="primary" @click="getState">获取状态</button>
    <button type="primary" @click="addBroadcastReceiver">注册断开连接广播</button>
    <button type="primary" @click="removeBroadcastReceiver">移除断开连接广播</button>
    <button type="primary" @click="startSearch">搜索设备</button>
    <button type="primary" @click="stopSearch">停止搜索</button>
    <button type="primary" @click="bond">配对</button>
    <div>
      <div>当前选择设备: {{device.name}}</div>
      <div>
        <div v-for="item in devices" @click="selectDevice(item)" :key="item.address">{{item.name}}</div>
      </div>
    </div>
  </div>
</template>

<script>
  // 获取 module,所有接口返回的数据格式为json: {success: true, msg: '' , data: Object}
  var printerModule = uni.requireNativePlugin("ammagician-printer")
  const modal = uni.requireNativePlugin('modal');

  //主动监听蓝牙设备断开后,插件向外发送的事件。该事件依赖于插件内部注册的广播。
  printerModule.addEventListener('disConnect', function (e) {})

  export default {
    data() {
      return {
        device: {
          name: ''
        },
        devices: []
      }
    },
    mounted() {
      //注册蓝牙搜索结果回调
      printerModule.addEventListener('searchHandler', function(e) {
        console.info(JSON.stringify(e))
      })
    },
    methods: {
      isReady(){
        //蓝牙是否打开
        printerModule.isReady({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
        })
      },
      //是否连接了设备
      isConnect(){
        printerModule.isConnect({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
        })
      },
      //获取当前连接设备的地址
      getConnectDevice(){
        printerModule.getConnectDevice({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
        })
      },

      //打开蓝牙
      openBluetooth(){
        printerModule.openBluetooth({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
        })
      },
      //关闭蓝牙
      closeBluetooth(){
        printerModule.closeBluetooth({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
        })
      },

      //获取绑定的设备, 返回data为{success: true, msg: '' , data: [name: 'xx', address: 'yyy', type: 0|1|2|3]}
      //设备类型0:未知 1:低功耗 2:经典蓝牙 3:低功耗、经典蓝牙双模
      refresh(type) {
        printerModule.getDevices({isUsb: type===2}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret.data),
            duration: 1.5
          });
          this.devices = ret.data;
        })
      },

      //选择设备
      selectDevice(item) {
        modal.toast({
          message: item.name,
          duration: 1.5
        });
        this.device = item
      },

      //连接设备
      connect() {
        if (this.device) {
          //参数为设备地址,
          //如果设备为BLE设备,需要增加参数BLE特征值"uuid_ble"、写特征值"uuid_write"、叙词特征值"uuid_descriptor"
          //该值默认分别为:"0000fff1-0000-1000-8000-00805f9b34fb"、"0000fff2-0000-1000-8000-00805f9b34fb"、"00002902-0000-1000-8000-00805f9b34fb"
          //如连接、发送数据等出现问题,请联系设备厂商
          printerModule.connect({
              'address': this.device.address,   //蓝牙连接
              vendorId: this.device.vendorId,   //usb连接需要
              productId: this.device.productId, //usb连接需要
              deviceId: this.device.deviceId, //usb连接需要
              isUSB: !!this.device.productId,  //是否为USB连接,与isIP不能同时为TRUE
              ip: this.device.vendorId,   //wifi连接需要
              port: this.device.productId, //wifi连接需要
              isIP: false  //是否为WiFi连接,与isUSB不能同时为TRUE
            },
            (ret) => {
              modal.toast({
                message: ret.msg,
                duration: 1.5
              });
            })
        }
      },

      //断开设备
      disconnect() {
        printerModule.disconnect({
          isUSB: !!this.device.productId,  //是否为USB连接,与isIP不能同时为TRUE
          isIP: false  //是否为WiFi连接,与isUSB不能同时为TRUE
          },
          (ret) => {
            modal.toast({
              message: ret.msg,
              duration: 1.5
            });
          })
      },

      //打印
      print() {
        if (this.device) {
          printerModule.print({
              'encoding':"gbk", //默认为gbk
              'cmdType': "cpcl",
              'data': [
                { type: 'setup', offset: 0, dpi_w: 200, dpi_h: 200, width:600, height: 620, qty:1}, //设置打印页面,必须存在
                { type: 'pageEnd'},
                { type: 'setAlign', value:0},
                { type: 'text', content: 'CPCL打印测试', font:0, value:4, bold:1, widthScale:2, heightScale:2, x:100, y:20 },
                { type: 'box', x: 10, y: 0, x1: 560, y1: 600, width:2 },
                { type: 'line', x: 10, y: 50, x1: 560, y1: 50, width:3 },
                { type: "text", content:"反色显示", font:24, value:0, x:20, y:60},
                { type: "text", content:"重量:6.980", font:24, value:0, x:20, y:90,},
                { type: "inverse", x:20, y:60, x1:300, y1:60, width:60},
                { type: "text", content:"材料代码:80050008", font:24, value:0, x:20, y:120, underline:1},
                { type: 'text', content:"第一行\r\n第二行\r\n第三行", font:24, value:0, x:20, y:150, height: 30}, 
                { type: 'qrcode', codeType:2, x:240, y:360, tolerant: 1, qrVersion:2, content:"www.baidu.com" },   
                { type: 'barcode', barcodeType:"128", width:1, height:60, x:300, y:520, content:"123456789", textPos: 1, font:0, value:2}, 
                { type: 'from'},
                { type: 'print'}  //触发打印命令,放在最后
              ],
              isUSB: !!this.device.productId,  //是否为USB连接,与isIP不能同时为TRUE
              isIP: false  //是否为WiFi连接,与isUSB不能同时为TRUE
            },
            (ret) => {
              modal.toast({
                message: ret.msg,
                duration: 1.5
              });
            })
        }
      },

      //获取打印机状态
      getState(){
        //获取打印机状态: timeout(100~1000) retry(1~10)  cmd十进制命令数组   resultLength返回结果字节数
        //具体的命令以及返回结果长度,需要参考具体打印机厂商的开发文档。目前例子cmd[29, 153]参数仅对济强有效
        //{27, 33, 101, 120, 105, 116, 13, 10, 27, 33, 63, 27, 33, 68} 芯烨
        //{29, 153} 芝柯
        printerModule.getState({
          isUSB: !!this.device.productId, //是否为USB连接,与isIP不能同时为TRUE
          isIP: false  //是否为WiFi连接,与isUSB不能同时为TRUE
          timeout:500, 
          retry:1, 
          cmd:[29, 153], 
          resultLength: 4
          },
          (ret) => {
            modal.toast({
              message: ret.msg,
              duration: 1.5
            });
          })
      },
      //默认情况下,插件会自动向系统注册蓝牙断开的广播,如果被调用removeBroadcastReceiver移除后。可以重新加回来
      addBroadcastReceiver(){
        printerModule.addBroadcastReceiver({},
          (ret) => {
            modal.toast({
              message: ret.msg,
              duration: 1.5
            });
          })
      },
      //默认情况下,插件会自动向系统注册蓝牙断开的广播,可以调用removeBroadcastReceiver移除。为了避免系统内存泄漏,建议在系统退出是调用此方法
      removeBroadcastReceiver(){
        printerModule.removeBroadcastReceiver({},
          (ret) => {
            modal.toast({
              message: ret.msg,
              duration: 1.5
            });
          })
      },
      startSearch() {
        printerModule.search({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret),
            duration: 3
          });
        })
      },
      stopSearch() {
        printerModule.stopSearch({}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret),
            duration: 3
          });
        })
      },
      bond() {
        //需要配对的地址
        const address = "00:12:52:40:60:79";
        printerModule.bond({address: address}, (ret) => {
          modal.toast({
            message: JSON.stringify(ret),
            duration: 3
          });
        })
      },
    }
  }
</script>

CPCL示例打印结果:

3.2 ESC方式打印

使用 ESC 方式需要将 cmdType 设置为 "esc", 同时指令也跟 CPCL 方式有一定的区别

let imgStr = '我是base64图片数据,需要替换为真正的BASE'
let jsonData = {
  cmdType: 'esc',
  data: [
    { type: 'setAlign', value: 1 },
    { type: 'feedLine', value: 2 },
    { type: 'text', content: 'ESC打印测试\n', value: 30, bold: 1 },
    { type: 'feedEnter' },
    { type: 'setAlign', value: 0 },
    { type: 'text', content: '**********************************************\n' },
    { type: 'text', content: '钢卷号:S945500150-450101\n', absolute: true, x: 5, underline: 1 },
    { type: 'text', content: '重量:6.980\n', absolute: true, x: 5 },
    { type: 'text', content: '供应商代码:450101\n', absolute: true, x: 5 },
    { type: 'text', content: '材料名称:热镀锌板Q235A 2.0x1250xC\n', absolute: true, x:15},
    { type: 'text', content: '材料代码:80050008\n', absolute: true, x: 5 },
    { type: "text", content:"第一列", midContent:"中间列", rightContent:"第三列", absolute:true, x:5},
    { type: 'text', content: '**********************************************\n' },
    { type: 'qrcode', content: 'www.baidu.com', width: 120, height:120, absolute: true, x: 25},
    { type: 'feedEnter' },
    { type: 'qrcode', codeType:0, content: 'www.baidu.com', width: 280, height:80, absolute: true, x: 50, imageCmd: 0}, //如打印异常可尝试imageCmd修改为1
    { type: 'feedDot', value: 10 },
    { type: 'barcode', content: '123456789', width:240, height: 40, absolute: true, x: 100, imageCmd: 0}, //如打印异常可尝试imageCmd修改为1
    { type: 'feedLine', value: 3 },
    { type: 'setAlign', value: 1 },
    { type: 'text', content: '---------测试图片----\n', rotate: 1 },
    { type: 'image', width: 240, height: 240, absolute: true, x: 200, content: imgStr, imageCmd: 0  }, //如图片打印异常可尝试imageCmd修改为1改用1d76指令打印

    { type: 'text', content: '\n-----------------绘制线条-------------\n' },
    { type: 'setAlign', value: 0 },
    { type: 'line', width: 300, height: 2, imageCmd: 0}, //如打印异常可尝试imageCmd修改为1
    { type: 'feedEnter'},
    { type: 'line', absolute: true, x: 50, y: 60, width: 300, height: 2, imageCmd: 0}, //如打印异常可尝试imageCmd修改为1
    { type: 'feedEnter'},
    { type: 'feedLine', value: 1 },

    { type: 'setAlign', value: 1 },
    { type: 'text', content: '-----------------设置Tab-------------\n' },
    { type: 'setAlign', value: 0 },
    { type: 'setTab', tabs: [10, 22, 34, 42] },
    { type: 'text', content: '运单号    到达站点    货物名称    件数    运费\n' },
    { type: 'text', content: '1234567' },
    { type: 'moveTab' },
    { type: 'text', content: '珠海' },
    { type: 'moveTab' },
    { type: 'text', content: '五香瓜子' },
    { type: 'moveTab' },
    { type: 'text', content: '5包' },
    { type: 'moveTab' },
    { type: 'text', content: '1毛' },
    { type: 'feedEnter' },
    { type: 'setAlign', value: 1 },
    { type: 'text', content: '-----------------设置Tab end-------------\n' },
    { type: 'feedLine', value: 2 },
    { type: 'pageEnd' },
  ],
}

printerModule.print(jsonData, (ret) => {
  modal.toast({
    message: ret.msg,
    duration: 1.5,
  })
})

ESC 示例打印结果:

3.3 TSPL方式打印

使用 TSPL 方式需要将 cmdType 设置为 "tspl", encoding设置为"UTF-8", 同时指令也跟 CPCL 方式有一定的区别

let imgStr = '我是base64图片数据,需要替换为真正的BASE'
let jsonData = {
  cmdType: 'tspl',
  data: [
    { type: 'setup', width:590, height: 600, unit: 'dot'}, //unit默认为dot,可以使用公制单位mm
    { type: 'gap', x: 0, y: 0, unit: 'dot' }, //unit默认为dot,可以使用公制单位mm
    {type:"text","content":"钣金入库标签(HSF)",widthScale:2,heightScale:2,x:288,y:20,align:1},
    {type:"barcode",content:"QTBJ10010023",barcodeType:"128",height:50,narrow:2,wide:2,textPos:1,y:70,x:288},
    {x:10,y:165,type:"text",content:"物料名称:过线盖"},
    {x:10,y:205,type:"text",content:"物料编码:068"},
    {x:10,y:245,type:"text",content:"物料图号:KFR35Wsdksahdkhk"},
    {x:10,y:285,type:"text",content:"工作中心:BJCY01"},
    {x:10,y:325,type:"text",content:"批次/订单数量:6/70"},
    {x:10,y:365,type:"text",content:"生产时间:2022-12-19 14:50:44"},
    {x:10,y:405,type:"text",content:"总装订单/线体:WERashdjhj7878"},
    {x:10,y:445,type:"text",font:"TSS24.BF2",content:"操作工:钣_操作工"},
    {type:"qrcode",content:"7878788c7f2332f795d94bc5fb96e17995e5b",y:450,x:400,tolerant:"L"},
    {type:"print", x:1,y:1}
  ],
}

printerModule.print(jsonData, (ret) => {
  modal.toast({
    message: ret.msg,
    duration: 1.5,
  })
})

TSPL 示例打印结果:

3.4 商米标签打印

使用商米标签打印方式需要将 cmdType 设置为 "sunmi_label", 指令参考商米API。其中style参数被打散为API参数,bool参数改为int型,大于0为true

let imgStr = '我是base64图片数据,需要替换为真正的BASE'
let jsonData = {
  cmdType: 'sunmi_label',
  data: [
    {type: 'setup', width:590, height: 620},
    {type:"text",text:"钣金入库标签",bold:1, textWidthRatio:2,textHightRatio:2,posX:288,y:20,align:2},
    {type:"barcode",text:"QTBJ10111010023",barcodeType:"CODE128",height:50,dotWidth:2,readable:2,align:2,posY:70,posX:288},
    {posX:10,posY:165,type:"text",text:"物料名称:过线盖"},
    {posX:10,posY:205,type:"text",text:"物料编码:0306888"},
    {posX:10,posY:245,type:"text",text:"物料图号:KFR35Wjasdhsadh7878"},
    {posX:10,posY:285,type:"text",text:"工作中心:BJCY01"},
    {posX:10,posY:325,type:"text",text:"批次/订单数量:6/70"},
    {posX:10,posY:365,type:"text",text:"生产时间:2022-12-19 14:50:44"},
    {posX:10,posY:405,type:"text",text:"总装订单/线体:WERWaksjkj7878"},
    {posX:10,posY:445,type:"text",text:"操作工:钣_操作工"},
    {type:"qrcode",text:"88c7f2332f795d94bc5fb96esdhhjhjsd17995e5b",posY:450,posX:400,dot:4},
    {type:"image",content:imgStr,posY:500,posX:200,width:80,height:80},
    {type:"print", value:1}
  ],
}

3.5 商米小票打印

使用商米小票打印方式需要将 cmdType 设置为 "sunmi_ticket", 指令参考商米API。其中style参数被打散为API参数,bool参数改为int型,大于0为true

let imgStr = '我是base64图片数据,需要替换为真正的BASE'
let jsonData = {
  cmdType: 'sunmi_ticket',
  data: [
    {type: 'setup', width:590, height: 620,align:2},
    {type:"printText",text:"钣金入库",bold:1, textWidthRatio:1,textHightRatio:1},
    {type:"barcode",text:"QTBJ10010023",barcodeType:"CODE128",height:50,dotWidth:2,readable:2,align:2},
    {type: 'setup', align:1},
    {type:"printText",text:"物料名称:过线盖"},
    {type:"printText",text:"物料编码:068"},
    {type:"printText",text:"物料图号:KFR35WJ33787KJKJKJ"},
    {type:"printText",text:"工作中心:BJCYKLKHBF01"},
    {type:"printText",text:"批次/订单数量:6/70"},
    {type:"printText",text:"生产时间:2022-12-19 14:50:44"},
    {type:"printText",text:"总装订单/线体:WERW3SDKJK4545"},
    {type:"printText",text:"操作工:钣_操作工"},
    {type:"qrcode",text:"78787888c7f2332f795d94bc5fb96e17995e5b",dot:4,align:2},
    {type:"image",content:imgStr,width:80,height:80,align:2},
    {type:"print"}
  ],
}

3.5 ZPL打印

使用ZPL打印方式需要将 cmdType 设置为 "zpl",

let imgStr = '我是base64图片数据,需要替换为真正的BASE'
let jsonData = {
  "cmdType": "zpl",
    "encoding":"UTF-8",
    "data": [
        { type: 'size', width:592, height: 640},
        { type: "text", content:"重量:6.980", font:"0", x:200, y:300, widthScale:40, heightScale:40,"customFont":"E:LZHONGHE.TTF"},
        { type: "text", content:"rotate 0", font:"B", x:100, y:500, widthScale:20, heightScale:20}, 
        { type: "textBlock", content:"我们12345679qwertyuiop", font:"A", x:400, y:400, widthScale:20, heightScale:20, width: 150, height: 200,"customFont":"E:LZHONGHE.TTF"}, 
        { type: 'box', x: 10, y: 20, width:200, height: 100, thickness: 2, radius: 0 },
        { type: 'bar', x: 10, y: 50, width:200, height: 3},
        { type: 'line', x: 10, y: 50, width:200, height: 3, direction: 'L'},
        { type: 'circle', x: 10, y: 50, diameter:200,thickness: 3 },
        { type: 'ellipse', x: 10, y: 50, width:200, height: 100, thickness: 2 },
        { type: 'qrcode', x:240, y:360, tolerant: 1, content:"www.baidu.com", model: '1', factor: 2, mask: 7, rotate: 90 },   
        { type: 'barcode', height:60, x:300, y:520, content:"123456789", textPos: 1, rotate: 90}, 
        { type: 'image', width:120, height:120, x:320, y:180, content: imgStr }
    ]
}

3.6 cmdType说明

通过cmdType区分打印机使用的指令类型,ESC适用于打印长度不固定内容,排版能力弱,比如流水单。 CPCL是一种以页面排版方式的指令集,适用于打印长度固定内容,比如价签,快递单。 每项数据通过 type 来区分不同的打印指令,ESC和CPCL下的指令略有不同。

3.7 encoding说明

插件中默认使用的编码方式为gbk。 出现乱码可以尝试以下方式解决:

  1. 更改encoding为其他编码。
  2. 可以尝试设置打印机。
  3. 或者在指令中指定字体文件,如以下zpl指令: "^FO0,45^A@N,36,18,E:MSUNG24.FNT^FD箱码:^FS"

3.8 ESC/CPCL/TSPL/ZPL指令打印示例

原始的打印机指令分为 “整型” 和 “字符串”两种。 ESC为典型的“整型”类型,它支持十进制、十六进制的格式,比如下列设置行间距指令: 十六进制: 0x1B 0x33 n
十进制: 27 51 n CPCL为典型的“字符串”类型,它支持字符串的格式,比如下列打印文字的指令: TEXT 7 0 210 60 HORIZ.

3.8.1整型指令示例

使用esc等“整型”指令, 需要将 cmdType 设置为 "esc",然后将原始指令的十进制形式放入esc数组中。

let jsonData = {
  cmdType: 'esc',  
  data: [
    { type: 'esc', esc: [27,51,2] }, // 发送原始命令,指令必须为十进制数值。
  ],
}

使用插件封装的ESC指令,配合原始指令进行自由组合可以实现复杂功能。该方式仅支持二次封装的ESC指令和原始ESC指令的混用

let jsonData = {
  cmdType: 'esc',  
  data: [
    { type: 'setAlign', value: 1 },
    { type: 'esc', esc: [27,51,2] }, // 发送原始命令,指令必须为十进制数值。
    { type: 'feedLine', value: 2 },
    { type: 'text', content: 'ESC打印测试\n', value: 30, bold: 1 },
    { type: 'esc', esc: [27,51,5] }, // 发送原始命令,指令必须为十进制数值。
  ],
}

3.8.2 字符串型指令示例

使用cpcl等“字符串”指令, 需要将 cmdType 设置为 "cpcl",然后将原始指令的字符串放入cpcl数组中。

//发送原始cpcl指令
let jsonData = {
  cmdType: 'cpcl',  
  data: [
    { type: 'cpcl', cpcl: ["BARCODE 128 1 1 50 150 10 HORIZ ", "TEXT 7 0 210 60 HORIZ"] }, // 发送原始命令,指令必须为字符串。
  ],
}
//发送原始zpl指令
jsonData = {
  cmdType: 'cpcl',  
  data: [
    {type: 'cpcl', cpcl: [
      "^XA^MNW^JUS^CI28",
      "^FO0,45^A@N,36,18,E:MSUNG24.FNT^FD箱码:^FS",
      "^FO90,25^JMA^MD20^BY2,3,320^BCN,60,Y,N,N^FD1234567890^FS",
      "^FO0,100^A@N,36,18^FD类型:直通^FS",
      "^PQ1,0,1,Y",
      "^XZ"
      ] 
    }, // 发送原始命令,指令为字符串,请参考各指令编程文档
  ]
}

使用插件封装的cpcl指令,配合原始指令进行自由组合可以实现复杂功能。该方式仅支持二次封装的cpcl指令和原始cpcl指令的混用

let jsonData = {
  cmdType: 'cpcl',  
  data: [
    {type:'setup', offset: 0, dpi_w: 200, dpi_h: 200, width:600, height: 620, qty:1},
    {type: 'cpcl', cpcl: ["TEXT 55 0 4 2 $"] },
    {type:'box',x:0, y:0, x1:560, y1:500,width:2},
    {type:'text',content:"生产订单:122",font:24,value:0,x:10,y:60}, 
    { type: 'from'},
    { type: 'print'} 
  ],
}

4. 二次封装指令完全说明

以下内容为针对本插件提供的二次封装指令的完全,使用者 切勿 完全照搬作为示例.

4.1 ESC二次封装指令说明

let imgStr = '我是base64图片数据,'

//ESC格式,由于各个厂商设备支持力度、固件不一样。字体、字体大小、一维码类型、容错等级、打印速度等的设置需要参考打印机说明。
let jsonData = {
  cmdType: 'esc',  
  data: [
    { type: 'esc', esc: [27,100,2] }, // 发送原始命令,指令为十进制数值。
    { type: 'setup',maxCharCount:48 }, // 设置当前字体设置下每行支持最大字符数,用于计算2列、3列的空白符个数
    { type: 'reset' }, // 重置打印机
    { type: 'setMode', value: 0 }, // 设置打印模式 0:标准模式 1:页模式, 未经测试
    { type: 'setPage', x: 20, y: 10, width: 300, height: 400 }, // 页模式下设置打印区域, 未经测试
    { type: 'setRotate', value: 0  }, // 页模式下设置打印方向 0 1 2 3, 未经测试
    { type: 'pluse', value: 10, x:10, y: 10 }, // 钱箱脉冲,未经测试  value  = 0, 1, 48, 49 0 ≤ x ≤ 255, 0 ≤ y ≤ 255。
    { type: 'pageLeft' }, // 走纸至左边黑标
    { type: 'pageRight' },  //走纸至右边黑标
    { type: 'pageEnd' },  //走纸到标签缝
    { type: 'cutPaper' }, // 半切,未经测试
    { type: 'cutPaper', value: 1 }, // 全切,未经测试
    { type: 'setLineSpace', value: 10 }, // 设置行间距为10
    { type: 'setCharSpace', value: 10  }, // 设置字符左右间距为10
    { type: 'setLeftMargin', value: 10  }, // 设置左边距10, 
    { type: 'setRightMargin', value: 10  }, // 设置右边距10, 
    { type: 'setAlign', value: 0 }, //设置对齐方式,行首有效(0:左对齐, 1:居中, 2:右对齐)
    { type: 'setTab', tabs: [10, 22, 34, 42] },  //设置4个tab位置点,单位为点
    { type: 'moveTab' },  //移动到下一TAB位置
    { type: 'feedEnter' }, //打印内容并换行
    { type: 'feedLine', value: 2 }, //打印内容并走纸 2行
    { type: 'feedDot', value: 2 }, //打印内容并走纸 2点
    { type: 'feedBack', value: 2 }, //打印内容并退纸 2点,未经测试
    { type: 'space', value: 10 }, //连续打印10个空格
    { type: 'line', absolute: true, x: 50, width: 300, height: 1, imageCmd: 0}, //如打印异常可尝试imageCmd修改为1, 从x=50处画横线,长300, 高1
    { type: 'text', content: '1234567' },  //默认打印文本
    { type: 'text', content: '钣金喷涂分厂物料合格标识', value: 30, bold: true, underline: true, rotate: 1 }, //默认位置打印内容,字体大小为30、祖体、带下横线、文字旋转90度(0,1,2,3)
    { type: 'text', content: '钢卷号:S945500150-450101', absolute: true, x: 5, underline: true }, //绝对位置打印文本,带下横线,absolute为true时表示绝对位置
    { type: 'text', content: '左边内容', rightContent: '右边内容\n' }, //双列打印
    { type: 'text', content: '左边内容', midContent: '中间内容', rightContent: '右边内容\n' }, //三列打印
    { type: 'image', width: 200, height: 50, absolute: true, x: 200, content: imgStr, imageCmd: 0 },  //绝对位置打印图片, width为宽度, height为高度,content为base64图片数据, 如图片打印异常可尝试imageCmd修改为1改用1d76指令打印
    { type: 'qrcode', content: 'www.baidu.com', absolute: true, x: 460,  codeType: 2, tolerant: 0, qrVersion: 1, imageCmd: 0 }, //绝对位置打印二维码,unit为条码单元大小. codeType二维码类型 0 :PDF417  1 :DataMatrix 2 :QRCode    tolerant容错级别QRCode: [ 0 1 2 3]  PDF417: [ 0 1 2 3 4 5 6 7 8]    如打印异常可尝试imageCmd修改为1
    { type: 'barcode', content: '123456789', width: 160, height: 40, absolute: true, x: 140, barcodeType:"128", imageCmd: 0},  //绝对位置打印条码,height条码高度,width条码宽度,barcodeType一维码类型(UPCA,UPCE,EAN13,EAN8,39,93,128,I2OF5,CODEBAR)  //如打印异常可尝试imageCmd修改为1
  ],
}

4.2 CPCL二次封装指令说明

CPCL格式,由于各个厂商设备支持力度、固件不一样。因此字体、字体大小、一维码类型、容错等级、打印速度等的设置需要参考打印机说明。cpcl指令先后顺序有一定影响,请参考cpcl文档

jsonData = {
  cmdType: 'cpcl',  
  data: [
    {type: 'cpcl', cpcl: ["TEXT 55 0 4 2 $"] }, // 发送原始命令,指令为字符串,请参考cpcl文档
    {type:'setup', offset: 0, dpi_w: 200, dpi_h: 200, width:600, height: 620, qty:1},  //设置水平补偿点数offset,水平分辨率dpi_w,垂直分辨率dpi_h,标签的最大高度点数height,标签的最大宽度点数width,打印次数qty'
    {type:'pageEnd'}, //设置标签检测指令,和FORM配合使用后,打印完后走纸到标签
    {type:'pageLeft'}, //设置标签检测指令,和FORM配合使用后,打印完后走纸到左侧标签
    {type:'pageRight'}, //设置标签检测指令,和FORM配合使用后,打印完后走纸到右侧标签
    {type:'background',value:110},  //设置水印文字灰度级,0-255
    {type:'setAlign',value:0}, //设置对齐方式 0左对齐 1居中 2右对齐 
    {type:'setCharSpace',value:5},  //设置字符间距为5
    {type:'text',content:"钣金喷涂分厂物料合格标识",font:55,value:4,bold:0,underline:0,widthScale:1, heightScale:1,x:10,y:10,rotate:0}, //添加文字,字体55,字体大小4,不加粗,不加下划线,宽度、高度缩放为1,坐标(10,10),旋转角度为0(0,90,180,270)。
    {type:'setCharSpace',value:0}, //设置字符间距为默认
    {type:'setAlign',value:2}, //设置右对齐 
    {type:'text',content:"HSF ",font:0, value:3, bold:1, underline:1, x:0, y:20}, //添加文字,字体0,字体大小3,加粗,加下划线,坐标(0,20)。
    {type:'setAlign',value:0}, //设置左对齐 
    {type:'box',x:0, y:0, x1:560, y1:500,width:2}, //添加矩形起点(0,0),终点(560,500),线宽2
    {type:'line',x:0, y:50,x1:560, y1:50,width:3}, //添加线条起点(0,50),终点(560,50),线宽3
    {type:'setAlign',value:0}, //设置左对齐 
    {type:'text',content:"生产订单:122",font:24,value:0,x:10,y:60}, //添加文字
    {type:'text',content:"物料名称/编号:122",font:24,value:0,x:10,y:90,}, //添加文字
    {type:'inverse',x:10, y:60,x1:300, y1:60,width:60}, //反白显示,起点(10,60),终点(300,60),线宽60,在此区域内的内容将反白显示
    {type:'text',content:"物料图号:122\r\n工作中心:122\r\n工艺路径:122",font:24,value:0,x:10,y:120,height: 30},  //添加多行文字,每行高度为30,height为0时表示为单行显示
    {type:'text',content:"批次/订单数量:122",font:24,value:0,x:10,y:210,}, //添加文字
    {type:'text',content:"操作工:122",font:24,value:0,x:10,y:240,}, //添加文字
    {type:'bktext',content:"生产时间:122",font:24,value:0,x:10,y:270,}, //添加水印文字
    {type:'concat',concats:["4 2 5 $","4 3 0 12","4 2 5 34",],x:10,y:300,}, //添加单行不同格式文字,示例为在(10,300)开始显示不同格式的文字。$字体为4,字体大小为2,偏移为5;12字体为4,字体大小为3,偏移为0;34字体为4,字体大小为2,偏移为5
    {type:'qrcode',codeType:1,width:120,height:120,x:10,y:360,density:3,content:"www.baidu.com" },  //添加DATAMATRIX码,不显示标识符,DATAMATRIX条码点密度density为3
    {type:'qrcode',codeType:2,x:140,y:360,tolerant: 1, qrScale: 6, content:"www.baidu.com" }, //添加二维码,不显示标识符,120*120。容错等级3(非常高的可靠和密度等级),2(高可靠等级),1(标准等级),0(高密度等级), qrScale:设置放大缩小(1-32,默认为6)
    {type:'image',width:120,height:120,x:320,y:360, content: imgStr},  //添加图片,数据为base64格式
    {type:'qrcode',codeType:0, minDot_w: 2, minDot_h:6, cap:3, tolerant:0, x:0,y:520,content:"www.baidu.com" },  //添加PDF-417码,宽度最小点数minDot_w为2,高度最小点数minDot_h为6,每行容纳的码数cap为3,容错等级为0
    {type:'barcode',barcodeType:"128",width:1,height:60,x:300,y:520,content:"123456789",textPos: 1,font:0,value:2}, //添加一维码,类型为“128”(参考打印机说明),显示标识符,标识符字体为0,标识符字体大小为2'
    {type:'background',value:0},  //设置水印文字灰度级为默认
    {type:'from'}, //设置打印结束后,并走纸到定位点。 必须要在print之前
    {type:'print'}  //执行打印控制内容 
    {type:'cutPaper', value: 0}  //切纸, 0半切 1全切

    //其他指令
    {type:'end', }  //结束指令
    {type:'abort'}  //取消指令
    {type:'preFeed', value: 10}  //打印前进纸10 
    {type:'postFeed', value: 20}  //打印后进纸20
    {type:'wait', value: 8}  //打印一张后,需要等待设置的时间过后才打印第二张。延时8*(1/8)秒的时间 
    {type:'contrast', value: 0}  //设置打印对比度0-3
    {type:'zprotate', value: 0}  //旋转打印0 90 180 270
    {type:'speed', value: 0}  //设置打印速度0-5,0最慢
  ]
}

4.3 TSPL二次封装指令说明

TSPL格式,由于各个厂商设备支持力度、固件不一样。因此字体、字体大小、一维码类型、容错等级、打印速度等的设置需要参考打印机说明。TSPL指令先后顺序有一定影响,请参考TSPL文档

jsonData = {
  cmdType: 'tspl',  
  data: [
    {type: 'tspl', tspl: ["size 600 dot, 500 dot"] }, // 插入发送原始命令,指令为字符串,请参考TSPL文档, 
    {type:'reset'}, //重置打印机
    { type: 'setup', width:590, height: 620, unit: 'dot'}, //设置初始参数,width: 标签宽度; height:标签高度;单位unit默认为dot/mm; 该指令同时设置了direction reference cls三个指令
    { type: 'size', width:590, height: 620, unit: 'dot'}, //设置标签宽高,width: 标签宽度; height:标签高度;单位unit默认为dot,可以使用公制mm;
    { type: 'gap', x: 0, y: 0, unit: 'dot' }, //设置两张标签之间空白距离,以及左右两边空白宽度,x: 标签之间空白距离,单位为dot/mm; y:左右两边空白宽度,单位为dot/mm; x设置为0,则为连续纸
    { type: 'direction', x: 0, y: 0 }, //设置打印方向,以及镜像打印,x: 打印方向; y:是否镜像; 默认为 0 0
    { type: 'feedDot', value: 0 }, //设置走纸距离; value:走纸距离,单位为dot;
    { type: 'feedBack', value: 0 }, //设置退纸距离; value:退纸距离,单位为dot;
    { type: 'form', }, //走纸一张标签纸
    { type: 'feedHome'}, //走纸到下一正确打印位置
    { type: 'wait', value: 0 }, //延迟执行命令,value:延迟毫秒数
    { type: 'speed', value: 0 }, //设置打印速度
    { type: 'density', value: 0 }, //设置打印黑度
    { type: 'cls'}, //清除缓冲区
    { type: 'country', content: "" }, //设置国际字符集
    { type: 'codePage', content: "" }, //设置国际代码页
    { type: 'cutPaper'}, //切纸
    { type: 'line', x: 0, y: 0, x1:100, y1: 100, thickness: 1 }, //打印直线,x: 起点X; y:起点Y; x1:终点x  y1:终点Y  thickness:线宽
    { type: 'bar', x: 0, y: 0, width: 100, height: 10 }, //打印矩形块,可以用来打印直线。x: 起点X; y:起点Y; width:宽度  height:高度
    { type: 'box', x: 0, y: 0, x1:100, y1: 100, thickness: 1, radius: 2 }, //打印线框,x: 起点X; y:起点Y; x1:终点x  y1:终点Y  thickness:线宽  radius: 圆角
    { type: 'circle', x: 0, y:0,  diameter: 10, thickness: 1 }, //打印圆,x: 起点X; y:起点Y; diameter:直径  thickness:线宽
    { type: 'ellipse', x: 0, y: 0, width: 100, height: 10, thickness: 1 }, //打印椭圆,x: 起点X; y:起点Y; width:宽度  height:高度  thickness:线宽
    { type: 'erase', x: 0, y: 0, width: 100, height: 10 }, //擦除,。x: 起点X; y:起点Y; width:宽度  height:高度
    {type:"text","content":"钣金入库标签(HSF)",widthScale:2,heightScale:2,x:288,y:20,align:1,rotate: 0, font: 'TSS24.BF2'}, //打印文字,x: 起点X; y:起点Y; content:内容  widthScale:文字X方向放大倍数  heightScale:文字Y方向放大倍数   align:对齐方式,(0:左 1:居中 2:右) rotate:旋转角度(0 90 180 270) font:字体,默认为TSS24.BF2
    {type:"block","content":"钣金入库标签(HSF)",width: 100, height: 50, space: 10, fit:0,  widthScale:2,heightScale:2,x:288,y:20,align:1,rotate: 0, font: 'TSS24.BF2'}, //打印文字块,x: 起点X; y:起点Y; content:内容  width:宽度  height:高度 widthScale:文字X方向放大倍数  heightScale:文字Y方向放大倍数   align:对齐方式,(0:左 1:居中 2:右) rotate:旋转角度(0 90 180 270) font:字体,默认为TSS24.BF2  space:增加行间距  fit: 是否收缩文字
    {type:"barcode",content:"QTBJ10010023",barcodeType:"128",height:50,narrow:2,wide:2,textPos:1,y:70,x:288, rotate: 0}, //打印条码,x: 起点X; y:起点Y; content:内容  barcodeType:条码类型   align:对齐方式,(0:左 1:居中 2:右) textPos:条码文字,(0:无 1:左 2:中 3:右) rotate:旋转角度(0 90 180 270) wide:宽bar宽度  narrow:窄bar宽度
    {type:"qrcode",content:"lyen-bdc|unitmes-nanjing|88c7f2332f795d94bc5fb96e17995e5b",y:450,x:400, tolerant: 'L', cellWidth: 4, mode: 'A',rotate: 0}, //打印二维码  x: 起点X; y:起点Y; content:二维码数据   tolerant:容错等级(L M H Q) cellWidth: 单元宽度  mode: 手动M/自动编码A  rotate:旋转角度(0 90 180 270)
    {type:"image",content:"data:image/png;base64xxxxxxx",y:450,x:400,width: 120, height:120}, //打印图片,x: 起点X; y:起点Y; content:base64格式图片数据   width:宽度  height:高度
    {type:"print", x:1,y:1}  //x:打印多少组  y: 每组打印多少份
  ]
}

4.4 ZPL二次封装指令说明

ZPL格式,由于各个厂商设备支持力度、固件不一样。如果使用原始指令请参考ZPL文档

jsonData = {
  cmdType: 'zpl',  
  data: [
    "cmdType": "zpl",
    "encoding":"UTF-8",  //设置编码方式
    "data": [
      { type: 'size', width:592, height: 640},  //设置标签宽高,也如果为连续纸,则必须设置height
      { type: 'printCount', value: 2}, //打印2份标签
      { type: 'zpl', zpl: ["^FO100,100","^BQN,2,10","^FDQA,https://www.example.com^FS"]},  //插入原始zpl指令,该方式可以实现更多插件没有封装的功能
      { type: 'customFont', customFont:"E:LZHONGHE.TTF", fontAlias: 'A', codePage: 28}, //降内部"A"字体映射为自定义字体"E:LZHONGHE.TTF",并且指定编码为28(UTF-8),该命令设置后,所有使用A字体打印都会使用自定义字体,在打印机关机前一直生效。该命令的具体值参考zpl文档,或者厂商指导文档
      { type: "text", content:"重量:6.980", x:200, y:300, widthScale:40, heightScale:40, customFont:"E:LZHONGHE.TTF", codePage: 28}, //使用默认自定义字体"E:LZHONGHE.TTF",编码UTF-8进行打印,widthScale字体款为40,heightScale字体高为40, 该方式只会影响当前指令,不会更改其它指令字体效果
      { type: "text", content:"rotate 0", font:"B", x:100, y:500, widthScale:20, heightScale:20, rotate: 90, reverse:false },    //使用默认B字体打印,widthScale字体款为20,heightScale字体高为20, rotate旋转角度(0/90/180/270), reverse是否打印白色(需要在对应区域打印黑色块,方能看到白色效果)
      { type: "textBlock", content:"我们12345679qwertyuiop", font:"B", x:400, y:400, widthScale:20, heightScale:20, width: 150, height: 200}, //在指定的矩形块区域(宽150高200)打印文本块,内容会自动换行,显示不下的字符会忽略。widthScale字体款为20,heightScale字体高为20
      { type: 'box', x: 10, y: 20, width:200, height: 100, thickness: 2}, //打印矩形,宽为200,高为100, 线宽为2
      { type: 'bar', x: 10, y: 50, width:200, height: 3},  //打印直线,宽为200,高为3
      { type: 'line', x: 10, y: 50, width:200, height: 100, direction: 'L', thickness: 2}, //打印对角线,外矩形宽为200,高为100,线宽为2, direction:R(对角线右倾)/L(对角线左倾)
      { type: 'circle', x: 10, y: 50, diameter:200, thickness: 3 }, //打印圆形,直径为200,线宽为3
      { type: 'ellipse', x: 10, y: 50, width:200, height: 100, thickness: 2 },  //打印椭圆形,外矩形宽为200,高为100,线宽为3
      { type: 'qrcode', x:240, y:360, tolerant: "L", content:"www.baidu.com", model: '1', factor: 2, rotate: 90 },  //打印二维码, tolerant容错级别(L/M/Q/H), factor放大因子(值越大显示的二维码越大,取值1-7), model模式1(原始)和 2(增强,推荐使用)
      { type: 'barcode', height:60, x:300, y:520, content:"123456789", textPos: 1, rotate: 90},  //打印code128条码,高为60,rotate旋转角度(0/90/180/270), textPos是否显示可读字符(0/1)
      { type: 'image', width:120, height:120, x:320, y:180, content: imgStr }  //打印图片, content需要为base64格式的图片数据
    ]
}

5. 使用可视化模板数据打印

5.1 该方式是使用模板化的数据,将布局数据转化为图片,然后进行图片打印。该方式消除了不同打印机厂商对指令实现的差异造成的异常,使不同打印机之间打印效果一致。

配合可视化的 "模板编辑器" http://47.107.85.113:81/label-editor/index.html, 可以快速的实现复杂的标签布局。标签编辑完成后,只需要将业务数据进行填充(替换布局元素的content字段)即可直接使用。改编辑器可以提供系统集成服务,欢迎洽谈!

5.2 ESC方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'esc',
  data: [
    { type: 'template', json: jsonStr, imageCmd: 0}, //如果条码、二维码、横线,图片异常,请尝试将imageCmd修改为1
  ],
}

5.3 CPCL方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'cpcl',
  data: [
    { type: 'template', json: jsonStr}, //如果条码、二维码、横线,图片异常,请尝试将imageCmd修改为1
  ],
}

5.4 TSPL方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'tspl',
  data: [
    { type: 'template', json: jsonStr, imageCmd: 0}, //如果条码、二维码、横线,图片异常,请尝试将imageCmd修改为1
  ],
}

5.5 商米标签方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'sunmi_label',
  data: [
    {type: 'setup', width:590, height: 620},
    {type:"image",width:80,height:80, posY:10,posX:10, json: jsonStr, heightAdjust:false }, //heightAdjust为true时,会重新调整高度以适应实际内容高度
    {type:"print", value:1}
  ],
}

5.6 商米小票方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'sunmi_ticket',
  data: [
    {type: 'setup', width:590, height: 620, align:1},
    {type:"image",width:80,height:80, x:10, y:10, json: jsonStr, heightAdjust:false }, //heightAdjust为true时,会重新调整高度以适应实际内容高度
    {type:"print"}
  ],
}

5.6 ZPL方式


let jsonStr = '我是模板数据,需要替换为填充业务数据后真正的json字符串';
let jsonData = {
  cmdType: 'zpl',
  data: [
    { type: 'template', json: jsonStr, imageCmd: 0}, //如果条码、二维码、横线,图片异常,请尝试将imageCmd修改为1
  ],
}

6. 联系方式

需要咨询的朋友也可以添加作者企鹅:‌壹‌壹‌玖贰玖‌陆零‌柒‌玖‌捌。或者v信: ‌壹‌伍‌捌‌壹‌肆零‌叁‌贰‌玖‌陆‌玖,获得更快捷的服务支持。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android:需要授予蓝牙权限 IOS:不支持

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问