Java直接控制打印机打印

我们是一家专业做酒店餐饮软件的公司,餐饮软件一个重要的功能就是后厨打印问题,前台点菜完毕,后厨立刻打印出单子,这样就减少人工递单的麻烦,节省时间,提高翻台率。这种信息化解决方案对打印技术要求很高,理论上最好 100% 不丢单,也就是每次点菜后厨都会相应出单子,但是实际上行不通,为什么呢?因为网线、打印机、网卡等都有可能有问题,别说打印机等硬件因为厨房油烟问题损坏,我们甚至碰到过网线被老鼠咬断的情况,总之硬件网络故障防不胜防,所以只能退而求其次,就是有问题不可怕,程序能够判断是否出了问题,并能给出提示,便于服务员处理,及时补单。

   如果我们用安装 Windows 驱动的方法来实现后厨打印,那么肯定是不行的,因为我们只能单向向驱动程序抛包,不能从驱动程序获得任何返回值,没有办法了解是否打印成功,而且经过验证后发现,热敏打印机驱动打印时速度上非常慢。而且更为严重的是,有时候因为后厨打印机过多,Windows 驱动甚至会因为网络堵塞自作主张将包丢弃,没有任何提示。这在行业应用中是不行的,会给用户带来损失,所以想到了绕过 Windows 驱动,直接写端口的方法。

  1     package com.common.util.portprinter;  
  2       
  3     import java.io.IOException;  
  4     import java.io.OutputStream;  
  5       
  6     import com.common.util.PrinterParameterConf;  
  7       
  8     /** 
  9      * @author ChenMing 
 10      * 
 11      */  
 12     public class PortPrinterBase {  
 13         private OutputStream out;  
 14         protected int lineCount = 40;  
 15         private String printType="0";  
 16         public PortPrinterBase(OutputStream out, String printType){  
 17             this.out = out;  
 18             this.printType = printType;  
 19             initPrinter();  
 20             String lineCountStr = PrinterParameterConf.printerParameterConf.getProperty(PrinterParameterConf.LINEPRINTERCHARCOUNT_NAME);  
 21             try{  
 22                 int temp = Integer.parseInt(lineCountStr);  
 23                 this.lineCount = temp;  
 24             }catch(Exception e){      
 25             }  
 26         }  
 27         protected final String LEFT = "LEFT";  
 28         protected final String CENTER = "CENTER";  
 29         protected final String RIGHT = "RIGHT";  
 30         public static final byte HT = 0x9;  
 31         public static final byte LF = 0x0A;  
 32         public static final byte CR = 0x0D;  
 33         public static final byte ESC = 0x1B;  
 34         public static final byte DLE = 0x10;  
 35         public static final byte GS = 0x1D;  
 36         public static final byte FS = 0x1C;  
 37         public static final byte STX = 0x02;  
 38         public static final byte US = 0x1F;  
 39         public static final byte CAN = 0x18;  
 40         public static final byte CLR = 0x0C;  
 41         public static final byte EOT = 0x04;  
 42           
 43         /* 初始化打印机 */   
 44         public static final byte[] ESC_INIT = new byte[] {ESC, '@'};  
 45         /* 设置标准模式 */  
 46         public static final byte[] ESC_STANDARD = new byte[] {ESC, 'S'};  
 47         /* 设置汉字打印模式 */  
 48         public static final byte[] ESC_CN_FONT = new byte[] {FS, '&'};  
 49         /* 选择字符集 */  
 50         public static final byte[] ESC_SELECT_CHARACTER = new byte[] {ESC, 'R', 9};  
 51         /* 设置用户自定义汉字字体 焗7118 */  
 52         public static final byte[] ESC_FS_2 = new byte[] {FS, 0x32, 0x71, 0x18};  
 53         /* 取消用户自定义字体 */  
 54         public static final byte[] ESC_CANCEL_DEFINE_FONT = new byte[]{ESC, '%', 0};  
 55         /* 打开钱箱指令 */   
 56         public static final byte[] ESC_OPEN_DRAWER = new byte[]{ESC, 'p', 0x00, 0x10, (byte) 0xff};  
 57         /* 切纸指令GS V m    
 58         * m  0,48 Executes a full cut(cuts the paper completely) 
 59         *    1,49 Excutes a partilal cut(one point left uncut) 
 60         */   
 61        public static final byte[] POS_CUT_MODE_FULL = new byte[]{GS, 'V', 0x00};  
 62        public static final byte[] POS_CUT_MODE_PARTIAL = new byte[]{GS, 'V', 0x01};  
 63         /* 西文字符 (半宽)字体A (6 ×12),汉字字符 (全宽)字体A (12×12) */   
 64         public static final byte[] ESC_FONT_A = new byte[]{ESC, '!', 0};  
 65         /* 西文字符 (半宽)字体B (8×16),汉字字符 (全宽)字体B (16×16) */   
 66         public static final byte[] ESC_FONT_B = new byte[]{ESC, '!', 1};  
 67         /* 12*24   0/48*/  
 68         public static final byte[] ESC_FONTA= new byte[]{ESC, 'M', 48};  
 69         /* 9*17    1/49*/  
 70         public static final byte[] ESC_FONTB= new byte[]{ESC, 'M', 1};  
 71         /* 默认颜色字体指令 */   
 72         public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[] {ESC, 'r', 0x00};  
 73         /* 红色字体指令 */   
 74         public static final byte[] ESC_FONT_COLOR_RED = new byte[] {ESC, 'r', 0x01 };  
 75         /* 标准大小 */   
 76         public static final byte[] FS_FONT_ALIGN = new byte[]{FS, 0x21, 1, ESC, 0x21, 1};   
 77         /* 横向放大一倍 */   
 78         public static final byte[] FS_FONT_ALIGN_DOUBLE = new byte[]{FS, 0x21, 4, ESC, 0x21, 4};   
 79         /* 纵向放大一倍 */   
 80         public static final byte[] FS_FONT_VERTICAL_DOUBLE = new byte[]{FS, 0x21, 8, ESC, 0x21, 8, GS, '!', 0x01};   
 81         /* 横向纵向都放大一倍 */   
 82         public static final byte[] FS_FONT_DOUBLE = new byte[]{FS, 0x21, 12, ESC, 0x21, 48};   
 83         /* 靠左打印命令 */   
 84         public static final byte[] ESC_ALIGN_LEFT = new byte[]{0x1b,'a', 0x00};  
 85         /* 居中打印命令 */   
 86         public static final byte[] ESC_ALIGN_CENTER = new byte[]{0x1b,'a', 0x01};  
 87         /* 靠右打印命令 */   
 88         public static final byte[] ESC_ALIGN_RIGHT = new byte[]{0x1b,'a', 0x02};  
 89         /* 字体加粗 */  
 90         public static final byte[] ESC_SETTING_BOLD = new byte[]{ESC, 0x45, 1};  
 91         /* 取消字体加粗 */  
 92         public static final byte[] ESC_CANCEL_BOLD = new byte[]{ESC, 0x45, 0};  
 93         //DLE EOT n 实时状态传送  
 94         //如果返回结果为22  
 95         /** 
 96          * 、DLE EOT n 实时状态传送 
 97             [格式] ASCII码 DLE EOT n 
 98             十六进制码 10 04 n 
 99             十进制码 16 4 n 
100             [范围] 1 ≤ n ≤ 4 
101             [描述] 根据下列参数,实时传送打印机状态,参数 n 用来指定所要传送的打印机状态: 
102             n = 1:传送打印机状态 
103             n = 2:传送脱机状态 
104             n = 3:传送错误状态 
105             n = 4:传送纸传感器状态 
106             [注释] 打印机收到该命令后立即返回相关状态 
107             该命令尽量不要插在2个或更多字节的命令序列中。 
108             即使打印机被ESC =(选择外设)命令设置为禁止,该命令依然有效。 
109             打印机传送当前状态,每一状态用1个字节数据表示。 
110             打印机传送状态时并不确认主机是否收到。 
111             打印机收到该命令立即执行。 
112             该命令只对串口打印机有效。打印机在任何状态下收到该命令都立即执行。 
113          */  
114         public static final byte[] PRINT_STATE_DLE_EOT = new byte[] {DLE, EOT,0x01};  
115           
116         public void initPrinter(){  
117             try {  
118                 //modify by gongqiyi 20090917   
119                 //ESC_INIT 将在清空缓存区的数据  
120                 //out.write(ESC_INIT);  
121                 //自定义字体  
122                 //out.write(ESC_FS_2);  
123                 out.write(ESC_STANDARD);  
124                 out.write(ESC_CANCEL_DEFINE_FONT);  
125                 out.write(ESC_FONTA);  
126                 out.write(ESC_SELECT_CHARACTER);  
127                 //进入汉字模式打印  
128                 //out.write(ESC_CN_FONT);  
129                   
130                   
131                 //out.write(ESC_FONT_B);  
132                 //out.write(ESC_FONTA);  
133             } catch (IOException e) {  
134                 e.printStackTrace();  
135             }  
136         }  
137         /** 
138          * 走纸到切纸位置并切纸 
139          */  
140         public void executeLineFeedAndPaperCut(){  
141             try {  
142                 out.write(PrinterParameterConf.printerParameterConf.getProperty  
143               (PrinterParameterConf.PRINTCUTLINE_NAME).getBytes());  
144                 out.write(POS_CUT_MODE_PARTIAL);  
145             } catch (IOException e) {  
146                 e.printStackTrace();  
147             }  
148         }  
149         /** 
150          * 单据头打印 
151          * @param str 
152          */  
153         public void billHeaderPrinter(String str){  
154             try {  
155                 out.write(ESC_ALIGN_CENTER);  
156                 out.write(FS_FONT_DOUBLE);  
157                 out.write((str+"\n").getBytes());  
158                 out.write(LF);  
159             } catch (IOException e) {  
160                 e.printStackTrace();  
161             }  
162         }  
163         /** 
164          * 叫单号打印 
165          * @param str 
166          */  
167         public void callNumPrinter(String str){  
168             try {  
169                 out.write(ESC_ALIGN_LEFT);  
170                 out.write(FS_FONT_DOUBLE);  
171                 out.write((str+"\n").getBytes());  
172             } catch (IOException e) {  
173                 e.printStackTrace();  
174             }  
175         }  
176         /** 
177          * 双倍大小字体 
178          * @param str 
179          */  
180         public void doubleSizePrinter(String str, String align){  
181             try {  
182                 if(CENTER.equals(align)){  
183                     out.write(ESC_ALIGN_LEFT);  
184                 }else if(RIGHT.equals(align)){  
185                     out.write(ESC_ALIGN_RIGHT);  
186                 }else{  
187                     out.write(ESC_ALIGN_LEFT);  
188                 }  
189                 out.write(FS_FONT_DOUBLE);  
190                 out.write((str+"\n").getBytes());  
191                 //out.write(LF);  
192             } catch (IOException e) {  
193                 e.printStackTrace();  
194             }  
195         }  
196         /** 
197          * 标准字体打印一行 
198          * @param str 需打印的字符串 
199          * @param align 打印的位置 LEFT/CENTER/RIGHT 其他为默认居左打印 
200          */  
201         public void standardPrinterLine(String str, String align){  
202             try{  
203                 if(CENTER.equals(align)){  
204                     out.write(ESC_ALIGN_CENTER);  
205                     out.write(FS_FONT_ALIGN);  
206                     out.write(ESC_CN_FONT);  
207                     out.write(ESC_CANCEL_BOLD);  
208                     if("1".equals(printType)){  
209                         out.write(ESC_FONTA);  
210                     }else{  
211                         out.write(ESC_FONT_B);  
212                     }  
213                     out.write(str.getBytes());  
214                 }else if(RIGHT.equals(align)){  
215                     out.write(ESC_ALIGN_RIGHT);  
216                     out.write(FS_FONT_ALIGN);  
217                     out.write(ESC_CN_FONT);  
218                     out.write(ESC_CANCEL_BOLD);  
219                     if("1".equals(printType)){  
220                         out.write(ESC_FONTA);  
221                     }else{  
222                         out.write(ESC_FONT_B);  
223                     }  
224                     out.write(str.getBytes());  
225                 }else{  
226                     out.write(ESC_ALIGN_LEFT);  
227                     out.write(FS_FONT_ALIGN);  
228                     out.write(ESC_CN_FONT);  
229                     out.write(ESC_CANCEL_BOLD);  
230                     if("1".equals(printType)){  
231                         out.write(ESC_FONTA);  
232                     }else{  
233                         out.write(ESC_FONT_B);  
234                     }  
235                     out.write(str.getBytes());  
236                 }  
237                 out.write("\n".getBytes());  
238             }catch(IOException e) {  
239                 e.printStackTrace();  
240             }  
241         }  
242       
243         /** 
244          * 标准粗体字体打印一行 
245          * @param str 需打印的字符串 
246          * @param align 打印的位置 LEFT/CENTER/RIGHT 其他为默认居左打印 
247          */  
248         public void standardBoldPrinterLine(String str, String align){  
249             try{  
250                 if(CENTER.equals(align)){  
251                     out.write(ESC_ALIGN_CENTER);  
252                     out.write(FS_FONT_ALIGN);  
253                     out.write(ESC_CN_FONT);  
254                     out.write(ESC_SETTING_BOLD);  
255                     if("1".equals(printType)){  
256                         out.write(ESC_FONTA);  
257                     }else{  
258                         out.write(ESC_FONT_B);  
259                     }  
260                     out.write(str.getBytes());  
261                 }else if(RIGHT.equals(align)){  
262                     out.write(ESC_ALIGN_RIGHT);  
263                     out.write(FS_FONT_ALIGN);  
264                     out.write(ESC_CN_FONT);  
265                     out.write(ESC_SETTING_BOLD);  
266                     if("1".equals(printType)){  
267                         out.write(ESC_FONTA);  
268                     }else{  
269                         out.write(ESC_FONT_B);  
270                     }  
271                     out.write(str.getBytes());  
272                 }else{  
273                     out.write(ESC_ALIGN_LEFT);  
274                     out.write(FS_FONT_ALIGN);  
275                     out.write(ESC_CN_FONT);  
276                     out.write(ESC_SETTING_BOLD);  
277                     if("1".equals(printType)){  
278                         out.write(ESC_FONTA);  
279                     }else{  
280                         out.write(ESC_FONT_B);  
281                     }  
282                     out.write(str.getBytes());  
283                 }  
284                 out.write("\n".getBytes());  
285             }catch(IOException e) {  
286                 e.printStackTrace();  
287             }  
288         }  
289       
290         /** 
291          * 双倍宽字体按行打印 
292          * @param str 
293          * @param align 
294          */  
295         public void largeSizePrinterLine(String str, String align){  
296             try{  
297                 if(CENTER.equals(align)){  
298                     out.write(ESC_ALIGN_CENTER);  
299                     out.write(FS_FONT_ALIGN_DOUBLE);  
300                     out.write(str.getBytes());  
301                 }else if(RIGHT.equals(align)){  
302                     out.write(ESC_ALIGN_RIGHT);  
303                     out.write(FS_FONT_ALIGN_DOUBLE);  
304                     out.write(str.getBytes());  
305                 }else{  
306                     out.write(ESC_ALIGN_LEFT);  
307                     out.write(FS_FONT_ALIGN_DOUBLE);  
308                     out.write(str.getBytes());  
309                 }  
310                 out.write("\n".getBytes());  
311             }catch(IOException e) {  
312                 e.printStackTrace();  
313             }  
314         }  
315           
316         /** 
317          * 双倍高字体按行打印 
318          * @param str 
319          * @param align 
320          */  
321         public void largeHSizePrinterLine(String str, String align){  
322             try{  
323                 if(CENTER.equals(align)){  
324                     out.write(ESC_ALIGN_CENTER);  
325                     out.write(FS_FONT_VERTICAL_DOUBLE);  
326                     out.write(str.getBytes());  
327                 }else if(RIGHT.equals(align)){  
328                     out.write(ESC_ALIGN_RIGHT);  
329                     out.write(FS_FONT_VERTICAL_DOUBLE);  
330                     out.write(str.getBytes());  
331                 }else{  
332                     out.write(ESC_ALIGN_LEFT);  
333                     out.write(FS_FONT_VERTICAL_DOUBLE);  
334                     out.write(str.getBytes());  
335                 }  
336                 out.write("\n".getBytes());  
337             }catch(IOException e) {  
338                 e.printStackTrace();  
339             }  
340         }    /** 
341          * 大号字体红色按行打印 
342          * @param str 
343          * @param align 
344          */  
345         public void largeSizeRedPrinterLine(String str, String align){  
346             try{  
347                 if(CENTER.equals(align)){  
348                     out.write(ESC_ALIGN_CENTER);  
349                     out.write(FS_FONT_ALIGN_DOUBLE);  
350                     out.write(ESC_FONT_COLOR_RED);  
351                     out.write(str.getBytes());  
352                 }else if(RIGHT.equals(align)){  
353                     out.write(ESC_ALIGN_RIGHT);  
354                     out.write(FS_FONT_ALIGN_DOUBLE);  
355                     out.write(ESC_FONT_COLOR_RED);  
356                     out.write(str.getBytes());  
357                 }else{  
358                     out.write(ESC_ALIGN_LEFT);  
359                     out.write(FS_FONT_ALIGN_DOUBLE);  
360                     out.write(ESC_FONT_COLOR_RED);  
361                     out.write(str.getBytes());  
362                 }  
363                 out.write("\n".getBytes());  
364             }catch(IOException e) {  
365                 e.printStackTrace();  
366             }  
367         }  
368         public void openDrawer(){  
369             try {  
370                 out.write(ESC_OPEN_DRAWER);  
371             } catch (IOException e) {  
372                 e.printStackTrace();  
373             }  
374         }  
375         public String makePrintString(int lineChars, String txt1, String txt2){  
376             if(txt1 == null){  
377                 txt1 = "";  
378             }  
379             if(txt2 == null){  
380                 txt2 = "";  
381             }  
382             int spaces = 0;  
383             String tab = "";  
384             try{  
385                 spaces = lineChars - (txt1.getBytes().length + txt2.getBytes().length);  
386                 for (int j = 0 ; j < spaces ; j++){  
387                     tab += " ";  
388                 }  
389             }catch(Exception e){  
390                 e.printStackTrace();  
391             }  
392             return txt1 + tab + txt2;  
393         }  
394         public String makePrintString(int lineChars, String txt1, String txt2, String txt3){  
395             if(txt1 == null){  
396                 txt1 = "";  
397             }  
398             if(txt2 == null){  
399                 txt2 = "";  
400             }  
401             if(txt3 == null){  
402                 txt3 = "";  
403             }  
404             int spaces = 0;  
405             int lineChars1 = lineChars*2/3;  
406             String tab = "";  
407             String returnStr = txt1;  
408             try{  
409                 spaces = lineChars1 - (returnStr.getBytes().length + txt2.getBytes().length);  
410                 for (int j = 0 ; j < spaces ; j++){  
411                     tab += " ";  
412                 }  
413                 returnStr = txt1 + tab + txt2;  
414                 spaces = lineChars - (returnStr.getBytes().length + txt3.getBytes().length);  
415                 tab = "";  
416                 for (int j = 0 ; j < spaces ; j++){  
417                     tab += " ";  
418                 }  
419                 returnStr = returnStr + tab + txt3;  
420             }catch(Exception e){  
421                 e.printStackTrace();  
422             }  
423             return returnStr;  
424         }  
425     }  
View Code

 

posted @ 2018-01-13 18:10  女侠的老公  阅读(2533)  评论(0编辑  收藏  举报