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

iText 實戰:在現有 PDF 中新增文字、圖片與圖形的最佳實踐

     編輯:Java 綜合教學

核心難題:直接修改原 PDF 會導致流衝突,需「讀副本、寫原檔」模式

業務常見需求:在已生成的 PDF(如合同、報表)上動態添加水印、簽章、批註。iText 的 `PdfStamper` 是核心工具,但直接「讀原檔、寫原檔」會因文件已被 `PdfReader` 鎖定而失敗。

解決方案:文件通道複製 + 覆寫原檔

  1. 使用 `FileChannel.transferTo()` 高效複製原 PDF 為臨時副本。
  2. `PdfReader` 讀取副本,`PdfStamper` 寫回目標原檔路徑。
  3. 操作完成後刪除臨時副本,保持原檔屬性(路徑、名稱、資料庫記錄)不變。

核心代碼實現

// 1. 管道複製原檔為副本
FileUtil.fileChannelCopy(new File("E:\\A.pdf"), new File("E:\\A_tmp.pdf"));

// 2. 讀取副本,寫入原檔
PdfReader reader = new PdfReader("E:\\A_tmp.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\\A.pdf"));
PdfContentByte over = stamper.getOverContent(1); // 獲取第 1 頁的繪圖畫布(上層)

// 3. 添加文字
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
over.beginText();
over.setFontAndSize(font, 10);
over.setTextMatrix(200, 200);
over.showTextAligned(Element.ALIGN_CENTER, "需要添加的文字", 580, 530, 0);
over.endText();

// 4. 添加圖片
PdfDictionary pageDict = reader.getPageN(1);
PdfArray mediaBox = (PdfArray) pageDict.get(PdfName.MEDIABOX);
Image img = Image.getInstance("D:\\1.jpg");
img.setAbsolutePosition(100, 100);
over.addImage(img);

// 5. 繪製紅色圓圈
over.setRGBColorStroke(0xFF, 0x00, 0x00);
over.setLineWidth(5f);
over.ellipse(250, 450, 350, 550);
over.stroke();

// 6. 關閉資源(必須調用,否則 PDF 損壞)
stamper.close();
reader.close();
// 7. 刪除臨時副本
Files.deleteIfExists(Paths.get("E:\\A_tmp.pdf"));

文件通道複製工具類

public static void fileChannelCopy(File src, File dest) {
    try (FileInputStream in = new FileInputStream(src);
         FileOutputStream out = new FileOutputStream(dest);
         FileChannel inCh = in.getChannel();
         FileChannel outCh = out.getChannel()) {
        inCh.transferTo(0, inCh.size(), outCh);
    } catch (IOException e) {
        throw new RuntimeException("PDF 複製失敗", e);
    }
}

流程圖解

直接讀寫失敗流程

副本模式成功流程

關鍵優勢

  • 原 PDF 路徑、名稱、資料庫記錄完全不變,零業務入侵。
  • `FileChannel` 複製屬於 OS 級零拷貝,大文件效能極高。
  • 支持文字、圖片、向量圖形、水印等豐富內容疊加。

避坑指南

  1. 務必在 `finally` 或 try-with-resources 中關閉 `PdfStamper`、`PdfReader`、流對象。
  2. 中文字體必須指定支持中文的編碼(如 `UniGB-UCS2-H`),否則顯示亂碼。
  3. 座標系統原點在頁面左下角,單位為點(1/72 英寸)。
  4. 生產環境建議引入字體文件(`.ttf`)而非依賴系統字體,保證跨環境一致性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved