java打印票據demo


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 "打印...";
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM