ESC/POS指令集在Android设备上使用实例(通过socket)

http://www.it165.net/pro/html/201503/35460.html

网上关于通过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、套入模板,打印小票

难点在于小票的排版的实现,我做了个工具库,如下:


加载中...
view source print ?
001. 1 package com;
002. 2
003. 3
004. 4
005. 5 public class printerCmdUtils {
006. 6
007. 7     public static final byte ESC = 27;//换码
008. 8     public static final byte FS = 28;//文本分隔符
009. 9     public static final byte GS = 29;//组分隔符
010. 10     public static final byte DLE = 16;//数据连接换码
011. 11     public static final byte EOT = 4;//传输结束
012. 12     public static final byte ENQ = 5;//询问字符
013. 13     public static final byte SP = 32;//空格
014. 14     public static final byte HT = 9;//横向列表
015. 15     public static final byte LF = 10;//打印并换行(水平定位)
016. 16     public static final byte CR = 13;//归位键
017. 17     public static final byte FF = 12;//走纸控制(打印并回到标准模式(在页模式下) )
018. 18     public static final byte CAN = 24;//作废(页模式下取消打印数据 )
019. 19    
020. 20    
021. 21    
022. 22 //------------------------打印机初始化-----------------------------
023. 23    
024. 24    
025. 25     /**
026. 26      * 打印机初始化
027. 27      * @return
028. 28      */
029. 29     public static byte[] init_printer()
030. 30     {
031. 31         byte[] result = new byte[2];
032. 32         result[0] = ESC;
033. 33         result[1] = 64;
034. 34         return result;
035. 35     }
036. 36    
037. 37    
038. 38 //------------------------换行-----------------------------
039. 39  
040. 40    
041. 41     /**
042. 42      * 换行
043. 43      * @param lineNum要换几行
044. 44      * @return
045. 45      */
046. 46     public static byte[] nextLine(int lineNum)
047. 47     {
048. 48             byte[] result = new byte[lineNum];
049. 49             for(int i=0;i<lineNum;i++)
050. 50             {
051. 51                 result[i] = LF;
052. 52             }
053. 53            
054. 54             return result;
055. 55     }
056. 56    
057. 57
058. 58 //------------------------下划线-----------------------------   
059. 59    
060. 60    
061. 61     /**
062. 62      * 绘制下划线(1点宽)
063. 63      * @return
064. 64      */
065. 65     public static byte[] underlineWithOneDotWidthOn()
066. 66     {
067. 67             byte[] result = new byte[3];
068. 68         result[0] = ESC;
069. 69         result[1] = 45;
070. 70         result[2] = 1;
071. 71         return result;
072. 72     }
073. 73    
074. 74    
075. 75     /**
076. 76      * 绘制下划线(2点宽)
077. 77      * @return
078. 78      */
079. 79     public static byte[] underlineWithTwoDotWidthOn()
080. 80     {
081. 81             byte[] result = new byte[3];
082. 82         result[0] = ESC;
083. 83         result[1] = 45;
084. 84         result[2] = 2;
085. 85         return result;
086. 86     }
087. 87    
088. 88    
089. 89     /**
090. 90      * 取消绘制下划线
091. 91      * @return
092. 92      */
093. 93     public static byte[] underlineOff()
094. 94     {
095. 95             byte[] result = new byte[3];
096. 96         result[0] = ESC;
097. 97         result[1] = 45;
098. 98         result[2] = 0;
099. 99         return result;
100. 100     }
101. 101
102. 102    
103. 103 //------------------------加粗-----------------------------
104. 104 
105. 105    
106. 106     /**
107. 107      * 选择加粗模式
108. 108      * @return
109. 109      */
110. 110     public static byte[] boldOn()
111. 111     {
112. 112             byte[] result = new byte[3];
113. 113         result[0] = ESC;
114. 114         result[1] = 69;
115. 115         result[2] = 0xF;
116. 116         return result;
117. 117     }
118. 118    
119. 119    
120. 120     /**
121. 121      * 取消加粗模式
122. 122      * @return
123. 123      */
124. 124     public static byte[] boldOff()
125. 125     {
126. 126             byte[] result = new byte[3];
127. 127         result[0] = ESC;
128. 128         result[1] = 69;
129. 129         result[2] = 0;
130. 130         return result;
131. 131     }
132. 132
133. 133
134. 134 //------------------------对齐-----------------------------
135. 135   
136. 136    
137. 137     /**
138. 138      * 左对齐
139. 139      * @return
140. 140      */
141. 141     public static byte[] alignLeft()
142. 142     {
143. 143             byte[] result = new byte[3];
144. 144         result[0] = ESC;
145. 145         result[1] = 97;
146. 146         result[2] = 0;
147. 147         return result;
148. 148     }
149. 149    
150. 150    
151. 151     /**
152. 152      * 居中对齐
153. 153      * @return
154. 154      */
155. 155     public static byte[] alignCenter()
156. 156     {
157. 157             byte[] result = new byte[3];
158. 158         result[0] = ESC;
159. 159         result[1] = 97;
160. 160         result[2] = 1;
161. 161         return result;
162. 162     }
163. 163    
164. 164    
165. 165     /**
166. 166      * 右对齐
167. 167      * @return
168. 168      */
169. 169     public static byte[] alignRight()
170. 170     {
171. 171             byte[] result = new byte[3];
172. 172         result[0] = ESC;
173. 173         result[1] = 97;
174. 174         result[2] = 2;
175. 175         return result;
176. 176     }
177. 177
178. 178    
179. 179     /**
180. 180      * 水平方向向右移动col列
181. 181      * @param col
182. 182      * @return
183. 183      */
184. 184     public static byte[] set_HT_position( byte col )
185. 185     {
186. 186         byte[] result = new byte[4];
187. 187         result[0] = ESC;
188. 188         result[1] = 68;
189. 189         result[2] = col;
190. 190         result[3] = 0;
191. 191         return result;
192. 192     }
193. 193 //------------------------字体变大-----------------------------
194. 194 
195. 195    
196. 196     /**
197. 197      * 字体变大为标准的n倍
198. 198      * @param num
199. 199      * @return
200. 200      */
201. 201     public static byte[] fontSizeSetBig(int num)
202. 202     {
203. 203             byte realSize = 0;
204. 204             switch (num)
205. 205             {
206. 206             case 1:
207. 207                 realSize = 0;break;
208. 208             case 2:
209. 209                 realSize = 17;break;
210. 210             case 3:
211. 211                 realSize = 34;break;
212. 212             case 4:
213. 213                 realSize = 51;break;
214. 214             case 5:
215. 215                 realSize = 68;break;
216. 216             case 6:
217. 217                 realSize = 85;break;
218. 218             case 7:
219. 219                 realSize = 102;break;
220. 220             case 8:
221. 221                 realSize = 119;break;
222. 222             }
223. 223             byte[] result = new byte[3];
224. 224             result[0] = 29;
225. 225             result[1] = 33;
226. 226             result[2] = realSize;
227. 227             return result;
228. 228     }
229. 229
230. 230    
231. 231 //------------------------字体变小-----------------------------
232. 232 
233. 233    
234. 234     /**
235. 235      * 字体取消倍宽倍高
236. 236      * @param num
237. 237      * @return
238. 238      */
239. 239     public static byte[] fontSizeSetSmall(int num)
240. 240     {
241. 241             byte[] result = new byte[3];
242. 242             result[0] = ESC;
243. 243             result[1] = 33;
244. 244        
245. 245         return result;
246. 246     }
247. 247
248. 248
249. 249 //------------------------切纸-----------------------------   
250. 250  
251. 251    
252. 252     /**
253. 253      * 进纸并全部切割
254. 254      * @return
255. 255      */
256. 256     public static byte[] feedPaperCutAll()
257. 257     {
258. 258              byte[] result = new byte[4];
259. 259          result[0] = GS;
260. 260          result[1] = 86;
261. 261          result[2] = 65;
262. 262          result[3] = 0;
263. 263          return result;
264. 264     }
265. 265    
266. 266    
267. 267     /**
268. 268      * 进纸并切割(左边留一点不切)
269. 269      * @return
270. 270      */
271. 271     public static byte[] feedPaperCutPartial()
272. 272     {
273. 273              byte[] result = new byte[4];
274. 274          result[0] = GS;
275. 275          result[1] = 86;
276. 276          result[2] = 66;
277. 277          result[3] = 0;
278. 278          return result;
279. 279     }
280. 280
281. 281    
282. 282 //------------------------切纸-----------------------------
283. 283     public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){ 
284. 284         byte[] byte_3 = new byte[byte_1.length+byte_2.length]; 
285. 285         System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length); 
286. 286         System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length); 
287. 287         return byte_3; 
288. 288     
289. 289    
290. 290    
291. 291     public static byte[] byteMerger(byte[][] byteList){ 
292. 292        
293. 293             int length = 0;
294. 294         for(int i=0;i<byteList.length;i++)
295. 295         {
296. 296                 length += byteList[i].length;
297. 297         }
298. 298         byte[] result = new byte[length];
299. 299        
300. 300         int index = 0;
301. 301         for(int i=0;i<byteList.length;i++)
302. 302         {
303. 303                 byte[] nowByte = byteList[i];
304. 304                 for(int k=0;k<byteList[i].length;k++)
305. 305                 {
306. 306                     result[index] = nowByte[k];
307. 307                     index++;
308. 308                 }
309. 309         }
310. 310         for(int i =0;i<index;i++)
311. 311         {
312. 312                 CommonUtils.LogWuwei('''result['+i+'] is '+result[i]);
313. 313         }
314. 314         return result; 
315. 315     
316. 316    
317. 317 
318. 318    
319. 319 }

工具库包括字体加粗、字体放大缩小、切纸、换行等基本操作,还有就是对byte数组的拼接,byte数组的拼接有很多方式,只实现了一种方式

效果图:

ESC/POS指令集在Android设备上使用实例(通过socket)_第1张图片

简单的代码解析:

view source print ?
01. public byte[] clientPaper()
02. {
03.  
04. try {
05. byte[] next2Line = printerCmdUtils.nextLine(2);
06. byte[] title = '出餐单(午餐)**万通中心店'.getBytes('gb2312');
07.  
08. byte[] boldOn = printerCmdUtils.boldOn();
09. byte[] fontSize2Big = printerCmdUtils.fontSizeSetBig(3);
10. byte[] center= printerCmdUtils.alignCenter();
11. byte[] Focus = '网 507'.getBytes('gb2312');
12. byte[] boldOff = printerCmdUtils.boldOff();
13. byte[] fontSize2Small = printerCmdUtils.fontSizeSetSmall(3);
14.  
15. byte[] left= printerCmdUtils.alignLeft();
16. byte[] orderSerinum = '订单编号:11234'.getBytes('gb2312');
17. boldOn = printerCmdUtils.boldOn();
18. byte[] fontSize1Big = printerCmdUtils.fontSizeSetBig(2);
19. byte[] FocusOrderContent = '韭菜鸡蛋饺子-小份(单)'.getBytes('gb2312');
20. boldOff = printerCmdUtils.boldOff();
21. byte[] fontSize1Small = printerCmdUtils.fontSizeSetSmall(2);
22.  
23.  
24. next2Line = printerCmdUtils.nextLine(2);
25.  
26. byte[] priceInfo = '应收:22元 优惠:2.5元 '.getBytes('gb2312');
27. byte[] nextLine = printerCmdUtils.nextLine(1);
28.  
29. byte[] priceShouldPay = '实收:19.5元'.getBytes('gb2312');
30. nextLine = printerCmdUtils.nextLine(1);
31.  
32. byte[] takeTime = '取餐时间:2015-02-13 12:51:59'.getBytes('gb2312');
33. nextLine = printerCmdUtils.nextLine(1);
34. byte[] setOrderTime = '下单时间:2015-02-13 12:35:15'.getBytes('gb2312');
35.  
36. byte[] tips_1 = '微信关注'**'自助下单每天免1元'.getBytes('gb2312');
37. nextLine = printerCmdUtils.nextLine(1);
38. byte[] tips_2 = '饭后点评再奖5毛'.getBytes('gb2312');
39. nextLine = printerCmdUtils.nextLine(1);
40.  
41. byte[] breakPartial = printerCmdUtils.feedPaperCutPartial();
42.  
43. byte[][] cmdBytes= {
44. title,nextLine,
45. center,boldOn,fontSize2Big,Focus,boldOff,fontSize2Small,next2Line,
46. left,orderSerinum,nextLine,
47. center,boldOn,fontSize1Big,FocusOrderContent,boldOff,fontSize1Small,nextLine,
48. left,next2Line,
49. priceInfo,nextLine,
50. priceShouldPay,next2Line,
51. takeTime,nextLine,
52. setOrderTime,next2Line,
53. center,tips_1,nextLine,
54. center,tips_2,next2Line,
55. breakPartial
56. };
57.  
58. return printerCmdUtils.byteMerger(cmdBytes);
59.  
60. catch (UnsupportedEncodingException e) {
61. // TODO Auto-generated catch block
62. e.printStackTrace();
63. }
64. return null;
65. }

字节码拼接过程如下:

view source print ?
01. 1  public static byte[] byteMerger(byte[][] byteList){ 
02. 2        
03. 3             int length = 0;
04. 4         for(int i=0;i<byteList.length;i++)
05. 5         {
06. 6                 length += byteList[i].length;
07. 7         }
08. 8         byte[] result = new byte[length];
09. 9        
10. 10         int index = 0;
11. 11         for(int i=0;i<byteList.length;i++)
12. 12         {
13. 13                 byte[] nowByte = byteList[i];
14. 14                 for(int k=0;k<byteList[i].length;k++)
15. 15                 {
16. 16                     result[index] = nowByte[k];
17. 17                     index++;
18. 18                 }
19. 19         }
20. 20         for(int i =0;i<index;i++)
21. 21         {
22. 22                 CommonUtils.LogWuwei('''result['+i+'] is '+result[i]);
23. 23         }
24. 24         return result; 
25. 25     }

将上步得到的字节码通过可写流写入套接字,这时小票打印机就会打印对应的内容。

1、demo链接地址如下:

http://pan.baidu.com/s/1eQ9y8mQ

你可能感兴趣的:(ESC/POS指令集在Android设备上使用实例(通过socket))