条形码打印

您所在的位置:网站首页 小票打印机怎样打印标签 条形码打印

条形码打印

2023-08-10 19:54| 来源: 网络整理| 查看: 265

         最近美团出餐宝要求服务商支持在小票上显示订单一维码信息,时间很赶,抓紧行动。由于我们有多个项目与打印相关。用到的打印机有驱动打印机,网口打印机,蓝牙打印机。不用惊讶,驱动打印机是用于delphi开发的桌面项目。开发的时候,找资料花了很长时间,完全把一维码的生成规则弄明白后,才解决了驱动机打印小票的问题。用delphi的人并不多,我还是先写安卓连接网口打印机和蓝牙打印机打印二维码吧。

 此段代码为条形码转换方式

public class OneDimensionUtil { private static String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static int scale = 62; /** * 数字转62进制 */ private static String encode(long num) { Long newNum = num; StringBuilder sb = new StringBuilder(); int remainder; while (newNum > scale - 1) { //对 scale 进行求余,然后将余数追加至 sb 中,由于是从末位开始追加的,因此最后需要反转字符串 remainder = (int) (newNum % scale); sb.append(chars.charAt(remainder)); //除以进制数,获取下一个末尾数 newNum /= scale; } sb.append(chars.charAt(Integer.parseInt(String.valueOf(newNum)))); return sb.toString(); } /** * 添加平台标志M前缀 */ public static String encodeM(long num) { return "M" + encode(num); } }

打印相关命令如下:

package com.yx.printerexec.bluetoothsdk; /** * author : dawn * e-mail : [email protected] * date : 2021/5/8 15:07 * desc : 打印命令 */ public class CommandConstants { /** * 复位打印机 */ public static byte[] RESET = new byte[]{0x1b, 0x40}; /** * 左对齐 */ public static byte[] ALIGN_LEFT = new byte[]{0x1b, 0x61, 0x00}; /** * 中间对齐 */ public static byte[] ALIGN_CENTER = new byte[]{0x1b, 0x61, 0x01}; /** * 右对齐 */ public static byte[] ALIGN_RIGHT = new byte[]{0x1b, 0x61, 0x02}; /** * 选择加粗模式 */ public static byte[] BOLD = new byte[]{0x1b, 0x45, 0x01}; /** * 取消加粗模式 */ public static byte[] BOLD_CANCEL = new byte[]{0x1b, 0x45, 0x00}; /** * 宽高加倍 */ public static byte[] DOUBLE_HEIGHT_WIDTH = new byte[]{0x1d, 0x21, 0x11}; /** * 宽加倍 */ public static byte[] DOUBLE_WIDTH = new byte[]{0x1d, 0x21, 0x10}; /** * 高加倍 */ public static byte[] DOUBLE_HEIGHT = new byte[]{0x1d, 0x21, 0x01}; /** * 字体不放大 */ public static byte[] NORMAL = new byte[]{0x1d, 0x21, 0x00}; /** * 设置默认行间距 */ public static byte[] LINE_SPACING_DEFAULT = new byte[]{0x1b, 0x32}; /** * 设置条形码高 */ public static byte[] BAR_CODE_H = new byte[]{0x1d, 0x68,0x6e}; /** * 设置条形码宽 */ public static byte[] BAR_CODE_W = new byte[]{0x1d, 0x77, 0x3}; /** * 换行 */ public static byte[] WRAP = new byte[]{0x0A}; /** * 走纸(防止内容已打印,包含内容的纸张打印机未全部吐出来) */ public static byte[] PAPER_FEED = new byte[]{0x1b, 0x4a, (byte) 0x96}; /** * 切纸 */ public static byte[] PAPER_CUT = new byte[]{0x1d, 0x56, 0x00, 0x30}; }

 1)、android连接网口打印机

        如果是连接网口打印机的话,打印完一定要记得断开连接,否则会导致一直占用其他的程序没有办法正常连接。    

 2)、android连接蓝牙打印机

这个方法里有一个outputStream 有一个outputStream,如果能用蓝牙打印机连接打印,应该知道怎么来的吧。我就直接略过了。只要蓝牙设备连接成功,就会有一个 BluetoothSocket 。

这两种打印机只是连接方式不一样,发送编码的方式完全相同

java发送指令部分   CODE B

/** * 设置打印格式 * * @param command 格式指令 */ public void selectCommand(byte[] command) { try { outputStream.write(command); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } private void printBarCode(String content) { selectCommand(CommandConstants.BAR_CODE_W);//设置条码的宽 selectCommand(CommandConstants.BAR_CODE_H);//设置条码的高度 byte[] headerBytes = new byte[]{29, 107, 73, 00, 123, 66}; byte[] contentByteArray = createByteCode(content); headerBytes[3] = (byte) (contentByteArray.length + headerBytes.length - 4); byte[] bytes = new byte[headerBytes.length + contentByteArray.length]; System.arraycopy(headerBytes, 0, bytes, 0, headerBytes.length); System.arraycopy(contentByteArray, 0, bytes, headerBytes.length, contentByteArray.length); selectCommand(bytes); } private byte[] createByteCode(String content) { byte[] arr = new byte[content.length()]; for (int i = 0; i < content.length(); i++) { arr[i] = (byte) content.charAt(i); } return arr; }

 Kotlin发送指令部分:CODE C

/** * 打印条形码 *设置其他值参考ESC/POS指令手册 * * @param content 条码内容 * @param w 指定条码宽 默认:3 * @param h 指定条码高 默认:162 */ fun printBarCode(content: String, w: Int = 3, h: Int = 162) { try { val width = byteArrayOf(0X1D, 0X77, w.toByte()) val height = byteArrayOf(0X1D, 0X68, h.toByte()) selectCommand(width)//设置条码的宽 selectCommand(height)//设置条码的高度 val formats = byteArrayOf(29, 107, 73, 0, 123, 66, 78, 111, 46, 123, 67) val contentByteArray = splitText(content) formats[3] = (contentByteArray.size + 7).toByte() val bytes = ByteArray(formats.size + contentByteArray.size) System.arraycopy(formats, 0, bytes, 0, formats.size) System.arraycopy(contentByteArray, 0, bytes, formats.size, contentByteArray.size) selectCommand(bytes) } catch (e: IOException) { e.printStackTrace() } }

/** * 按照两位分割字符串 */ private fun splitText(content: String): ByteArray { val sb = StringBuffer(content) var count = 0 for (i in content.indices) { val index = i + 1 //如果下标是偶数数则加入特殊字符 if (index % 2 == 0 && index != content.length) { sb.insert(index + count, "&") count++ } } val split = sb.toString().split("&") val byteArray = ByteArray(split.size) for (i in split.indices) { byteArray[i] = split[i].toByte() } return byteArray }

=========================================================================

byte[] headerBytes = new byte[]{29, 107, 73, 00, 123, 66};

应该有人对这句代码有疑惑,待我解释一下。 这还要从我从官网下载下来的编程手册说起。写打印功能的同行,应该对《XP-80X中文编程手册》不陌生。里面关于打印条形码是这么说的。条码类型很多,我只选择了我所熟悉的CODE128

                          

Code128 A码可表示:大写英文字母、数字、控制字符组成的字符串,比如:ABC、ABC123。

Code128 B码可表示:大小写英文字母、数字、字符组成的字符串,比如:Abc123、A-123(B)。

Code128 C码可表示:仅可表示100个“两位”数字编码(00-99),比如:123456、00225869。

 

一般来说,如果条码内容是大写英文字母,用Code128 A码或B码都可以,如果是包含大小写字母就需要用Code128 B码,如果是纯数字的一般用C码。在这里有一点需要注意的是,如果是条码内容位数是“奇数”的纯数字,那么就需要把条码内容给拆分,前面偶数用Code128 C码,后面一位奇数用B码或者A码。比如条码:1234567

拆分后,12、34、56是Code128 C码:,而最后一位7就是B码或者A码。在实际应用中Code 128 A码、Code128 B码和Code128 C码是可以相互组合的。

数据位可以只使用CODE B 编码,也可以只使用CODE C编码,也可以混合编码。需要注意的是,转换编码前需要提前说一下,也就是在真实数据前,注明编码。

混合编码方式:如M15202145

 

 CODE B 编码方式:

  CODE C 编码方式:

 注明一下:以上三张图只是声明传值格式,数据位的内容是随机写的。大家对照着上面的例子看,希望能有所帮助。

      至于要验证从字符转换为编码后是否正确,自行参考https://blog.csdn.net/weixin_30654419/article/details/95916713

    

参考:

https://jingyan.baidu.com/article/b907e6270f790906e6891c14.html   

Code128一维条码中A码、B码、C码的区别



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3