当前位置: 首页 > news >正文

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.dtcms.com/a/318222.html

相关文章:

  • 力扣热题100------136.只出现一次的数字
  • 【纵火犯的春天】纵火犯是如何解题leetcode的?
  • Python驱动的无人机多光谱-点云融合技术在生态三维建模与碳储量/生物量/LULC估算中的全流程实战
  • JDK9+ Method.class.getDeclaredFields() Method实例将不能再直接通过反射修改
  • 无人机航拍数据集|第4期 无人机太阳光伏板红外目标检测YOLO数据集10945张yolov11/yolov8/yolov5可训练
  • 大疆无人机使用eport连接Jetson主板实现目标检测
  • selenium操作指南
  • 前端路由守卫
  • JavaWeb服务器/servlet容器(Tomcat、Undertow 、WebLogic)
  • 前端应用场景题目(待总结优化)
  • 攻防世界WEB(新手模式)20-unseping
  • 基于 kubeadm 搭建 k8s 集群
  • 京东商品评论接口开发全指南:从数据获取到分析应用实战
  • 【20205CVPR-目标检测方向】基于事件的高效目标检测:具有空间和时间注意力的混合神经网络
  • Lodash 的终极进化Radashi
  • JAVA 程序员cursor 和idea 结合编程
  • 北京JAVA基础面试30天打卡03
  • SAP MR51 显示不是ALV格式的问题
  • 开源远程工具rustdesk
  • 力扣 hot100 Day67
  • Linux firewall 防火墙管理
  • SpringBoot 接入SSE实现消息实时推送的优点,原理以及实现
  • React:生命周期
  • 二、Istio流量治理(一)
  • 佳文鉴赏 || FD-LLM:用于机器故障诊断的大规模语言模型
  • 性能为王:一次从压测到调优的实战全流程复盘
  • PHP常用日期时间函数
  • 线程-线程池篇(二)
  • 【CSS】动态修改浏览器滚动条宽度
  • 楼宇自控系统对建筑碳中和目标的实现具重要价值