網上關於通過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 * @return 109 */ 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 * @return 123 */ 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 * @return 140 */ 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 * @return 154 */ 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 * @return 168 */ 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 col 182 * @return 183 */ 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 num 199 * @return 200 */ 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 num 237 * @return 238 */ 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 * @return 255 */ 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 * @return 270 */ 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 }
工具庫包括字體加粗、字體放大縮小、切紙、換行等基本操作,還有就是對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、參考文章