package com.zns.print; import com.zns.model.Product; import com.zns.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.awt.*; import java.awt.print.*; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; @Component public class MyPrint implements Printable { @Autowired private ProductService productService; private static MyPrint myPrint; @PostConstruct //通過@PostConstruct實現初始化bean之前進行的操作 public void init() { myPrint = this; myPrint.productService = this.productService; } private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //每個條項的長度 private float filedW = 120; //list里面字段的默認長度 private float commonListItemW = 55; //序號 private int dataNo = 0; //標題 private String title = "出 庫 單"; //列表字段名稱 private List<String> listFieldTitles = new ArrayList<>(Arrays.asList("序號", "編號", "名稱", "規格", "單位", "單價", "數量", "小計", "備注")); //列表字段長度 private List<Float> listFieldWidths = new ArrayList<>(Arrays.asList(commonListItemW, commonListItemW, commonListItemW, commonListItemW, commonListItemW, commonListItemW, commonListItemW, commonListItemW, commonListItemW)); //列表字段key 對應對象的屬性值 private List<String> listFieldKeys = new ArrayList<>(Arrays.asList("no", "code", "name", "spec", "unit", "unitPrice", "num", "total", "remark")); private List<Product> dataList; //需要打印的頁數 private int totalPageCount; public List<Product> getDataList() { return dataList; } public void setDataList(List<Product> dataList) { this.dataList = dataList; } public int getTotalPageCount() { return totalPageCount; } public void setTotalPageCount(int totalPageCount) { this.totalPageCount = totalPageCount; } /** * 打印方法 * graphics - 用來繪制頁面的上下文,即打印的圖形 * pageFormat - 將繪制頁面的大小和方向,即設置打印格式,如頁面大小一點為計量單位(以1/72 英寸為單位,1英寸為25.4毫米。A4紙大致為595 × 842點) * pageIndex - 要繪制的頁面從 0 開始的索引 ,即頁號 */ @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { System.out.println("pageIndex為:" + pageIndex); //獲取數據 this.dataList = myPrint.productService.getDataList(pageIndex + 1); Graphics2D g2 = (Graphics2D) graphics; g2.setColor(Color.black); if (pageIndex > totalPageCount - 1) { return NO_SUCH_PAGE; } else { System.out.println("開始打印第:" + (pageIndex + 1) + "頁"); g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());// 轉換坐標,確定打印邊界 //打印起點坐標 double x = pageFormat.getImageableX(); //返回與此 PageFormat相關的 Paper對象的可成像區域左上方點的 x坐標。 double y = pageFormat.getImageableY(); //返回與此 PageFormat相關的 Paper對象的可成像區域左上方點的 y坐標。 //Font.PLAIN: 普通樣式常量 Font.ITALIC 斜體樣式常量 Font.BOLD 粗體樣式常量。 Font font = new Font("宋體", Font.BOLD, 18); g2.setFont(font);//設置標題打印字體 g2.setStroke(new BasicStroke(1.0f));//線條寬度 float height = font.getSize2D();//獲取字體的高度 //設置標題 g2.drawString(title, (float) x + 180, (float) y + height); float line = 2 * height; //下一行開始打印的高度 g2.setFont(new Font("宋體", Font.PLAIN, 10)); height = font.getSize2D();// 字體高度 line += 5; g2.drawString("出貨日期: 2018-01-01", (float) x, (float) y + line); g2.drawString("交貨進間: 2018-01-01", (float) x + filedW, (float) y + line); g2.drawString("出貨單號: 20180101123", (float) x + 2 * filedW, (float) y + line); line += height; g2.drawString("取貨方式: 貨到付款", (float) x, (float) y + line); g2.drawString("電話號碼: 18818000000", (float) x + filedW, (float) y + line); g2.drawString("頁 次: 第 1 頁,共 2 頁", (float) x + 2 * filedW, (float) y + line); line += height; g2.drawString("收 貨 人: 張三", (float) x, (float) y + line); g2.drawString("移動電話: 18818000000", (float) x + filedW, (float) y + line); g2.drawString("訂購客戶: 華強北九方店", (float) x + 2 * filedW, (float) y + line); line += height; g2.drawString("收貨地址: 深圳市福田區會展中心", (float) x, (float) y + line); g2.drawString("出貨倉庫: 總倉", (float) x + 2 * filedW, (float) y + line); //表格線微調值 float lineFineTuning = 5; //設置列表項標題 line += height; //畫上橫線 g2.drawLine((int) (x - lineFineTuning), (int) (y + line - height + lineFineTuning), (int) (x + getlistFieldWidthTotal()), (int) (y + line - height + lineFineTuning)); //畫左豎線 g2.drawLine((int) (x - lineFineTuning), (int) (y + line - height + lineFineTuning), (int) (x - lineFineTuning), (int) (y + line + lineFineTuning)); for (int i = 0; i < listFieldTitles.size(); i++) { float offsetNum = 0; for (int j = 0; j < i; j++) { offsetNum += listFieldWidths.get(j); } g2.drawString(listFieldTitles.get(i).toString(), (float) x + offsetNum, (float) y + line); //畫豎線 int temX = (int) (x + getlistFieldWidthTotal(i) - lineFineTuning); if (i == listFieldTitles.size() - 1) { temX = temX + (int) lineFineTuning; } g2.drawLine(temX, (int) (y + line - height + lineFineTuning), temX, (int) (y + line + height)); } //畫下橫線 g2.drawLine((int) (x - lineFineTuning), (int) (y + line + lineFineTuning), (int) (x + getlistFieldWidthTotal()), (int) (y + line + lineFineTuning)); //設置列表項數據 line += height; if (dataList != null && dataList.size() > 0) { for (int i = 0; i < dataList.size(); i++) { dataNo++; for (int k = 0; k < listFieldKeys.size(); k++) { float offsetNum = 0; for (int j = 0; j < k; j++) { offsetNum += listFieldWidths.get(j); } String filedValue = ""; //如果是序號列 if (k == 0) { filedValue = String.valueOf(dataNo); } else { filedValue = getValueByKey(dataList.get(i), listFieldKeys.get(k)).toString(); } g2.drawString(filedValue, (float) x + offsetNum, (float) y + line); //畫豎線 int temX = (int) (x + getlistFieldWidthTotal(k) - lineFineTuning); if (k == listFieldTitles.size() - 1) { temX = temX + (int) lineFineTuning; } g2.drawLine(temX, (int) (y + line - height + lineFineTuning), temX, (int) (y + line + lineFineTuning)); //畫下橫線 g2.drawLine((int) (x - lineFineTuning), (int) (y + line + lineFineTuning), (int) (x + getlistFieldWidthTotal()), (int) (y + line + lineFineTuning)); } //畫左豎線 g2.drawLine((int) (x - lineFineTuning), (int) (y + line - height + lineFineTuning), (int) (x - lineFineTuning), (int) (y + line + lineFineTuning)); line += height; } } //在點 (x1, y1) 和 (x2, y2) 之間畫一條線 //line += height; //g2.drawLine((int) x, (int) (y + line), (int) x + 500, (int) (y + line)); //虛線 //line += height; //g2.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 2, 2 }, 0)); //g2.drawLine((int) x, (int) (y + line), (int) x + 500, (int) (y + line)); line += height; g2.drawString("備注: 這里是備注...", (float) x, (float) y + line); line += height; g2.drawString("服務電話: 18818000000", (float) x, (float) y + line); g2.drawString("訂單編號: 20180101123", (float) x + filedW, (float) y + line); g2.drawString("制表日期:" + sdf.format(new Date()), (float) x + 2 * filedW, (float) y + line); line += height; g2.drawString("訂購: 華強北九方店", (float) x, (float) y + line); g2.drawString("白聯:倉庫 紅聯:客戶 藍、黃聯:財務", (float) x + filedW, (float) y + line); return PAGE_EXISTS; } } /** * 獲取對象屬性值 * * @param obj * @param key * @return */ public static Object getValueByKey(Object obj, String key) { // 得到類對象 Class userCla = (Class) obj.getClass(); /* 得到類中的所有屬性集合 */ Field[] fs = userCla.getDeclaredFields(); for (int i = 0; i < fs.length; i++) { Field f = fs[i]; f.setAccessible(true); // 設置些屬性是可以訪問的 try { if (f.getName().endsWith(key)) { return f.get(obj); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } // 沒有查到時返回空字符串 return ""; } //獲取列表字段總寬度 private float getlistFieldWidthTotal() { float widthTotal = 0; for (int i = 0; i < listFieldWidths.size(); i++) { widthTotal += listFieldWidths.get(i); } return widthTotal; } //獲取截止到某個字段索引的字段總寬度 index從0開始 private float getlistFieldWidthTotal(int index) { float widthTotal = 0; for (int i = 0; i <= index; i++) { widthTotal += listFieldWidths.get(i); } return widthTotal; } public void doPrint(Printable printable) { try { MyPrint myPrint = new MyPrint(); //Book 類提供文檔的表示形式,該文檔的頁面可以使用不同的頁面格式和頁面 painter Book book = new Book(); //要打印的文檔 //PageFormat類描述要打印的頁面大小和方向 PageFormat pf = new PageFormat(); //初始化一個頁面打印對象 pf.setOrientation(PageFormat.PORTRAIT); //設置頁面打印方向,從上往下,從左往右 //設置打印紙頁面信息。通過Paper設置頁面的空白邊距和可打印區域。必須與實際打印紙張大小相符。 Paper paper = new Paper(); // 紙張大小 //paper.setSize(683, 793.7); paper.setSize(683, 500); // A4(595 X 842)設置打印區域 A4紙的默認X,Y邊距是72 //paper.setImageableArea(20, 20, 683, 793.7); paper.setImageableArea(20, 20, 683, 500); pf.setPaper(paper); book.append(printable, pf, this.totalPageCount); PrinterJob job = PrinterJob.getPrinterJob(); //獲取打印服務對象 job.setPageable(book); //設置打印類 job.print(); } catch (PrinterException e) { e.printStackTrace(); } } }
控制器調用
@Autowired private ProductService productService; @RequestMapping("/print") @ResponseBody public String print() { MyPrint myPrint = new MyPrint(); //設置打印頁面數量 myPrint.setTotalPageCount(2); myPrint.doPrint(myPrint); System.out.println("打印成功。。。"); return "打印..."; }