1. 程式人生 > >基於Zpl實現斑馬印表機列印條碼

基於Zpl實現斑馬印表機列印條碼

基於他人程式碼,為需要的朋友提供

import java.io.File;  

import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.UnsupportedEncodingException;  
  
import javax.print.Doc;  
import javax.print.DocFlavor;  
import javax.print.DocPrintJob;  
import javax.print.PrintException;  
import javax.print.PrintService;  
import javax.print.PrintServiceLookup;  
import javax.print.SimpleDoc;  
import javax.print.attribute.standard.PrinterName;  
  
import sun.awt.AppContext;  
/** 
 * 採用點陣字型檔ts24.lib 
 * @author Labrador 
 * 
 */  
public class ZplPrinter {  
    private String printerURI = null;           //印表機完整路徑  
    private PrintService printService = null;   //印表機服務  
    private byte[] dotFont;  
    private String darkness = "~SD22";  //Set Darkness設定色帶顏色的深度 0-30  
    private String width = "^PW1200";   //Print Width列印寬度0-1500  
    private String length = "^LL800";   //Label Length標籤長度0-x(暫無作用)  
    private String begin = "^XA" + darkness + width;    //標籤格式以^XA開始  
    private String end = "^XZ";         //標籤格式以^XZ結束  
    private String content = "";        //列印內容  
    private String message = "";        //列印的結果資訊  
  
    /** 
     * 構造方法 
     * @param printerURI 印表機路徑 
     */  
    public ZplPrinter(String printerURI){  
        this.printerURI = printerURI;  
        //載入字型  
        File file = new File("E://ts24.lib");  
        if(file.exists()){  
            FileInputStream fis;  
            try {  
                fis = new FileInputStream(file);  
                dotFont = new byte[fis.available()];  
                fis.read(dotFont);  
                fis.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }else{  
            System.out.println("C://ts24.lib檔案不存在");  
        }  
        //初始化印表機  
        AppContext.getAppContext().put(PrintServiceLookup.class.getDeclaredClasses()[0], null);//重新整理印表機列表  
        PrintService[] services = PrintServiceLookup.lookupPrintServices(null,null);  
        if (services != null && services.length > 0) {  
            for (PrintService service : services) {  
                if (printerURI.equals(service.getName())) {  
                    printService = service;  
                    break;  
                }  
            }  
        }  
        if (printService == null) {  
            System.out.println("沒有找到印表機:["+printerURI+"]");  
            //迴圈出所有的印表機  
            if (services != null && services.length > 0) {  
                System.out.println("可用的印表機列表:");  
                for (PrintService service : services) {  
                    System.out.println("["+service.getName()+"]");  
                }  
            }  
        }else{  
            System.out.println("找到印表機:["+printerURI+"]");  
            System.out.println("印表機名稱:["+printService.getAttribute(PrinterName.class).getValue()+"]");  
        }  
    }  
    /** 
     * 設定條形碼 
     * @param barcode 條碼字元 
     * @param zpl 條碼樣式模板 
     */  
    public void setBarcode(String barcode,String zpl) {  
        content += zpl.replace("${data}", barcode);  
    }  
  
    /** 
     * 中文字元、英文字元(包含數字)混合 
     * @param str 中文、英文 
     * @param x x座標 
     * @param y y座標 
     * @param eh 英文字型高度height 
     * @param ew 英文字型寬度width 
     * @param es 英文字型間距spacing 
     * @param mx 中文x軸字型圖形放大倍率。範圍1-10,預設1 
     * @param my 中文y軸字型圖形放大倍率。範圍1-10,預設1 
     * @param ms 中文字型間距。24是個比較合適的值。 
     */  
    public void setText(String str, int x, int y, int eh, int ew, int es, int mx, int my, int ms) {  
        byte[] ch = str2bytes(str);  
        for (int off = 0; off < ch.length;) {  
            if (((int) ch[off] & 0x00ff) >= 0xA0) {//中文字元  
                try {  
                    int qcode = ch[off] & 0xff;  
                    int wcode = ch[off + 1] & 0xff;  
                    content += String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x, y, qcode, wcode, mx, my);  
                    begin += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode);  
                    qcode = (qcode + 128 - 32) & 0x00ff;  
                    wcode = (wcode + 128 - 32) & 0x00ff;  
                    int offset = ((int) qcode - 16) * 94 * 72 + ((int) wcode - 1) * 72;  
                    for (int j = 0; j < 72; j += 3) {  
                        qcode = (int) dotFont[j + offset] & 0x00ff;  
                        wcode = (int) dotFont[j + offset + 1] & 0x00ff;  
                        int qcode1 = (int) dotFont[j + offset + 2] & 0x00ff;  
                        begin += String.format("%02X%02X%02X\n", qcode, wcode, qcode1);  
                    }  
                    x = x + ms * mx;  
                    off = off + 2;  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    //替換成X號  
                    setChar("X", x, y, eh, ew);  
                    x = x + es;//注意間距更改為英文字元間距  
                    off = off + 2;  
                }  
            } else if (((int) ch[off] & 0x00FF) < 0xA0) {//英文字元  
                setChar(String.format("%c", ch[off]), x, y, eh, ew);  
                x = x + es;  
                off++;  
            }  
        }  
    }  
    /** 
     * 英文字串(包含數字) 
     * @param str 英文字串 
     * @param x x座標 
     * @param y y座標 
     * @param h 高度 
     * @param w 寬度 
     */  
    public void setChar(String str, int x, int y, int h, int w) {  
        content += "^FO" + x + "," + y + "^A0," + h + "," + w + "^FD" + str + "^FS";  
    }  
    /** 
     * 英文字元(包含數字)順時針旋轉90度 
     * @param str 英文字串 
     * @param x x座標 
     * @param y y座標 
     * @param h 高度 
     * @param w 寬度 
     */  
    public void setCharR(String str, int x, int y, int h, int w) {  
        content += "^FO" + x + "," + y + "^A0R," + h + "," + w + "^FD" + str + "^FS";  
    }  
    /** 
     * 獲取完整的ZPL 
     * @return 
     */  
    public String getZpl() {  
        return begin + content + end;  
    }  
    /** 
     * 重置ZPL指令,當需要列印多張紙的時候需要呼叫。 
     */  
    public void resetZpl() {  
        begin = "^XA" + darkness + width;  
        end = "^XZ";  
        content = "";  
    }  
    /** 
     * 列印 
     * @param zpl 完整的ZPL 
     */  
    public boolean print(String zpl){  
        if(printService==null){  
            message = "打印出錯:沒有找到印表機["+printerURI+"]";  
            System.out.println("打印出錯:沒有找到印表機["+printerURI+"]");  
            return false;  
        }  
        DocPrintJob job = printService.createPrintJob();  
        byte[] by = zpl.getBytes();  
        DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;  
        Doc doc = new SimpleDoc(by, flavor, null);  
        try {  
            job.print(doc, null);  
            message = "已列印";  
            System.out.println("已列印");  
            return true;  
        } catch (PrintException e) {  
            message = "打印出錯:"+e.getMessage();  
            System.out.println("打印出錯:"+e.getMessage());  
            e.printStackTrace();  
            return false;  
        }  
    }  
    public String getMessage(){  
        return message;  
    }  
    /** 
     * 字串轉byte[] 
     * @param s 
     * @return 
     */  
    private byte[] str2bytes(String s) {  
        if (null == s || "".equals(s)) {  
            return null;  
        }  
        byte[] abytes = null;  
        try {  
            abytes = s.getBytes("gb2312");  
        } catch (UnsupportedEncodingException ex) {  
            ex.printStackTrace();  
        }  
        return abytes;  
    }  

}  

