用JAVA 創建自己的 A4 打印語言

在這個低碳的時代,大家都在追求無紙化,但是有些打印還是不可避免,比如說產品出貨單之類的,講到打印那辦法就多了,通過報表控件也可以完成打印,但我始終覺得不夠靈活,如果有人玩過ZPL(zebra print language),就能瞭解打印格式其實可以很靈活地控制,可惜 ZPL只適用於Zebra的標籤打印機,並不適合用平常的紙張打印。所以能不能做一種類ZPL的語言來打印,之前我也看過PCL,由於本人水平有限,真沒看懂。

package hpl;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.IOException;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
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.DocFlavor.URL;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.PrinterName;
import javax.swing.JOptionPane;

import Kanban.LineInfo;
/**
 * java定位打印,把打印內容打到指定的地方。
 *
 * @author Harvey_Huang
 *
 */
public class LocatePrint implements Printable {
    private int PAGES = 0;
    private String printStr;
    private String fontname;
    private int fontsize;
    private String imagepath;
    private int locx;
    private int locy;
    private String  Singpage;
    private String Orientation="N";
    private String Fontflag="N";
    private String Sizeflag="N";
    private String message="OK";
    /*
     * Graphic指明打印的圖形環境;PageFormat指明打印頁格式(頁面大小以點爲計量單位,
     * 1點爲1英寸的1/72,1英寸爲25.4毫米。A4紙大致爲595×842點);page指明頁號
     * 
     */
    
   // int pp= 1;
    public int print(Graphics gp, PageFormat pf, int page)
            throws PrinterException {
    	//pp++;
        try {
        	
        try{	
        	
    	Graphics2D g2 = (Graphics2D) gp;
        g2.setPaint(Color.black); // 設置打印顏色爲黑色
        
        //System.err.println("PPPPPPPP  : " + page);
        if (page >= PAGES) // 當打印頁號大於需要打印的總頁數時,打印工作結束
            return Printable.NO_SUCH_PAGE;
        g2.translate(pf.getImageableX(), pf.getImageableY());// 轉換座標,確定打印邊界
        //g2.drawString(printStr, locx, locy);// 具體打印每一行文本,同時走紙移位
    
		
		
		
 		String[] itemarray;
 		String[] detailarray;
 		String typeflag = null;
 		Font font;
		
		itemarray=Singpage.split("\\^FS");
		//System.err.println("XZ:::::::" +itemarray.length);
		 for (int i=0; i<itemarray.length;i++){
			 typeflag="";
				System.out.println("Split  " + i +" : "+itemarray[i]);
				//System.out.println("-------------------------");
				detailarray= itemarray[i].split("\\^");
			  for (int j=0; j<detailarray.length;j++){
				  if(detailarray[j].length()>1){
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("XA")){
					 // System.out.println("初始化"); 
					  PAGES=0;
					  printStr="";
					  fontname="Arial";
					  fontsize=14;
					  imagepath="";
					  locx=0;
					 locy=0;
				
				  }if(detailarray[j].substring(0, 2).toUpperCase().equals("FO")){
					//  System.out.println("找到FO"); 
					  String[] location=detailarray[j].substring(2, detailarray[j].length()).split(",");
					  if(location.length>1){ 
					     locx=Integer.parseInt(location[0]);
						 locy=Integer.parseInt(location[1]);
						//  System.out.println(location[1]); 
					  }
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("FD")){
					 // System.out.println("找到FD"); 
					  printStr=detailarray[j].substring(2, detailarray[j].length());
					//  System.out.println(printStr); 
				  }
				  
			
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("PA")){
					 // System.out.println("找到PA"); 
					  imagepath=detailarray[j].substring(2, detailarray[j].length());
					//  System.out.println(imagepath);
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("PQ")){
					//  System.out.println("找到PQ");   
					  PAGES=Integer.parseInt(detailarray[j].substring(2, detailarray[j].length()));
					  
					    if (PAGES==0) // 當打印頁號大於需要打印的總頁數時,打印工作結束
				            return Printable.NO_SUCH_PAGE;
					//  System.out.println(PAGES); 
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("AN")){
					 // System.out.println("找到AN");  
					  fontname=detailarray[j].substring(2, detailarray[j].length());
					//  System.out.println(fontname);
					  Fontflag="Y";
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("AS")){
					 // System.out.println("找到AS");  
					  fontsize=Integer.parseInt(detailarray[j].substring(2, detailarray[j].length()));
					//  System.out.println(fontsize);   
					  Sizeflag="Y";
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("OR")){
						 // System.out.println("找到AS");  
					  Orientation=detailarray[j].substring(2, detailarray[j].length());
						//  System.out.println(Orientation);
						  
					  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("ST")){
					//  System.out.println("找到ST");
					 typeflag="ST";
				
				  }
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("RP")){
					 // System.out.println("找到RP");
					 typeflag="RP";
					 
					 String[] rpstring=detailarray[j].substring(2, detailarray[j].length()).split(",");
					  if(rpstring.length>1){ 
			 
					
						  printStr="";
					 for(int h=0; h<Integer.parseInt(rpstring[1])+1;h++){
						 printStr=rpstring[0].toString()+printStr;
					 }
					  }
				
				  }
				  
				  if(detailarray[j].substring(0, 2).toUpperCase().equals("GF")){
					 // System.out.println("找到GF");  
					 typeflag="GF";
				  }
				  }
				//System.out.println(detailarray[j]);
			  }

		        
				   if (Orientation.toUpperCase().equals("R")){
						g2.rotate((3.14159/2), locx, locy);    
				   }
				   
				   if (Orientation.toUpperCase().equals("I")){
						g2.rotate(3.14159, locx, locy);    
				   }
				   
				   if (Orientation.toUpperCase().equals("B")){
						g2.rotate((3.14159*3/2), locx, locy);    
				   }
		        
			  if(typeflag.equals("ST")){
			//	 System.out.println(printStr+"    "+fontname+"    "+fontsize+"    ");  
				// N = Normal
				// R = Rotated, 90 degrees clockwise;
				// I = Inverted, 180 degrees
				 //B = Read from Bottom up, 270 degrees
				 if(Fontflag.equals("Y")||Sizeflag.equals("Y")){
					    font = new Font(fontname, Font.PLAIN, fontsize);// 創建字體
				        g2.setFont(font);	 
				 }
			    
		
			        // 打印當前頁文本
			        g2.drawString(printStr, locx, locy); 
			        Fontflag="N";
			        Sizeflag="N";
			        

			  }
			  

			 if(typeflag.equals("GF")){
				 // System.out.println("打印準備");
				    BufferedImage img = ImageIO.read(new File(imagepath));
				   
				   // g2.rotate(3.14159, locx, locy);
					g2.drawImage(img, locx, locy, null);
					//  System.out.println("打印結束");
					//g2.rotate(-3.14159, locx, locy); 
			  }
			 
			  if(typeflag.equals("RP")){
					// System.out.println(printStr+"    "+fontname+"    "+fontsize+"    ");  
					 
				
				         font = new Font("Arial", Font.PLAIN, fontsize);// 創建字體
				        g2.setFont(font);
				        // 打印當前頁文本
				        g2.drawString(printStr, locx, locy); 
					 
				  } 
			 
		 	   if (Orientation.toUpperCase().equals("R")){
					g2.rotate(-(3.14159/2), locx, locy);    
			   }
			   
			   if (Orientation.toUpperCase().equals("I")){
					g2.rotate(-3.14159, locx, locy);    
			   }
			   
			   if (Orientation.toUpperCase().equals("B")){
					g2.rotate(-(3.14159*3/2), locx, locy);    
			   }     
			   Orientation="N";
			 

			   
			   
			 // System.out.println("-------------------------");
		}
		
		
		 
		
    	} catch (IIOException e) {
			// TODO Auto-generated catch block
    		message="E004";
			e.printStackTrace();
		    return Printable.NO_SUCH_PAGE;
		}
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    return Printable.NO_SUCH_PAGE;
		} 

	//	System.err.println("pppppp:::::::" + pp);
       return Printable.PAGE_EXISTS; // 存在打印頁時,繼續打印工作

    }
    // 打印內容到指定位置
    public String printContent(String hplpage,String Printq) {
   // 	System.err.println("tttttt:" + pp);
    	//String message="OK";
    	Singpage=hplpage;
    	
       // printStr = "aaaaa";// 獲取需要打印的目標文本
       // fontname = "Free 3 of 9";// 獲取需要打印的目標文本
       // fontsize=24;
       // imagepath="c:\\2.jpg";
       // locx=100;
       // locy=300;
  
        if (hplpage.length() > 0) // 當打印內容不爲空時
        {
        	
        	  try {
        		 
        	DocPrintJob job = null;
            PAGES = 1; // 獲取打印總頁數
            // 指定打印輸出格式
            DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
            // 定位默認的打印服務
            
            HashAttributeSet hs = new HashAttributeSet();  
            String printerName=Printq;  
            
            hs.add(new PrinterName(printerName,null));
            PrintService[] printService =PrintServiceLookup.lookupPrintServices(null, hs);  
           // PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
            // 創建打印作業
            if(printService.length>0){
                 job = printService[0].createPrintJob();
        
     
            // 設置打印屬性
            PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
            // 設置紙張大小,也可以新建MediaSize類來自定義大小
            pras.add(MediaSizeName.ISO_A4);

  
            DocAttributeSet das = new HashDocAttributeSet();
            // 指定打印內容
            Doc doc = new SimpleDoc(this, flavor, das);
            // 不顯示打印對話框,直接進行打印工作
  
          
                job.print(doc, pras); // 進行每一頁的具體打印操作
            	//System.err.print("分析標識點5");
            }else{
           	 message="E002";
           }
            } catch (PrintException pe) {
                pe.printStackTrace();
                message="E001";
            }
        
        } else {
            // 如果打印內容爲空時,提示用戶打印將取消
            JOptionPane.showConfirmDialog(null,
                    "Sorry, Printer Job is Empty, Print Cancelled!",
                    "Empty", JOptionPane.DEFAULT_OPTION,
                    JOptionPane.WARNING_MESSAGE);
            message="E003";
        }
        
        return message;
    }
    
    

    public String analyze(String hpl,String Printq) {
       
    	String printstate="OK";
    	
    	  LocatePrint test = new LocatePrint();
 		String[] pagearray=hpl.split("\\^XZ");
 		//System.err.println("nnnnnnn======"+ pagearray.length);

 		for(int k=0; k<pagearray.length;k++){
 			
 			 printstate=test.printContent(pagearray[k].toString().trim(),Printq);
 			 
 		}
 		return printstate;
    }

    
    public static void main(String[] args) {
    	 String testdata="^XA" +
	 		"^STthis is test^FO20,42^FDPICK LIST^ANArial^AS30^FS" +
	 		"^STthis is test^FO52,120^FDhelloworld^AN3 of 9 Barcode^AS20^FS" +
	 		"^STthis is test^FO60,482^FD中文測試中文測試^AN宋體^AS30^FS" +
	 		"^STthis is test^FO470,602^FD黑體測試^AN黑體^ORB^AS20^FS" +
	 		"^STthis is test^FO170,632^FD黑體測試1^FS" +
	 		"^STthis is test^FO170,652^FD黑體測試2^FS" +
	 		"^STthis is test^FO170,672^FD黑體測試3^FS" +
	 		"^STthis is test^FO170,692^FD黑體測試4^AS40^FS" +
	 		"^RP_,50^FO52,522^AS20^FS" +
    	    "^STthis is test^FO80,482^FD中文測試中文測試(旋轉)^ORR^AN宋體^AS30^FS" +
	 		"^GFThis is test^PAc:\\2.jpg^FO294,372^ORI^FS" +
	 		"^PQ1" +
	 		"^XZ";
    	  LocatePrint test = new LocatePrint();
    	  System.out.print(test.analyze(testdata,"TESTPRINT"));
       
    }
}


