Android PDFBox 的使用指南

Android PDFBox 使用指南

概述

PDFBox是一個強大的PDF處理庫,在Android平臺上也有對應的實現。本指南將介紹如何在Android項目中使用PDFBox進行PDF文件的加載、讀取、修改等操作。

依賴配置

app/build.gradle 中添加PDFBox依賴:

dependencies {implementation 'com.tom-roush:pdfbox-android:2.0.27.0'
}

核心功能

1. 初始化PDFBox

在使用PDFBox之前,必須先初始化資源加載器:

// 在Application或Activity的onCreate中調用
PDFBoxResourceLoader.init(context)

2. 加載PDF文件

從Assets文件夾加載
fun loadPdfFromAssets(context: Context, fileName: String): PDDocument? {return try {context.assets.open(fileName).use { inputStream ->PDDocument.load(inputStream, MemoryUsageSetting.setupMixed(1000 * 1024 * 1024))}} catch (e: IOException) {null}
}
從文件路徑加載
fun loadPdfFromFile(filePath: String): PDDocument? {return try {PDDocument.load(File(filePath), MemoryUsageSetting.setupMixed(1000 * 1024 * 1024))} catch (e: IOException) {null}
}

3. 獲取PDF信息

fun getPdfInfo(document: PDDocument): String {val info = StringBuilder()// 獲取頁面數量val pageCount = document.numberOfPagesinfo.append("頁面數量: $pageCount\n")// 獲取文檔信息val documentInformation = document.documentInformationif (documentInformation != null) {info.append("標題: ${documentInformation.title ?: ""}\n")info.append("作者: ${documentInformation.author ?: ""}\n")info.append("主題: ${documentInformation.subject ?: ""}\n")info.append("創建者: ${documentInformation.creator ?: ""}\n")info.append("創建日期: ${documentInformation.creationDate ?: ""}\n")info.append("修改日期: ${documentInformation.modificationDate ?: ""}\n")}return info.toString()
}

4. 提取文本內容

提取整個文檔的文本
fun extractText(document: PDDocument): String {return try {val stripper = PDFTextStripper()stripper.text = document} catch (e: IOException) {"提取文本失敗"}
}
提取指定頁面的文本
fun extractTextFromPage(document: PDDocument, pageIndex: Int): String {return try {val stripper = PDFTextStripper()stripper.startPage = pageIndex + 1stripper.endPage = pageIndex + 1stripper.text = document} catch (e: IOException) {"提取頁面文本失敗"}
}

5. 獲取頁面信息

fun getPageInfo(document: PDDocument, pageIndex: Int): String {return try {val page = document.getPage(pageIndex)val mediaBox = page.mediaBoxval cropBox = page.cropBox"頁面 ${pageIndex + 1}:\n" +"媒體框 - 寬度: ${mediaBox.width}, 高度: ${mediaBox.height}\n" +"裁剪框 - 寬度: ${cropBox.width}, 高度: ${cropBox.height}\n" +"旋轉角度: ${page.rotation}°\n" +"注釋數量: ${page.annotations.size}"} catch (e: Exception) {"獲取頁面信息失敗"}
}

6. 添加注釋

添加文本注釋
fun addTextAnnotation(document: PDDocument, pageIndex: Int, x: Float, y: Float, text: String) {try {val page = document.getPage(pageIndex)val annotation = PDAnnotationInk()annotation.subtype = "FreeText"// 設置注釋位置和大小val rect = PDRectangle(x, y, x + 100, y + 50)annotation.rectangle = rect// 設置注釋內容annotation.contents = text// 設置顏色annotation.color = AWTColor.YELLOW// 添加到頁面page.annotations.add(annotation)} catch (e: Exception) {Log.e(TAG, "添加文本注釋失敗: ${e.message}")}
}
添加手繪注釋
fun addInkAnnotation(document: PDDocument, pageIndex: Int, points: List<FloatArray>) {try {val page = document.getPage(pageIndex)// 創建手繪注釋val inkAnnotation = PDAnnotationInk()inkAnnotation.subtype = "Ink"// 計算邊界val bounds = calculateInkBounds(points, page.mediaBox)inkAnnotation.rectangle = bounds// 創建外觀流val normalAppearance = PDAppearanceStream(document)normalAppearance.bBox = bounds// 繪制軌跡PDPageContentStream(document, normalAppearance).use { cs ->cs.setStrokingColor(AWTColor.RED)cs.setLineWidth(2f)for (path in points) {if (path.size >= 4) {cs.moveTo(path[0], path[1])for (index in 2 until path.size step 2) {cs.lineTo(path[index], path[index + 1])}cs.stroke()}}}// 設置外觀val apDict = COSDictionary()apDict.setItem(COSName.N, normalAppearance)inkAnnotation.cosObject.setItem(COSName.AP, apDict)// 添加到頁面page.annotations.add(inkAnnotation)} catch (e: Exception) {Log.e(TAG, "添加手繪注釋失敗: ${e.message}")}
}

7. 保存PDF文件

fun savePdf(document: PDDocument, outputPath: String): Boolean {return try {document.save(outputPath)true} catch (e: IOException) {false}
}

8. 關閉文檔

fun closeDocument(document: PDDocument) {try {document.close()} catch (e: IOException) {Log.e(TAG, "關閉PDF文檔失敗: ${e.message}")}
}

使用示例

完整處理流程示例

fun processPdfExample(context: Context, fileName: String) {// 1. 加載PDFval document = loadPdfFromAssets(context, fileName)if (document == null) {Log.e(TAG, "無法加載PDF文件")return}try {// 2. 獲取PDF信息val info = getPdfInfo(document)Log.i(TAG, "PDF信息:\n$info")// 3. 提取文本val text = extractText(document)Log.i(TAG, "PDF文本內容:\n$text")// 4. 獲取第一頁信息if (document.numberOfPages > 0) {val pageInfo = getPageInfo(document, 0)Log.i(TAG, "第一頁信息:\n$pageInfo")// 5. 添加文本注釋addTextAnnotation(document, 0, 100f, 100f, "這是一個測試注釋")// 6. 添加手繪注釋示例val samplePoints = listOf(floatArrayOf(50f, 50f, 100f, 100f, 150f, 50f),floatArrayOf(200f, 200f, 250f, 250f, 300f, 200f))addInkAnnotation(document, 0, samplePoints)}// 7. 保存修改后的PDFval outputPath = context.getExternalFilesDir(null)?.absolutePath + "/modified_$fileName"if (savePdf(document, outputPath)) {Log.i(TAG, "PDF處理完成,已保存到: $outputPath")}} finally {// 8. 關閉文檔closeDocument(document)}
}

注意事項

  1. 內存管理: PDFBox需要大量內存,建議使用MemoryUsageSetting.setupMixed()來優化內存使用。

  2. 異常處理: 所有PDF操作都應該包含適當的異常處理。

  3. 資源釋放: 使用完PDF文檔后,務必調用close()方法釋放資源。

  4. 線程安全: PDFBox操作應該在后臺線程中執行,避免阻塞UI線程。

  5. 文件權限: 確保應用有適當的文件讀寫權限。

更多資源

  • PDFBox Android GitHub
  • PDFBox 官方文檔
  • Android 開發文檔

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

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

相關文章

TFTP: Linux 系統安裝 TFTP,文件系統啟動后TFTP使用

安裝 TFTP 服務器 sudo apt update sudo apt install tftpd-hpa配置 TFTP 服務器 編輯配置文件 /etc/default/tftpd-hpa&#xff1a; sudo nano /etc/default/tftpd-hpa 修改內容如下&#xff1a; TFTP_USERNAME"tftp" TFTP_DIRECTORY"/srv/tftp" TFTP_ADD…

昇思+昇騰開發板+DeepSeek模型LoRA微調

昇思昇騰開發板DeepSeek模型LoRA微調 LoRA微調原理核心思想&#xff1a;凍結預訓練模型權重&#xff0c;僅訓練橙色的低秩適配矩陣&#xff08;A/B矩陣&#xff09;優勢&#xff1a; 訓練參數量減少至全量微調的0.5%顯存占用降低50%以上適配器權重僅需保存3MB&#xff08;原模型…

計算機網絡:詳解網絡地址的計算步驟

網絡地址計算是網絡規劃與配置的基礎,核心是通過IP地址和子網掩碼確定網絡標識、廣播地址、可用主機范圍等關鍵信息。以下是詳細的計算步驟,配合實例說明(以IPv4為例): 一、明確基礎概念 在計算前,需先明確3個核心概念: IP地址:標識網絡中主機的32位二進制數,通常以…

Spring AI 系列之三十五 - Spring AI Alibaba-Graph框架之MCP

之前做個幾個大模型的應用&#xff0c;都是使用Python語言&#xff0c;后來有一個項目使用了Java&#xff0c;并使用了Spring AI框架。隨著Spring AI不斷地完善&#xff0c;最近它發布了1.0正式版&#xff0c;意味著它已經能很好的作為企業級生產環境的使用。對于Java開發者來說…

FastAPI后端工程化項目記錄

以下是一個使用fastapi上傳視頻的接口&#xff0c;記錄一下工程化后端程序的業務邏輯 重點是代碼如何抽離 項目結構優化 project/ ├── .env # 環境變量配置 ├── app/ │ ├── __init__.py │ ├── main.py # 主應用入口 │ …

令牌桶限流算法

你提供的 Java 代碼實現的是令牌桶限流算法&#xff08;Token Bucket Algorithm&#xff09;&#xff0c;這是目前最常用、最靈活的限流算法之一。它允許一定程度的“突發流量”&#xff0c;同時又能控制平均速率。下面我將&#xff1a;逐行詳細解釋 TokenBucketLimiter 類的每…

基于springboot的寵物商城設計與實現

管理員&#xff1a;登錄&#xff0c;個人中心&#xff0c;用戶管埋&#xff0c;寵物分類管理&#xff0c;寵物信息管理&#xff0c;留言反饋&#xff0c;寵物論壇&#xff0c;系統管理&#xff0c;訂單管理用戶&#xff1a;寵物信息&#xff0c;寵物論壇&#xff0c;公告信息&a…

Python day36

浙大疏錦行 Python day36. 復習日 本周內容&#xff1a; 如何導入模塊以及庫項目的規范拆分和寫法官方文檔的閱讀MLP神經網絡的訓練在GPU上訓練模型可視化以及推理

【gaussian-splatting】用自己的數據復現高斯潑濺(一)

1.環境準備1.1.下載diff-gaussian-rasterization這里本來沒啥說的&#xff0c;直接從github上下載就行了&#xff0c;但是我踩坑了&#xff0c;下的版本不對&#xff0c;后續運行報錯參數個數對不上&#xff0c;特在此給大家避坑&#xff0c;注意一定要下帶3dgs版本的diff-gaus…

中國移動h10g-01_S905L處理器安卓7.1當貝純凈版線刷機包帶root權限_融合終端網關

下載固件之前請先將主板上的屏蔽罩取下&#xff0c;查看處理器型號 是否為S905L型號&#xff0c;然后再下載固件進行刷機&#xff1b; 本頁面的固件是采用雙公頭數據線進行刷機的哈&#xff1b; 安卓4.4.2版本固件下載地址&#xff1a;點此進行下載 安卓7.1版本固件下載地址…

夜天之書 #110 涓滴開源:Cronexpr 的故事

在年初的一篇關于商業開源的博文當中&#xff0c;我介紹了在開發商業軟件的過程中&#xff0c;衍生出開源公共軟件庫的模式。在那篇博文里面&#xff0c;我只是簡單羅列了相關開源庫的名字及一句話總結。近期&#xff0c;我會結合商業開源實踐的最新進展&#xff0c;對其中一些…

完整的登陸學生管理系統(配置數據庫)

目錄 要求 思路 1. 登錄模塊&#xff08;LoginFrame.java&#xff09; 2. 學生信息管理模塊&#xff08;StudentFrame.java&#xff09; 3. 數據層&#xff08;StudentDAO.java&#xff09; 4. 業務層&#xff08;StudentService.java / UserService.java&#xff09; 5…

譯 | 在 Python 中從頭開始構建 Qwen-3 MoE

文章出自&#xff1a;基于 2個Expert 的 MoE 架構分步指南 本篇適合 MoE 架構初學者。文章亮點在于詳細拆解 Qwen 3 MoE 架構&#xff0c;并用簡單代碼從零實現 MoE 路由器、RMSNorm 等核心組件&#xff0c;便于理解內部原理。 該方法適用于需部署高性能、高效率大模型&#x…

Spring Boot + ShardingSphere 分庫分表實戰

&#x1f680;Spring Boot ShardingSphere 實戰&#xff1a;分庫分表&#xff0c;性能暴增的終極指南&#xff01; ? 適用場景&#xff1a;千萬級大表、高并發、讀寫分離場景 ? 核心框架&#xff1a;Spring Boot 3.x ShardingSphere-JDBC 5.4.1 ? 數據庫&#xff1a;MySQL…

MaxKB 使用 MCP 連接 Oracle (免安裝 cx_Oracle 和 Oracle Instant Client)

一、背景 安裝cx_Oracle包和Oracle Instant Client來操作數據庫&#xff0c;比較繁瑣同時容易沖突&#xff0c;不同的 Oracle 版本都需要安裝不同的插件。這篇文章將介紹使用 MCP 協議的連接方法。 二、操作步驟 1、使用 1Panel 安裝 DBhub a) 數據庫類型選擇 Oracle 類型。…

基于Python的超聲波OFDM數字通信鏈路設計與實現

基于Python的超聲波OFDM數字通信鏈路設計與實現 摘要 本文詳細介紹了使用Python實現的超聲波OFDM(正交頻分復用)數字通信鏈路系統。該系統能夠在標準音響設備上運行&#xff0c;利用高于15kHz的超聲波頻段進行數據傳輸&#xff0c;采用48kHz采樣率。文章涵蓋了從OFDM基本原理、…

滑動窗口相關題目

近些年來&#xff0c;我國防沙治沙取得顯著成果。某沙漠新種植N棵胡楊&#xff08;編號1-N&#xff09;&#xff0c;排成一排。一個月后&#xff0c;有M棵胡楊未能成活。現可補種胡楊K棵&#xff0c;請問如何補種&#xff08;只能補種&#xff0c;不能新種&#xff09;&#xf…

Java 工具類的“活化石”:Apache Commons 核心用法、性能陷阱與現代替代方案

在上一篇文章中&#xff0c;我們回顧了 Apache Commons 的經典組件。但作為 Java 世界中資歷最老、影響最深遠的工具庫&#xff0c;它的價值遠不止于此。許多開發者可能只使用了它 10% 的功能&#xff0c;卻忽略了另外 80% 能極大提升代碼質量的“隱藏寶石”。本文將提供一個更…

數據結構——圖及其C++實現 多源最短路徑 FloydWarshall算法

目錄 一、前言 二、算法思想 三、代碼實現 四、測試 五、源碼 一、前言 前兩篇學習的Dijkstra算法和Bellman-Ford算法都是用來求解圖的單源最短路徑&#xff0c;即從圖中指定的一個源點出發到圖中其他任意頂點的最短路徑。Dijkstra算法不能求解帶有負權重的圖的最短路徑&…

解決微軟應用商店 (Microsoft store) 打不開,無網絡連接的問題!

很多小伙伴都會遇見微軟應用商店 (Microsoft store)打開后出現無網絡的問題&#xff0c;一般出現這種問題基本都是因為你的電腦安裝了某些銀行的網銀工具&#xff0c;因為網銀工具為了安全會關閉Internet 選項中的最新版本的TLS協議&#xff0c;而微軟商店又需要最新的TLS協議才…