使用Java和iText庫填充PDF表單域的完整指南

PDF表單是企業和機構常用的數據收集工具,而通過編程方式自動填充PDF表單可以大大提高工作效率。本文將詳細介紹如何使用Java和iText庫來實現PDF表單的自動化填充。

為什么選擇iText庫?

iText是一個強大的PDF操作庫,具有以下優勢:

  • 功能全面,支持PDF創建、編輯和填充

  • 性能優異,適合處理大量PDF文檔

  • 支持復雜的PDF操作如表單填充、數字簽名等

  • 活躍的社區支持和良好的文檔

環境準備

在開始之前,請確保:

  1. 項目中已添加iText依賴(Maven配置如下)

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version>
</dependency>
  1. 準備好PDF表單模板(確保是可填寫的PDF表單),具體可以查看使用Adobe Acrobat DC創建PDF表單域的完整指南-CSDN博客

  2. 準備好要填充的數據

核心代碼解析

1. 基本表單填充

public static void fillPDFTemplate(Map<String,Object> sourceMap) {PdfReader reader = null;FileOutputStream out = null;try {// 設置中文字體BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);// 讀取PDF模板reader = new PdfReader(TEMPLATE_PATH);out = new FileOutputStream(NEW_PDF_PATH);PdfStamper stamper = new PdfStamper(reader, out);AcroFields form = stamper.getAcroFields();// 填充文本數據Map<String, String> dataMap = (Map<String,String>) sourceMap.get("dataMap");form.addSubstitutionFont(bfChinese);for(String key : dataMap.keySet()){form.setField(key, dataMap.get(key));}stamper.setFormFlattening(true); // 使表單不可編輯stamper.close();} catch (Exception e) {e.printStackTrace();} finally {// 關閉資源}
}

2. 高級功能:處理多行文本和自動換行

TextField textField = new TextField(stamper.getWriter(), rect, key);
textField.setFont(baseFont);
textField.setFontSize(fontSize);
if (!canFitInOneLine) {textField.setOptions(TextField.MULTILINE | TextField.DO_NOT_SCROLL);
}
textField.setText(text);// 智能對齊:單行居中,多行左對齊
PdfFormField field = textField.getTextField();
field.setQuadding(canFitInOneLine ? PdfFormField.Q_CENTER : PdfFormField.Q_LEFT);// 替換原字段
form.removeField(key);
stamper.addAnnotation(field, 1);

3. 處理圖片字段

// 獲取圖片位置信息
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;// 創建圖片對象
Image image = createPdfImage(imageObj);
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
image.setAbsolutePosition(x, y);// 添加圖片到PDF
PdfContentByte under = stamper.getOverContent(pageNo);
under.addImage(image);

完整實現步驟

  1. 加載PDF模板:使用PdfReader讀取模板文件

  2. 準備輸出流:創建FileOutputStreamByteArrayOutputStream

  3. 創建PdfStamper:用于修改PDF內容

  4. 獲取表單域:通過AcroFields訪問表單字段

  5. 設置字體:解決中文顯示問題

  6. 填充文本數據:遍歷數據Map并設置字段值

  7. 處理圖片數據:計算位置并插入圖片

  8. 設置表單狀態setFormFlattening決定是否鎖定表單

  9. 保存輸出:關閉stamper并輸出結果

中文顯示問題解決方案

處理PDF中文顯示是常見挑戰,以下是幾種解決方案:

方案1:使用系統字體

BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

方案2:使用自定義字體文件

BaseFont.createFont("font/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

跨平臺兼容處理

BaseFont bfChinese;
if(isWindowsSystem()){bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
} else {bfChinese = BaseFont.createFont("font/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
}

圖片處理技巧

iText支持多種圖片源:

  • 文件路徑

  • BufferedImage對象

  • 字節數組

private static Image createPdfImage(Object imageObj) throws Exception {if (imageObj instanceof String) {return Image.getInstance((String) imageObj);} else if (imageObj instanceof BufferedImage) {BufferedImage bufferedImage = (BufferedImage) imageObj;ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "png", baos);return Image.getInstance(baos.toByteArray());} else if (imageObj instanceof byte[]) {return Image.getInstance((byte[]) imageObj);} else {throw new IllegalArgumentException("不支持的圖片類型");}
}

最佳實踐

  1. 資源管理:確保正確關閉所有流和reader

  2. 錯誤處理:捕獲并記錄可能出現的異常

  3. 性能優化:對于批量處理,考慮重用某些對象

  4. 表單設計:提前規劃好表單字段命名規范

  5. 日志記錄:記錄關鍵操作便于調試

常見問題解決

  1. 中文顯示為空白:檢查字體是否正確設置和嵌入

  2. 字段無法填充:確認字段名稱匹配且PDF是可填寫的表單

  3. 圖片位置不正確:仔細檢查坐標計算邏輯

  4. 內存泄漏:確保所有資源都被正確關閉

結語

通過本文介紹的方法,您可以使用Java和iText庫高效地實現PDF表單的自動化填充。無論是簡單的文本字段還是復雜的圖片和格式要求,iText都提供了強大的支持。根據實際需求選擇合適的實現方式,可以大大提高PDF處理的自動化程度和工作效率。

完整的示例代碼已在文章中展示,您可以根據自己的需求進行調整和擴展。希望這篇指南能幫助您更好地理解和應用PDF表單處理技術!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89010.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89010.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89010.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

跟著AI學習C#之項目實踐Day6

&#x1f4c5; Day 6&#xff1a;實現文章搜索功能&#xff08;Search System&#xff09; ? 今日目標&#xff1a; 實現按 標題、內容、作者 搜索文章使用 LINQ 構建動態查詢條件添加搜索框 UI 界面可選&#xff1a;使用全文搜索優化&#xff08;如 SQL Server 全文索引&am…

Learning to Prompt for Continual Learning

Abstract 持續學習背后的主流范式是使模型參數適應非平穩數據分布&#xff0c;其中災難性遺忘是核心挑戰。典型方法依賴于排練緩沖區或測試時已知的任務標識來檢索已學知識并解決遺忘問題&#xff0c;而這項工作提出了一種持續學習的新范式&#xff0c;旨在訓練一個更簡潔的記…

【論文閱讀筆記】知網SCI——基于主成分分析的空間外差干涉數據校正研究

論文詞條選擇 —— 知網 【SCI】【數據分析】 題目&#xff1a;基于主成分分析的空間外差干涉數據校正研究 原文摘要&#xff1a; 空間外差光譜技術(SHS)是一種新型的高光譜遙感探測技術&#xff0c;被廣泛應用于大氣觀測、天文遙感、物質識別等領域。通過空間外差光譜儀獲取…

如何用VS Code、Sublime Text開發51單片機

文章目錄 一、前置工作二、VS Code2.1 Code Runner配置2.2 編譯快捷鍵 三、Sublime Text3.1 Build System創建3.2 編譯快捷鍵 四、使用STC-ISP下載代碼到單片機 使用VS Code開發51單片機的好處自不必多說&#xff0c;直接進入正題。本博客的目標是讓你能夠使用VS Code或者Subli…

信息抽取數據集全景分析:分類體系、技術演進與挑戰_DEEPSEEK

信息抽取數據集全景分析&#xff1a;分類體系、技術演進與挑戰 摘要 信息抽取&#xff08;IE&#xff09;作為自然語言處理的核心任務&#xff0c;是構建知識圖譜、支持智能問答等應用的基礎。近年來&#xff0c;隨著深度學習技術的發展和大規模預訓練模型的興起&#xff0c;…

利用 Python 腳本批量查找并刪除指定 IP 的 AWS Lightsail 實例

在 AWS Lightsail 管理中&#xff0c;隨著實例數量的增多&#xff0c;我們常常會遇到這樣一個問題&#xff1a; “我知道某個公網 IP 地址&#xff0c;但不知道它關聯的是哪臺實例。” 或者&#xff1a; “我有一批老舊的實例只知道 IP&#xff0c;需要一鍵定位并選擇刪除。…

CompletableFuture 深度解析

本文將探討 Java 8 引入的 CompletableFuture&#xff0c;一個在異步編程中實現非阻塞、可組合操作的強大工具。我們將從 CompletableFuture 的基本概念、與傳統 Future 的區別、核心 API 用法&#xff0c;到復雜的鏈式調用、組合操作以及異常處理進行全面解析&#xff0c;并通…

給自己網站增加一個免費的AI助手,純HTML

助手效果圖 看完這篇文章&#xff0c;你將免費擁有你自己的Ai助手&#xff0c;全程干貨&#xff0c;先到先得 獲取免費的AI大模型接口 訪問這個地址 生成key https://openrouter.ai/mistralai/mistral-small-3.2-24b-instruct:free/api 或者調用其他的免費大模型&#xff0c;這…

ASProxy64.dll導致jetbrains家的IDE都無法打開。

在Windows11中,無法打開jetbrains的IDE的軟件,經過排查,發現與ASProxy64.dll有關。 E:\idea\IntelliJ IDEA 2024.1.7\bin>idea.bat CompileCommand: exclude com/intellij/openapi/vfs/impl/FilePartNodeRoot.trieDescend bool exclude = true # # A fatal error has bee…

springboot+Vue逍遙大藥房管理系統

概述 基于springbootVue開發的逍遙大藥房管理系統。該系統功能完善&#xff0c;既包含強大的后臺管理模塊&#xff0c;又具備用戶友好的前臺展示界面。 主要內容 一、后臺管理系統功能 ??核心管理模塊??&#xff1a; 用戶管理&#xff1a;管理員與普通用戶權限分級藥品分…

探索阿里云智能媒體管理IMM:解鎖媒體處理新境界

一、引言&#xff1a;開啟智能媒體管理新時代 在數字化浪潮的席卷下&#xff0c;媒體行業正經歷著前所未有的變革。從傳統媒體到新媒體的轉型&#xff0c;從內容生產到傳播分發&#xff0c;每一個環節都在尋求更高效、更智能的解決方案。而云計算&#xff0c;作為推動這一變革…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的新生報道管理系統,推薦!

摘要 隨著信息技術在管理上越來越深入而廣泛的應用&#xff0c;管理信息系統的實施在技術上已逐步成熟。本文介紹了新生報道管理系統的開發全過程。通過分析高校新生入學報到信息管理的不足&#xff0c;創建了一個計算機管理高校新生入學報到信息的方案。文章介紹了新生報道管…

給定一個整型矩陣map,求最大的矩形區域為1的數量

題目: 給定一個整型矩陣map,其中的值只有0和1兩種,求其中全是1的 所有矩形區域中,最大的矩形區域為1的數量。 例如: 1 1 1 0 其中,最大的矩形區域有3個1,所以返回3。 再如: 1 0 1 1 1 1 1 1 1 1 1 0 其中,最大的矩形區域有6個1,所以返回6。 解題思…

第8章-財務數據

get_fund # 查看股票代碼000001.XSHE在2022年9月1日的總市值 q query( valuation ).filter( valuation.code 000001.XSHE ) df get_fundamentals(q, 2022-09-01) print(df[market_cap][0]) # 獲取第一行的market_cap值 這段代碼看起來是用于查詢股票在特定日期的總…

SQL關鍵字三分鐘入門:ROW_NUMBER() —— 窗口函數為每一行編號

在進行數據分析時&#xff0c;我們常常需要為查詢結果集中的每條記錄生成一個唯一的序號或行號。例如&#xff1a; 為每位員工按照入職時間排序并編號&#xff1b;按照訂單金額對訂單進行排序&#xff0c;并給每個訂單分配一個順序編號&#xff1b;在分組數據內為每條記錄編號…

微信小程序如何實現通過郵箱驗證修改密碼功能

基于騰訊云開發&#xff08;Tencent Cloud Base&#xff09;實現小程序郵箱驗證找回密碼功能的完整邏輯說明及關鍵代碼實現。結合安全性和開發效率&#xff0c;方案采用 ??云函數 小程序前端?? 的架構&#xff0c;使用 ??Nodemailer?? 發送郵件。Nodemailer 是一個專為…

C# VB.NET中Tuple輕量級數據結構和固定長度數組

C# VB.NET取字符串中全角字符數量和半角字符數量-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148871910 在VB.NET中&#xff0c;使用Tuple和固定長度數組在性能上有細微差異&#xff0c;以下是詳細分析&#xff1a; 性能對比測試 通過測試 100 萬次調用&am…

建筑物年代預測與空間異質性分析解決方案

建筑物年代預測與空間異質性分析解決方案 1. 問題分析與創新點設計 核心任務:預測建筑物建造年代,并分析空間異質性對預測的影響 創新點設計: 空間權重矩陣集成:構建空間鄰接矩陣量化地理鄰近效應多尺度特征提取:融合建筑物微觀特征與街區宏觀特征異質性分區建模:基于…

FOUPK3system5XOS

Foupk3systemX5OS系統19.60內測版&#xff08;X9&#xff09;2023年4月16日正式發布 1.0Foupk3systemX5OS系統19.60&#xff08;X9&#xff09;2024年10月6日發布 Foupk3systemX5OS系統19.60增強版&#xff08;X9X5&#xff09;2024年10月6日發布Foupk3systemX5OS系統19.60正…

隨機生成的亂碼域名”常由**域名生成算法(DGA)** 產生

“隨機生成的亂碼域名”常由**域名生成算法&#xff08;DGA&#xff09;** 產生&#xff0c;是網絡攻擊&#xff08;尤其是僵尸網絡、惡意軟件控制場景 &#xff09;中躲避檢測的手段&#xff0c;以下是關鍵解析&#xff1a; ### 一、本質與產生邏輯 亂碼域名是攻擊者利用 **DG…