如果你夠仔細的話,你就會發現,程序會執行兩遍後纔會被打印出來,一開始我也以爲是我的程序方面的問題,後來在網上查了一下,這塊屬於正常現像,原因就查閱:

http://hi.baidu.com/dcjob/item/e6c40d16d34b08ec9913d6fb

下面講一下打印參數的含義:

^XA  是每次打印的開始。

^XZ 是結束

^AS 字體大小

^AN 字體名字,一定是操作系統中存在的字體

^FS 打印單項結束標識

^FD 打印數據

^FO 打印位置

^RP 重複打印某一字符或文字

^ST 字符串打印標識

^GF 圖片打印標識

^PA 圖片路徑,注意路徑的反斜槓需反義

^PQ 打印數量

^OR 打印方向  N正常,R 90度,I 180度 B 270度

請注意這行   System.out.print(test.analyze(testdata,"TESTPRINT"));

TESTPRINT是安裝好的打印機在系統中的名稱。名稱一定要對應,默認或非默認打印機不會有問題。

參照例子的實例即可,如果想了解每個參數,請查閱下面的說明,由於公司是洋人開的,就假裝一回洋鬼子,如果你學過ZPL會發現和ZPL手冊很像。



HPL  Command Guide

__________________________________________

   

^XA

^STthis is test^FO20,42^FDPICK LIST^ANArial^AS30^FS

