首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 列印程式設計全攻略:文字、圖形、檔案與預覽完整實作

     編輯:Java 相關知識

Java 列印 API 演進脈絡

  • JDK 1.1: java.awt.print.Printable、PrinterJob、PrintJob(AWT 簡易列印)。
  • JDK 1.4+: Java Print Service API (JPS)──javax.print.*,統一列印服務發現、屬性、事件、文件風味,支援更豐富的列印場景。

核心列印流程兩要素

  1. 列印服務對象: JDK 1.4 前用 Printable 或 Toolkit.getPrintJob();JPS 用 PrintServiceLookup.lookupDefaultPrintService()。
  2. 啟動列印工作: PrinterJob.print() 或 DocPrintJob.print(doc, attributes)。

列印對話框差異

特性PrinterJob.printDialog()ServiceUI.printDialog()
來源JDK 1.1 AWTJDK 1.4 JPS
預設行為顯示對話框預設不顯示,需程式碼主動呼叫
頁數預估需自行計算或用 Book 傳遞同樣需應用層計算

實作一:列印文字(分頁邏輯)

關鍵介面:Printable

public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException {
    Graphics2D g2 = (Graphics2D) g;
    if (pageIndex >= totalPages) return NO_SUCH_PAGE; // 結束
    g2.translate(pf.getImageableX(), pf.getImageableY()); // 原點平移到可列印區
    drawPageContent(g2, pf, pageIndex); // 繪製當頁內容
    return PAGE_EXISTS; // 繼續下一頁
}

分頁計算

預先將完整文字按「每頁 54 行」切分成 String[] pages,getPagesCount() 回傳總頁數供 pageIndex 判斷。

兩種啟動方式

  • 傳統: PrinterJob.getPrinterJob().setPrintable(this, pf); if (job.printDialog()) job.print();
  • JPS: DocFlavor.SERVICE_FORMATTED.PRINTABLE + SimpleDoc(this, flavor, das) + DocPrintJob.print(doc, pras)。

實作二:列印預覽

原理:print() 只是將內容繪製到 Graphics 物件。預覽時將 Graphics2D 導向螢幕元件,並套用縮放與平移,讓整頁 A4 適配螢幕矩形。

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
    double scale = Math.min(getWidth()/pf.getWidth(), getHeight()/pf.getHeight());
    g2.translate(offsetX, offsetY);
    g2.scale(scale, scale);
    // 繪製頁框背景
    g2.setPaint(Color.WHITE); g2.fill(pageRect);
    g2.setPaint(Color.BLACK); g2.draw(pageRect);
    // 呼叫同一個 print() 邏輯繪製指定頁
    printable.print(g2, pf, currentPage);
}

翻頁只需更新 currentPage 並 repaint()。

實作三:列印元件/圖形(整個視窗)

Component.printAll(Graphics g) 會遞迴繪製元件樹。搭配 AWT Toolkit.getPrintJob() 取得 PrintJob 與 Graphics:

PrintJob pj = Toolkit.getDefaultToolkit().getPrintJob(frame, "Title", props);
Graphics pg = pj.getGraphics();
frame.printAll(pg);
pg.dispose();
pj.end();

適合快速列印表單、報表畫面,但精細排版控制力較弱。

實作四:列印外部檔案(JPS 強項)

JPS 提供 DocFlavor.INPUT_STREAM.* 系列,自動匹配列印服務支援的格式:

JFileChooser fc = new JFileChooser();
if (fc.showOpenDialog(this) == APPROVE_OPTION) {
    File file = fc.getSelectedFile();
    DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; // 自動偵測
    PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, null);
    PrintService svc = ServiceUI.printDialog(null, 200, 200, services, defaultSvc, flavor, null);
    if (svc != null) {
        DocPrintJob job = svc.createPrintJob();
        Doc doc = new SimpleDoc(new FileInputStream(file), flavor, null);
        job.print(doc, null);
    }
}

已知格式請指定具體 DocFlavor(如 INPUT_STREAM.PDF、INPUT_STREAM.GIF、INPUT_STREAM.TEXT_PLAIN_US_ASCII),提高成功率。

總結建議

  • 新專案優先使用 JPS (javax.print),功能完整、可擴展。
  • 複雜報表排版建議產出 PDF 再用 JPS 列印,或整合 iText/Apache PDFBox 直接生成 PDF。
  • 預覽與正式列印共用同一 Printable 實作,確保所見即所得。
  • 列印屬性(雙面、份數、紙張大小)皆透過 PrintRequestAttributeSet 設定。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved