18、ESC/POS指令集在android设备上使用实例(通过socket)
16lz
2021-01-23
网上关于通过android来操作打印机的例子太少了,为了方便更多的开发同仁,将近日所学分享一下。
我这边是通过android设备通过无线来对打印机(佳博58mm热敏式-58130iC)操作,实现餐厅小票的打印。写了一个简单的小demo,分享下。
前提:
1、android设备一个(coolPad8085N)
2、小票打印机(佳博 58mm热敏式打印机-58130IC)
这里将打印机IP设置为固定IP(这里略微复杂,是前辈设置过的,我没有具体操作,问了一下:打印机自检出的条子可以显示IP、通过自带或者官网的window管理软件设置)
3、无线路由器一个(从局域网口引出一根网线接到小票打印机网口)
4、android设备连接wifi到同一网络
(这样就保证了android和打印机在同一网络内,并且打印机的IP是固定的,开发人员是知道的,很变态)
流程:
1、android运行app,根据打印机的IP地址和端口号创建套接字socket,得到可写流outputStream
2、根据订单号,获取订单信息(demo是模拟的)
3、套入模板,打印小票
难点在于小票的排版的实现,我做了个工具库,如下:
1 package com; 2 3 4 5 public class printerCmdUtils { 6 7 public static final byte ESC = 27;//换码 8 public static final byte FS = 28;//文本分隔符 9 public static final byte GS = 29;//组分隔符 10 public static final byte DLE = 16;//数据连接换码 11 public static final byte EOT = 4;//传输结束 12 public static final byte ENQ = 5;//询问字符 13 public static final byte SP = 32;//空格 14 public static final byte HT = 9;//横向列表 15 public static final byte LF = 10;//打印并换行(水平定位) 16 public static final byte CR = 13;//归位键 17 public static final byte FF = 12;//走纸控制(打印并回到标准模式(在页模式下) ) 18 public static final byte CAN = 24;//作废(页模式下取消打印数据 ) 19 20 21 22 //------------------------打印机初始化----------------------------- 23 24 25 /** 26 * 打印机初始化 27 * @return 28 */ 29 public static byte[] init_printer() 30 { 31 byte[] result = new byte[2]; 32 result[0] = ESC; 33 result[1] = 64; 34 return result; 35 } 36 37 38 //------------------------换行----------------------------- 39 40 41 /** 42 * 换行 43 * @param lineNum要换几行 44 * @return 45 */ 46 public static byte[] nextLine(int lineNum) 47 { 48 byte[] result = new byte[lineNum]; 49 for(int i=0;i<lineNum;i++) 50 { 51 result[i] = LF; 52 } 53 54 return result; 55 } 56 57 58 //------------------------下划线----------------------------- 59 60 61 /** 62 * 绘制下划线(1点宽) 63 * @return 64 */ 65 public static byte[] underlineWithOneDotWidthOn() 66 { 67 byte[] result = new byte[3]; 68 result[0] = ESC; 69 result[1] = 45; 70 result[2] = 1; 71 return result; 72 } 73 74 75 /** 76 * 绘制下划线(2点宽) 77 * @return 78 */ 79 public static byte[] underlineWithTwoDotWidthOn() 80 { 81 byte[] result = new byte[3]; 82 result[0] = ESC; 83 result[1] = 45; 84 result[2] = 2; 85 return result; 86 } 87 88 89 /** 90 * 取消绘制下划线 91 * @return 92 */ 93 public static byte[] underlineOff() 94 { 95 byte[] result = new byte[3]; 96 result[0] = ESC; 97 result[1] = 45; 98 result[2] = 0; 99 return result;100 }101 102 103 //------------------------加粗-----------------------------104 105 106 /**107 * 选择加粗模式108 * @return109 */110 public static byte[] boldOn()111 {112 byte[] result = new byte[3];113 result[0] = ESC;114 result[1] = 69;115 result[2] = 0xF;116 return result;117 }118 119 120 /**121 * 取消加粗模式122 * @return123 */124 public static byte[] boldOff()125 {126 byte[] result = new byte[3];127 result[0] = ESC;128 result[1] = 69;129 result[2] = 0;130 return result;131 }132 133 134 //------------------------对齐-----------------------------135 136 137 /**138 * 左对齐139 * @return140 */141 public static byte[] alignLeft()142 {143 byte[] result = new byte[3];144 result[0] = ESC;145 result[1] = 97;146 result[2] = 0;147 return result;148 }149 150 151 /**152 * 居中对齐153 * @return154 */155 public static byte[] alignCenter()156 {157 byte[] result = new byte[3];158 result[0] = ESC;159 result[1] = 97;160 result[2] = 1;161 return result;162 }163 164 165 /**166 * 右对齐167 * @return168 */169 public static byte[] alignRight()170 {171 byte[] result = new byte[3];172 result[0] = ESC;173 result[1] = 97;174 result[2] = 2;175 return result;176 }177 178 179 /**180 * 水平方向向右移动col列181 * @param col182 * @return183 */184 public static byte[] set_HT_position( byte col )185 {186 byte[] result = new byte[4];187 result[0] = ESC;188 result[1] = 68;189 result[2] = col;190 result[3] = 0;191 return result;192 }193 //------------------------字体变大-----------------------------194 195 196 /**197 * 字体变大为标准的n倍198 * @param num199 * @return200 */201 public static byte[] fontSizeSetBig(int num)202 {203 byte realSize = 0;204 switch (num)205 {206 case 1:207 realSize = 0;break;208 case 2:209 realSize = 17;break;210 case 3:211 realSize = 34;break;212 case 4:213 realSize = 51;break;214 case 5:215 realSize = 68;break;216 case 6:217 realSize = 85;break;218 case 7:219 realSize = 102;break;220 case 8:221 realSize = 119;break;222 }223 byte[] result = new byte[3];224 result[0] = 29;225 result[1] = 33;226 result[2] = realSize;227 return result;228 }229 230 231 //------------------------字体变小-----------------------------232 233 234 /**235 * 字体取消倍宽倍高236 * @param num237 * @return238 */239 public static byte[] fontSizeSetSmall(int num)240 {241 byte[] result = new byte[3];242 result[0] = ESC;243 result[1] = 33;244 245 return result;246 }247 248 249 //------------------------切纸----------------------------- 250 251 252 /**253 * 进纸并全部切割254 * @return255 */256 public static byte[] feedPaperCutAll()257 {258 byte[] result = new byte[4];259 result[0] = GS;260 result[1] = 86;261 result[2] = 65;262 result[3] = 0;263 return result;264 }265 266 267 /**268 * 进纸并切割(左边留一点不切)269 * @return270 */271 public static byte[] feedPaperCutPartial()272 {273 byte[] result = new byte[4];274 result[0] = GS;275 result[1] = 86;276 result[2] = 66;277 result[3] = 0;278 return result;279 }280 281 282 //------------------------切纸-----------------------------283 public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){ 284 byte[] byte_3 = new byte[byte_1.length+byte_2.length]; 285 System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length); 286 System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length); 287 return byte_3; 288 } 289 290 291 public static byte[] byteMerger(byte[][] byteList){ 292 293 int length = 0;294 for(int i=0;i<byteList.length;i++)295 {296 length += byteList[i].length;297 }298 byte[] result = new byte[length];299 300 int index = 0;301 for(int i=0;i<byteList.length;i++)302 {303 byte[] nowByte = byteList[i];304 for(int k=0;k<byteList[i].length;k++)305 {306 result[index] = nowByte[k];307 index++;308 }309 }310 for(int i =0;i<index;i++)311 {312 CommonUtils.LogWuwei("", "result["+i+"] is "+result[i]);313 }314 return result; 315 } 316 317 318 319 }View Code
工具库包括字体加粗、字体放大缩小、切纸、换行等基本操作,还有就是对byte数组的拼接,byte数组的拼接有很多方式,只实现了一种方式
效果图:
简单的代码解析:
public byte[] clientPaper() { try { byte[] next2Line = printerCmdUtils.nextLine(2); byte[] title = "出餐单(午餐)**万通中心店".getBytes("gb2312"); byte[] boldOn = printerCmdUtils.boldOn(); byte[] fontSize2Big = printerCmdUtils.fontSizeSetBig(3); byte[] center= printerCmdUtils.alignCenter(); byte[] Focus = "网 507".getBytes("gb2312"); byte[] boldOff = printerCmdUtils.boldOff(); byte[] fontSize2Small = printerCmdUtils.fontSizeSetSmall(3); byte[] left= printerCmdUtils.alignLeft(); byte[] orderSerinum = "订单编号:11234".getBytes("gb2312"); boldOn = printerCmdUtils.boldOn(); byte[] fontSize1Big = printerCmdUtils.fontSizeSetBig(2); byte[] FocusOrderContent = "韭菜鸡蛋饺子-小份(单)".getBytes("gb2312"); boldOff = printerCmdUtils.boldOff(); byte[] fontSize1Small = printerCmdUtils.fontSizeSetSmall(2); next2Line = printerCmdUtils.nextLine(2); byte[] priceInfo = "应收:22元 优惠:2.5元 ".getBytes("gb2312"); byte[] nextLine = printerCmdUtils.nextLine(1); byte[] priceShouldPay = "实收:19.5元".getBytes("gb2312"); nextLine = printerCmdUtils.nextLine(1); byte[] takeTime = "取餐时间:2015-02-13 12:51:59".getBytes("gb2312"); nextLine = printerCmdUtils.nextLine(1); byte[] setOrderTime = "下单时间:2015-02-13 12:35:15".getBytes("gb2312"); byte[] tips_1 = "微信关注\"**\"自助下单每天免1元".getBytes("gb2312"); nextLine = printerCmdUtils.nextLine(1); byte[] tips_2 = "饭后点评再奖5毛".getBytes("gb2312"); nextLine = printerCmdUtils.nextLine(1); byte[] breakPartial = printerCmdUtils.feedPaperCutPartial(); byte[][] cmdBytes= { title,nextLine, center,boldOn,fontSize2Big,Focus,boldOff,fontSize2Small,next2Line, left,orderSerinum,nextLine, center,boldOn,fontSize1Big,FocusOrderContent,boldOff,fontSize1Small,nextLine, left,next2Line, priceInfo,nextLine, priceShouldPay,next2Line, takeTime,nextLine, setOrderTime,next2Line, center,tips_1,nextLine, center,tips_2,next2Line, breakPartial }; return printerCmdUtils.byteMerger(cmdBytes); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
字节码拼接过程如下:
1 public static byte[] byteMerger(byte[][] byteList){ 2 3 int length = 0; 4 for(int i=0;i<byteList.length;i++) 5 { 6 length += byteList[i].length; 7 } 8 byte[] result = new byte[length]; 9 10 int index = 0;11 for(int i=0;i<byteList.length;i++)12 {13 byte[] nowByte = byteList[i];14 for(int k=0;k<byteList[i].length;k++)15 {16 result[index] = nowByte[k];17 index++;18 }19 }20 for(int i =0;i<index;i++)21 {22 CommonUtils.LogWuwei("", "result["+i+"] is "+result[i]);23 }24 return result; 25 }
将上步得到的字节码通过可写流写入套接字,这时小票打印机就会打印对应的内容。
1、demo链接地址如下:
http://pan.baidu.com/s/1eQ9y8mQ
2、参考文章
Java 实现 POS 打印机无驱打印
java 合并两个byte数组
小票打印机ESC/POS命令集
android 控制POS机图文打印(二)
更多相关文章
- 海创软件组--20200712--Butterknife与自定义图标字体
- Android特殊字体引入,以及描边和投影
- android webview字体大小的控制
- android中添加arial字体(非android默认字体)