測試類

public class ZplPrinterTest {  
    public static void main(String[] args) {  
        ZplPrinter p = new ZplPrinter("ZDesigner ZT410-300dpi ZPL");  
//        ZplPrinter p = new ZplPrinter("\\\\10.0.1.102\\ZDesigner ZT410-300dpi ZPL");  
//      ZplPrinter p = new ZplPrinter("\\\\10.10.13.224\\ZDesigner GT800 (ZPL)");  
          
//      printBarcode(p);  
//      p.resetZpl();//清除  
//      printPicking300DPI(p);  
//      p.resetZpl();//清除  
//      printPicking203DPI(p);  
//      p.resetZpl();//清除  
        printRestoking(p);  
    }  
    private static boolean printBarcode(ZplPrinter p){  
        //1.列印單個條碼  
        String bar0 = "131ZA010101";//條碼內容  
//      String bar0Zpl = "^FO110,110^BY6,3.0,280^BCN,,Y,N,N^FD${data}^FS";//條碼樣式模板  
        String bar0Zpl = "^FO100,50^AAN,100,110^BY6,3.0,280^BCN,,N,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar0, bar0Zpl);  
        p.setChar(bar0,200,380,140,110);  
        p.setText("上", 880, 380, 60, 60, 30, 4, 4, 24);  
        String zpl = p.getZpl();  
        System.out.println(zpl);  
        boolean result = p.print(zpl);//列印  
        return result;  
    }  
    private static boolean printPicking300DPI(ZplPrinter p){  
        //左邊的條碼  
        String bar1 = "07";  
        p.setChar(bar1, 190, 130, 60, 60);  
        String bar1Zpl = "^FO100,200^BY8,3.0,240^BCR,,N,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar1,bar1Zpl);  
        //下邊的條碼  
        String bar2 = "123459999900188ABCDE";//20位  
        String bar2Paper = "^FO380,600^BY3,3.0,100^BCN,,Y,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar2,bar2Paper);  
          
        p.setText("國藥控股湖南有限公司", 380, 40, 60, 60, 30, 2, 2, 24);  
        p.setChar("CSS0BPKPPR", 380, 100, 60, 60);  
          
        p.setText("09件",940, 80, 60, 60, 30, 2, 2, 24);  
        p.setText("補", 1100, 80, 60, 60, 30, 2, 2, 24);  
          
        p.setText("公司自配送 公路", 380, 180, 80, 80, 30, 3, 3, 24);  
        p.setChar("03231151",940, 187, 40, 40);  
        p.setChar("2015-10-10",940, 227, 30, 30);  
          
        p.setText("湖南六穀大藥房連鎖有限公司", 380, 260, 60, 60, 30, 2, 2, 24);  
          
        p.setText(":長沙市:開福區:撈刀河鎮中嶺村258號:", 380, 320, 60, 60, 30, 2, 2, 22);  
          
        p.setText("多SKU", 800, 485, 60, 60, 30, 2, 2, 24);  
          
        p.setText("庫位:49", 380, 420, 56, 56, 30, 2, 2, 24);  
        p.setText("品類:感冒膠囊", 380, 485, 56, 56, 30, 2, 2, 24);  
          
        p.setText("批號:", 380, 550, 56, 56, 30, 2, 2, 24);  
        p.setChar("78787878788", 500, 560, 40, 40);  
          
        String zpl = p.getZpl();  
        System.out.println(zpl);  
        boolean result = p.print(zpl);  
        return result;  
    }  
    private static boolean printPicking203DPI(ZplPrinter p){  
        //左邊的條碼  
        String bar1 = "07";  
        p.setChar(bar1, 126, 86, 40, 40);  
        String bar1Zpl = "^FO66,133^BY5,3.0,160^BCR,,N,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar1,bar1Zpl);  
        //下邊的條碼  
        String bar2 = "00000999990018822969";//20位  
        String bar2Paper = "^FO253,400^BY2,3.0,66^BCN,,Y,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar2,bar2Paper);  
          
        p.setText("國藥控股湖南有限公司", 253, 26, 40, 40, 20, 1, 1, 24);  
        p.setChar("CSS0BPKPPR", 253, 66, 20, 20);  
          
        p.setText("09件",626, 53, 40, 40, 20, 1, 1, 24);  
        p.setText("補", 733, 53, 40, 40, 20, 1, 1, 24);  
          
        p.setText("公司自配送 公路", 253, 120, 53, 53, 20, 1, 1, 24);  
        p.setChar("03231151",626, 124, 26, 26);  
        p.setChar("2015-10-10",626, 151, 20, 20);  
          
        p.setText("湖南六穀大藥房連鎖有限公司", 253, 173, 40, 40, 20, 1, 1, 24);  
          
        p.setText("長沙市開福區撈刀河鎮中嶺村258號", 253, 213, 30, 30, 20, 1, 1, 22);  
          
        p.setText("多SKU", 533, 323, 40, 40, 20, 1, 1, 24);  
          
        p.setText("庫位:49", 253, 280, 37, 37, 20, 1, 1, 24);  
        p.setText("品類:感冒膠囊", 253, 323, 37, 37, 20, 1, 1, 24);  
          
        p.setText("批號:", 253, 366, 37, 37, 20, 1, 1, 24);  
        p.setChar("78787878788", 333, 373, 26, 26);  
          
        String zpl = p.getZpl();  
        System.out.println(zpl);  
        boolean result = p.print(zpl);  
        return result;  
    }  
    private static boolean printRestoking(ZplPrinter p){  
        //上方的條碼  
        String bar1 = "1434455567773344abcd";  
        String bar1Zpl = "^FO85,70^BY4,3.0,140^BCN,,Y,N,N^FD${data}^FS";//條碼樣式模板  
        p.setBarcode(bar1,bar1Zpl);  
        //源貨位  
        p.setText("來源:131ZA010101", 100, 320, 60, 60, 30, 2, 2, 24);  
        //目標貨位  
        p.setText("目的:131ZA010102",640, 320, 60, 60, 30, 2, 2, 24);  
        //貨品編號  
        p.setText("貨品編號:YF10001", 100, 440, 60, 60, 30, 2, 2, 24);  
        //件裝數  
        p.setText("補貨數量:200", 640, 440, 60, 60, 30, 2, 2, 24);  
        //品名  
        p.setText("複方一支黃花:", 100, 580, 60, 60, 30, 2, 2, 24);  
          
        String zpl = p.getZpl();  
        System.out.println(zpl);  
        boolean result = p.print(zpl);  
        return result;  
    }  
}