almost 3 years ago

Java如果要直接列印的話功能上是有點弱也不是很好理解

所以就順便記錄下來

先看環境,因為需要解PDF所以加載了apache.pdfbox套件

build.gradle
apply plugin: 'java'

sourceCompatibility = '1.5'
targetCompatibility = '1.5'
sourceSets.main.java.srcDir 'src'   // 設置 Java 源碼所在目錄
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'

// 設置 maven 庫地址
repositories {  
    mavenCentral() // 中央庫
}
 
// 設置依賴
dependencies {
    compile 'org.apache.pdfbox:pdfbox:1.8.7'
}

//打包jar
jar {
    //產出檔名設置mitake-print-0.1.0.jar
    baseName = 'mitake-print'
    version =  '0.1.0'
    //此方法類似fatjar將相依套件一併包進來
    from {
        configurations.runtime.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    //需要描述檔但不用啟動程式
    manifest {
        //attributes 'Main-Class': 'com.mitake.utils.print.PrintUtil'
    }
    //包含跟不包含則一使用
    //include('com/**')
    exclude('test/**')
}

再來我們需要實作Printable來達成我們列印需求

ImagePrintable.java
import java.awt.Graphics;
import java.awt.image.*;
import java.awt.print.*;

public class ImagePrintable implements Printable{
    private double x, y, width;
    private int orientation;
    private BufferedImage image;
    private int pagesize = 1;

    public ImagePrintable(PrinterJob printJob, BufferedImage image, int pagesize) {
        PageFormat pageFormat = printJob.defaultPage();
        this.x = pageFormat.getImageableX();
        this.y = pageFormat.getImageableY();
        this.width = pageFormat.getImageableWidth();
        this.orientation = pageFormat.getOrientation();
        this.image = image;
        this.pagesize = pagesize;
    }

    public ImagePrintable(PrinterJob printJob, BufferedImage image) {
        PageFormat pageFormat = printJob.defaultPage();
        this.x = pageFormat.getImageableX();
        this.y = pageFormat.getImageableY();
        this.width = pageFormat.getImageableWidth();
        this.orientation = pageFormat.getOrientation();
        this.image = image;
    }

    public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if(pageIndex < pagesize){
            int pWidth = 0;
            int pHeight = 0;
            if (orientation == PageFormat.PORTRAIT) {//直印

                pWidth = (int) Math.min(width, (double) image.getWidth());
                pHeight = pWidth * image.getHeight() / image.getWidth();
            } else {//橫印 LANDSCAPE

                pHeight = (int) Math.min(width, (double) image.getHeight());
                pWidth = pHeight * image.getWidth() / image.getHeight();
            }
            g.drawImage(image, (int) x, (int) y, pWidth, pHeight, null);
            return PAGE_EXISTS;
        } else {
            return NO_SUCH_PAGE;
        }
    }
}

再來是自訂的工具類封裝相關操作

PrintUtil.java
import java.awt.image.BufferedImage;
import java.awt.print.Book;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.PrintRequestAttributeSet;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

public class PrintUtil {
    private PrintService printService;
    private boolean hasUI = false; 
    
    /**
     * 只印一張圖
     * @param filepath
     * @throws IOException
     * @throws PrinterException
     */
    public void printImage(String filepath) throws IOException, PrinterException{
        BufferedImage image = ImageIO.read(new File(filepath));
        this.printImage(image);
    }
    
    /**
     * 只印一張圖
     * @param image
     * @throws PrinterException
     */
    public void printImage(BufferedImage image) throws PrinterException{
        PrinterJob printJob = PrinterJob.getPrinterJob();
        if(this.printService != null){
            printJob.setPrintService(printService);
        }
        printJob.setPrintable(new ImagePrintable(printJob, image));
        if(hasUI == true){
            if (printJob.printDialog()) {
                printJob.print();
            }
        }else{
            printJob.print();
        }
    }
    
    /**
     * 印整個PDF
     * @param filepath
     * @throws IOException
     * @throws PrinterException
     */
    public void printPdf(String filepath) throws IOException, PrinterException{
        PDDocument doc = PDDocument.load(filepath);
        this.printPdf(doc);
    }
    
    /**
     * 印整個PDF
     * @param doc
     * @throws IOException
     * @throws PrinterException
     */
    public void printPdf(PDDocument doc) throws IOException, PrinterException{
        PrinterJob printJob = PrinterJob.getPrinterJob();
        Book book = new Book();
        List pages = doc.getDocumentCatalog().getAllPages();
        for(int i=0;i<pages.size();i++){
            PDPage page = (PDPage) pages.get(i);
            BufferedImage image = page.convertToImage();
            book.append(new ImagePrintable(printJob, image, pages.size()), printJob.defaultPage());
        }
        printJob.setPageable(book);
        if(this.printService != null){
            printJob.setPrintService(printService);
        }
        if(hasUI == true){
            if (printJob.printDialog()) {
                printJob.print();
            }
        }else{
            printJob.print();
        }
    }
    
    /**
     * 找出一樣的印表機名稱
     * @param printname
     * @return
     */
    public PrintService findPrintServicesName(String printname){
        PrintService printservice = null;
        PrintService services[] = this.findPrintServices(null, null);
        if (services.length == 0){
            return null;
        }
        for(int i = 0 ; i < services.length ; i++){
            PrintService ps = services[i];
            if(printname.equalsIgnoreCase(ps.getName())){
                printservice = ps;
            }
        }
        return printservice;
    }
    
    /**
     * 依照條件找出可用的印表機
     * @param docflavor
     * @param pras
     * @return
     */
    public PrintService[] findPrintServices(DocFlavor docflavor, PrintRequestAttributeSet pras){
        PrintService[] services = PrintServiceLookup.lookupPrintServices(docflavor, pras);
        return services;
    }

    public PrintService getPrintService() {
        return printService;
    }

    public void setPrintService(PrintService printService) {
        this.printService = printService;
    }

    public boolean isHasUI() {
        return hasUI;
    }

    public void setHasUI(boolean hasUI) {
        this.hasUI = hasUI;
    }
}

使用方法

PrintUtil printUtil = new PrintUtil();
//找出特定印表機並指定使用

String printname = "\\\\PRINT.com.tw\\HP LaserJet Professional P1606dn-PCD";
PrintService printService = printUtil.findPrintServicesName(printname);
printUtil.setPrintService(printService);
//列印圖片

printUtil.printImage("D:/test_4753813843870926843.png");
//列印PDF

printUtil.printPdf("D:/測試2.pdf");

圖片的話好像ImageIO的限制所以有些jpg是不能印出來的(正確說是讀不進來),反正暫時用不到就不處理了

← 使用Spring AOP機制插入紀錄點 scala、spray、IntelliJ環境安裝篇 →
 
comments powered by Disqus