Java调用Zebra条码打印机打印条码、中英文数字条码混合标签,可自由控制格式和排版(2)

上一篇文章中介绍了Java调用条码打印机的相关方法,但是在实际生产环境中发现了一些问题,于是在此给出解决办法。

上一个Demo存在的一些问题包括:

1.打印浓度和宽度必须在打印机控制面板设置;

2.主机新添加的打印机获取不到;

3.严重:当某些中文字符无法打印时会终止程序。

4.添加了一个getMessage方法来获取打印结果。

第一个问题,只要在打印指令中加入~SDa和^PWa来控制打印深度和宽度即可。

第二个问题我采用了多种方法均无效,最终在一篇文章中偶然提到的一个在PrintServiceLookup.lookupPrintServices之前执行AppContext.getAppContext().put(PrintServiceLookup.class.getDeclaredClasses()[0], null)就能够解决问题。

第三个问题,通过try...catch捕获异常,并且替换掉这个无法打印的字符就行了。

完整的Demo如下

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.IOException;  
  4. import java.io.UnsupportedEncodingException;  
  5.   
  6. import javax.print.Doc;  
  7. import javax.print.DocFlavor;  
  8. import javax.print.DocPrintJob;  
  9. import javax.print.PrintException;  
  10. import javax.print.PrintService;  
  11. import javax.print.PrintServiceLookup;  
  12. import javax.print.SimpleDoc;  
  13. import javax.print.attribute.standard.PrinterName;  
  14.   
  15. import sun.awt.AppContext;  
  16. /** 
  17.  * 采用点阵字库ts24.lib 
  18.  * @author Labrador 
  19.  * 
  20.  */  
  21. public class ZplPrinter {  
  22.     private String printerURI = null;           //打印机完整路径  
  23.     private PrintService printService = null;   //打印机服务  
  24.     private byte[] dotFont;  
  25.     private String darkness = "~SD22";  //Set Darkness设置色带颜色的深度 0-30  
  26.     private String width = "^PW1200";   //Print Width打印宽度0-1500  
  27.     private String length = "^LL800";   //Label Length标签长度0-x(暂无作用)  
  28.     private String begin = "^XA" + darkness + width;    //标签格式以^XA开始  
  29.     private String end = "^XZ";         //标签格式以^XZ结束  
  30.     private String content = "";        //打印内容  
  31.     private String message = "";        //打印的结果信息  
  32.   
  33.     /** 
  34.      * 构造方法 
  35.      * @param printerURI 打印机路径 
  36.      */  
  37.     public ZplPrinter(String printerURI){  
  38.         this.printerURI = printerURI;  
  39.         //加载字体  
  40.         File file = new File("C://ts24.lib");  
  41.         if(file.exists()){  
  42.             FileInputStream fis;  
  43.             try {  
  44.                 fis = new FileInputStream(file);  
  45.                 dotFont = new byte[fis.available()];  
  46.                 fis.read(dotFont);  
  47.                 fis.close();  
  48.             } catch (IOException e) {  
  49.                 e.printStackTrace();  
  50.             }  
  51.         }else{  
  52.             System.out.println("C://ts24.lib文件不存在");  
  53.         }  
  54.         //初始化打印机  
  55.         AppContext.getAppContext().put(PrintServiceLookup.class.getDeclaredClasses()[0], null);//刷新打印机列表  
  56.         PrintService[] services = PrintServiceLookup.lookupPrintServices(null,null);  
  57.         if (services != null && services.length > 0) {  
  58.             for (PrintService service : services) {  
  59.                 if (printerURI.equals(service.getName())) {  
  60.                     printService = service;  
  61.                     break;  
  62.                 }  
  63.             }  
  64.         }  
  65.         if (printService == null) {  
  66.             System.out.println("没有找到打印机:["+printerURI+"]");  
  67.             //循环出所有的打印机  
  68.             if (services != null && services.length > 0) {  
  69.                 System.out.println("可用的打印机列表:");  
  70.                 for (PrintService service : services) {  
  71.                     System.out.println("["+service.getName()+"]");  
  72.                 }  
  73.             }  
  74.         }else{  
  75.             System.out.println("找到打印机:["+printerURI+"]");  
  76.             System.out.println("打印机名称:["+printService.getAttribute(PrinterName.class).getValue()+"]");  
  77.         }  
  78.     }  
  79.     /** 
  80.      * 设置条形码 
  81.      * @param barcode 条码字符 
  82.      * @param zpl 条码样式模板 
  83.      */  
  84.     public void setBarcode(String barcode,String zpl) {  
  85.         content += zpl.replace("${data}", barcode);  
  86.     }  
  87.   
  88.     /** 
  89.      * 中文字符、英文字符(包含数字)混合 
  90.      * @param str 中文、英文 
  91.      * @param x x坐标 
  92.      * @param y y坐标 
  93.      * @param eh 英文字体高度height 
  94.      * @param ew 英文字体宽度width 
  95.      * @param es 英文字体间距spacing 
  96.      * @param mx 中文x轴字体图形放大倍率。范围1-10,默认1 
  97.      * @param my 中文y轴字体图形放大倍率。范围1-10,默认1 
  98.      * @param ms 中文字体间距。24是个比较合适的值。 
  99.      */  
  100.     public void setText(String str, int x, int y, int eh, int ew, int es, int mx, int my, int ms) {  
  101.         byte[] ch = str2bytes(str);  
  102.         for (int off = 0; off < ch.length;) {  
  103.             if (((int) ch[off] & 0x00ff) >= 0xA0) {//中文字符  
  104.                 try {  
  105.                     int qcode = ch[off] & 0xff;  
  106.                     int wcode = ch[off + 1] & 0xff;  
  107.                     content += String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x, y, qcode, wcode, mx, my);  
  108.                     begin += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode);  
  109.                     qcode = (qcode + 128 - 32) & 0x00ff;  
  110.                     wcode = (wcode + 128 - 32) & 0x00ff;  
  111.                     int offset = ((int) qcode - 16) * 94 * 72 + ((int) wcode - 1) * 72;  
  112.                     for (int j = 0; j < 72; j += 3) {  
  113.                         qcode = (int) dotFont[j + offset] & 0x00ff;  
  114.                         wcode = (int) dotFont[j + offset + 1] & 0x00ff;  
  115.                         int qcode1 = (int) dotFont[j + offset + 2] & 0x00ff;  
  116.                         begin += String.format("%02X%02X%02X\n", qcode, wcode, qcode1);  
  117.                     }  
  118.                     x = x + ms * mx;  
  119.                     off = off + 2;  
  120.                 } catch (Exception e) {  
  121.                     e.printStackTrace();  
  122.                     //替换成X号  
  123.                     setChar("X", x, y, eh, ew);  
  124.                     x = x + es;//注意间距更改为英文字符间距  
  125.                     off = off + 2;  
  126.                 }  
  127.             } else if (((int) ch[off] & 0x00FF) < 0xA0) {//英文字符  
  128.                 setChar(String.format("%c", ch[off]), x, y, eh, ew);  
  129.                 x = x + es;  
  130.                 off++;  
  131.             }  
  132.         }  
  133.     }  
  134.     /** 
  135.      * 英文字符串(包含数字) 
  136.      * @param str 英文字符串 
  137.      * @param x x坐标 
  138.      * @param y y坐标 
  139.      * @param h 高度 
  140.      * @param w 宽度 
  141.      */  
  142.     public void setChar(String str, int x, int y, int h, int w) {  
  143.         content += "^FO" + x + "," + y + "^A0," + h + "," + w + "^FD" + str + "^FS";  
  144.     }  
  145.     /** 
  146.      * 英文字符(包含数字)顺时针旋转90度 
  147.      * @param str 英文字符串 
  148.      * @param x x坐标 
  149.      * @param y y坐标 
  150.      * @param h 高度 
  151.      * @param w 宽度 
  152.      */  
  153.     public void setCharR(String str, int x, int y, int h, int w) {  
  154.         content += "^FO" + x + "," + y + "^A0R," + h + "," + w + "^FD" + str + "^FS";  
  155.     }  
  156.     /** 
  157.      * 获取完整的ZPL 
  158.      * @return 
  159.      */  
  160.     public String getZpl() {  
  161.         return begin + content + end;  
  162.     }  
  163.     /** 
  164.      * 重置ZPL指令,当需要打印多张纸的时候需要调用。 
  165.      */  
  166.     public void resetZpl() {  
  167.         begin = "^XA" + darkness + width;  
  168.         end = "^XZ";  
  169.         content = "";  
  170.     }  
  171.     /** 
  172.      * 打印 
  173.      * @param zpl 完整的ZPL 
  174.      */  
  175.     public boolean print(String zpl){  
  176.         if(printService==null){  
  177.             message = "打印出错:没有找到打印机["+printerURI+"]";  
  178.             System.out.println("打印出错:没有找到打印机["+printerURI+"]");  
  179.             return false;  
  180.         }  
  181.         DocPrintJob job = printService.createPrintJob();  
  182.         byte[] by = zpl.getBytes();  
  183.         DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;  
  184.         Doc doc = new SimpleDoc(by, flavor, null);  
  185.         try {  
  186.             job.print(doc, null);  
  187.             message = "已打印";  
  188.             System.out.println("已打印");  
  189.             return true;  
  190.         } catch (PrintException e) {  
  191.             message = "打印出错:"+e.getMessage();  
  192.             System.out.println("打印出错:"+e.getMessage());  
  193.             e.printStackTrace();  
  194.             return false;  
  195.         }  
  196.     }  
  197.     public String getMessage(){  
  198.         return message;  
  199.     }  
  200.     /** 
  201.      * 字符串转byte[] 
  202.      * @param s 
  203.      * @return 
  204.      */  
  205.     private byte[] str2bytes(String s) {  
  206.         if (null == s || "".equals(s)) {  
  207.             return null;  
  208.         }  
  209.         byte[] abytes = null;  
  210.         try {  
  211.             abytes = s.getBytes("gb2312");  
  212.         } catch (UnsupportedEncodingException ex) {  
  213.             ex.printStackTrace();  
  214.         }  
  215.         return abytes;  
  216.     }  
  217. }  


测试main方法如下

扫描二维码关注公众号,回复: 576684 查看本文章
[java]  view plain  copy
  1. public class ZplPrinterTest {  
  2.     public static void main(String[] args) {  
  3.         ZplPrinter p = new ZplPrinter("\\\\10.10.13.235\\ZDesigner 105SLPlus-300dpi ZPL");  
  4. //      ZplPrinter p = new ZplPrinter("\\\\10.10.13.224\\ZDesigner GT800 (ZPL)");  
  5.           
  6. //      printBarcode(p);  
  7. //      p.resetZpl();//清除  
  8. //      printPicking300DPI(p);  
  9. //      p.resetZpl();//清除  
  10. //      printPicking203DPI(p);  
  11. //      p.resetZpl();//清除  
  12.         printRestoking(p);  
  13.     }  
  14.     private static boolean printBarcode(ZplPrinter p){  
  15.         //1.打印单个条码  
  16.         String bar0 = "131ZA010101";//条码内容  
  17. //      String bar0Zpl = "^FO110,110^BY6,3.0,280^BCN,,Y,N,N^FD${data}^FS";//条码样式模板  
  18.         String bar0Zpl = "^FO100,50^AAN,100,110^BY6,3.0,280^BCN,,N,N,N^FD${data}^FS";//条码样式模板  
  19.         p.setBarcode(bar0, bar0Zpl);  
  20.         p.setChar(bar0,200,380,140,110);  
  21.         p.setText("上"8803806060304424);  
  22.         String zpl = p.getZpl();  
  23.         System.out.println(zpl);  
  24.         boolean result = p.print(zpl);//打印  
  25.         return result;  
  26.     }  
  27.     private static boolean printPicking300DPI(ZplPrinter p){  
  28.         //左边的条码  
  29.         String bar1 = "07";  
  30.         p.setChar(bar1, 1901306060);  
  31.         String bar1Zpl = "^FO100,200^BY8,3.0,240^BCR,,N,N,N^FD${data}^FS";//条码样式模板  
  32.         p.setBarcode(bar1,bar1Zpl);  
  33.         //下边的条码  
  34.         String bar2 = "123459999900188ABCDE";//20位  
  35.         String bar2Paper = "^FO380,600^BY3,3.0,100^BCN,,Y,N,N^FD${data}^FS";//条码样式模板  
  36.         p.setBarcode(bar2,bar2Paper);  
  37.           
  38.         p.setText("国药控股湖南有限公司"380406060302224);  
  39.         p.setChar("CSS0BPKPPR"3801006060);  
  40.           
  41.         p.setText("09件",940806060302224);  
  42.         p.setText("补"1100806060302224);  
  43.           
  44.         p.setText("公司自配送 公路"3801808080303324);  
  45.         p.setChar("03231151",9401874040);  
  46.         p.setChar("2015-10-10",9402273030);  
  47.           
  48.         p.setText("湖南六谷大药房连锁有限公司"3802606060302224);  
  49.           
  50.         p.setText(":长沙市:开福区:捞刀河镇中岭村258号:"3803206060302222);  
  51.           
  52.         p.setText("多SKU"8004856060302224);  
  53.           
  54.         p.setText("库位:49"3804205656302224);  
  55.         p.setText("品类:感冒胶囊"3804855656302224);  
  56.           
  57.         p.setText("批号:"3805505656302224);  
  58.         p.setChar("78787878788"5005604040);  
  59.           
  60.         String zpl = p.getZpl();  
  61.         System.out.println(zpl);  
  62.         boolean result = p.print(zpl);  
  63.         return result;  
  64.     }  
  65.     private static boolean printPicking203DPI(ZplPrinter p){  
  66.         //左边的条码  
  67.         String bar1 = "07";  
  68.         p.setChar(bar1, 126864040);  
  69.         String bar1Zpl = "^FO66,133^BY5,3.0,160^BCR,,N,N,N^FD${data}^FS";//条码样式模板  
  70.         p.setBarcode(bar1,bar1Zpl);  
  71.         //下边的条码  
  72.         String bar2 = "00000999990018822969";//20位  
  73.         String bar2Paper = "^FO253,400^BY2,3.0,66^BCN,,Y,N,N^FD${data}^FS";//条码样式模板  
  74.         p.setBarcode(bar2,bar2Paper);  
  75.           
  76.         p.setText("国药控股湖南有限公司"253264040201124);  
  77.         p.setChar("CSS0BPKPPR"253662020);  
  78.           
  79.         p.setText("09件",626534040201124);  
  80.         p.setText("补"733534040201124);  
  81.           
  82.         p.setText("公司自配送 公路"2531205353201124);  
  83.         p.setChar("03231151",6261242626);  
  84.         p.setChar("2015-10-10",6261512020);  
  85.           
  86.         p.setText("湖南六谷大药房连锁有限公司"2531734040201124);  
  87.           
  88.         p.setText("长沙市开福区捞刀河镇中岭村258号"2532133030201122);  
  89.           
  90.         p.setText("多SKU"5333234040201124);  
  91.           
  92.         p.setText("库位:49"2532803737201124);  
  93.         p.setText("品类:感冒胶囊"2533233737201124);  
  94.           
  95.         p.setText("批号:"2533663737201124);  
  96.         p.setChar("78787878788"3333732626);  
  97.           
  98.         String zpl = p.getZpl();  
  99.         System.out.println(zpl);  
  100.         boolean result = p.print(zpl);  
  101.         return result;  
  102.     }  
  103.     private static boolean printRestoking(ZplPrinter p){  
  104.         //上方的条码  
  105.         String bar1 = "1434455567773344abcd";  
  106.         String bar1Zpl = "^FO85,70^BY4,3.0,140^BCN,,Y,N,N^FD${data}^FS";//条码样式模板  
  107.         p.setBarcode(bar1,bar1Zpl);  
  108.         //源货位  
  109.         p.setText("来源:131ZA010101"1003206060302224);  
  110.         //目标货位  
  111.         p.setText("目的:131ZA010102",6403206060302224);  
  112.         //货品编号  
  113.         p.setText("货品编号:YF10001"1004406060302224);  
  114.         //件装数  
  115.         p.setText("补货数量:200"6404406060302224);  
  116.         //品名  
  117.         p.setText("复方一支黄花:"1005806060302224);  
  118.           
  119.         String zpl = p.getZpl();  
  120.         System.out.println(zpl);  
  121.         boolean result = p.print(zpl);  
  122.         return result;  
  123.     }  
  124. }  

猜你喜欢

转载自blog.csdn.net/scholar_man/article/details/78784278
今日推荐