^STthis is test^FO52,120^FDhelloworld^AN3 of 9 Barcode^AS20^FS

^STthis is test^FO60,482^FD中文測試中文測試^AN宋體^AS30^FS

^STthis is test^FO470,602^FD黑體測試^AN黑體^ORB^AS20^FS

^STthis is test^FO170,632^FD黑體測試1^FS

^STthis is test^FO170,652^FD黑體測試2^FS

^STthis is test^FO170,672^FD黑體測試3^FS

^STthis is test^FO170,692^FD黑體測試4^AS40^FS

^RP_,50^FO52,522^AS20^FS

^STthis is test^FO80,482^FD中文測試(旋轉)^ORR^AN宋^AS30^FS

^GFThis is test^PAc:\\2.jpg^FO294,372^ORI^FS

^PQ1

^XZ





    ^XA
        Start Format

Description:The ^XA command is used at the beginning of HPL code,It is the opening      bracket and indicates the start of a new label format.


                 Format:^XA

Comments:Report formats should start with the ^XA command and end with the ^XZ command to be in valid HPL format


    ^XZ
        End Format

Description:The ^XZ command is the ending (closing) bracket.It indicates the end of a report format.When this command is received. a report will be printed.


                 Format:^XZ

Comments:Report formats should start with the ^XA command and end with the ^XZ command to be in valid HPL format.


     ^AN
        Font name

Description:The ^AN is used with system fonts


Format:^ANf


Parameters:

     f= font name

          Accepted Values:System font name


Example:

         ^XA

         ^STthis is test^FO20,42^FDPICK LIST^ANArial^AS30^FS

         ^PQ1

         ^XZ



     ^AS
        Font Size

Description:Font Size  


Format:^ASf


Parameters:

     f= font size

          Accepted Values:System font size


Example:

         ^XA

         ^STthis is test^FO20,42^FDPICK LIST^ANArial^AS30^FS

         ^PQ1

         ^XZ


     ^FD
        Field Data

Description:The ^FD command defines the data string for the field.The filed data can be any printable character.


Format:^FDa


Parameters:

     a= data to be printed

          Accepted Values:Any ASCII string


     ^FO
        Field Origin

Description:The ^FO command  sets a field origin,

Format:^FOx,y


Parameters:

     x= x-axis location

          Default Value:0

     y= y-axis location

          Default Value:0


Comments:If the value entered for x or y parameter is too high,it could position the field origin completely off the report.


     ^FS
        Field Separator

Description:The ^FS command  denotes the end of the field definiton.


Format:^FS



     ^OR
        Field orientation

Description:The ^FO command  sets a field orientation


Format:^ORo

       

Parameters:

     Accepted values:

                  N=normal;

                  R=rotated 90 degrees(clockwise)

                  I=inverted 180 degrees

                  B=read from bottom up,270 degrees


     ^PQ
        Print quantity

Description:The ^PQ command  gives control over serveral printing operations.It controls the number of reports to print.

Format:^FOq


Parameters:

     q= total quantity of reports to print

          Default Value:0


Comments:If Q=0 ,It wouldn’t print the report.




     ^PA
        graphic path

Description:The ^PA command  sets graphic path,It controls the path of graphic to print.

Format:^PAp


Parameters:

     p= graphic path.the “\” need transfer to Antisense character “\\”


Example:

                    ^XA

                                    ^GFThis is test^PAc:\\2.jpg^FO294,372^FS
                                    ^PQ1

                    ^XZ


     ^RP
        repeat print character

Description:The ^RP command  gives control continuous print the same character

Format:^RPc,q


Parameters:

     c= Need to be printed characters

     q= Quantity of character


     Example:

                    ^XA

                                    ^RP_,50^FO52,522^AS20^FS
                                    ^PQ1

                    ^XZ






     ^ST
        Print string start

Description:The ^ST command is used at the beginning of string printing, It is the opening bracket and indicates the start of string printing.

Format:^STd


Parameters:

     d= Description,it will not be printed on the report,Just better understanding of the code

          Default Value:NULL




     ^GF
        Print graphic start

Description:The ^GF command is used at the beginning of graphic printing, It is the opening bracket and indicates the start of graphic printing.

Format:^GFd


Parameters:

     d= Description.it will not be printed on the report,Just better understanding of the code

          Default Value:NULL


作者xhhuang1979

歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章