Android Kotlin中如何解码PDF文件提取的乱码文本?
解决PDF文本提取乱码问题
你现在的问题核心是把PDF当成纯文本文件读取了,PDF是二进制格式,内部包含压缩内容、字体映射等信息,不是普通文本文件,直接用InputStreamReader读肯定会乱码——那些乱码是PDF的二进制流和压缩数据,和字符编码(UTF-8之类)没关系,换编码也没用。
正确解决方案:用专门的PDF文本提取库
推荐使用Apache PDFBox(轻量、易用),步骤如下:
1. 添加依赖
在你的Module级build.gradle.kts(或build.gradle)里添加PDFBox依赖:
dependencies { implementation("org.apache.pdfbox:pdfbox:2.0.32") // 若需处理加密PDF,额外添加 implementation("org.apache.pdfbox:pdfbox-tools:2.0.32") }
2. 替换文本读取方法
修改readTextFromUri方法,用PDFBox解析PDF并提取文本:
@Throws(IOException::class) fun readTextFromUri(uri: Uri): String { val stringBuilder = StringBuilder() contentResolver.openInputStream(uri)?.use { inputStream -> // 加载PDF文档 PDDocument.load(inputStream).use { document -> if (!document.isEncrypted) { // 提取文本 val stripper = PDFTextStripper() stringBuilder.append(stripper.getText(document)) } else { // 处理加密PDF,可提示用户或用解密工具 stringBuilder.append("该PDF已加密,无法提取文本") } } } Log.d(TAG, "提取的文本: $stringBuilder") return stringBuilder.toString() }
3. 修正Compose状态变量
原来的stringResult是普通remember变量,修改后不会触发UI重组,要改成可观察状态:
val stringResult = remember { mutableStateOf("") }
在launcher回调里更新状态:
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri -> result.value = uri uri?.let { stringResult.value = readTextFromUri(it) } }
4. 更新UI显示
把UI里的显示内容改成stringResult:
Row { Text(text = "提取的文本: ${stringResult.value}") }
补充说明
- 若提取文本不准确,可能是PDF字体嵌入问题,或是扫描版PDF(图片格式),这种情况需要配合OCR工具(如Tesseract)处理。
- 你原来代码里的
readText()会一次性读取所有内容,后续readLine()直接返回null,循环是多余的,但这不是乱码的核心原因。
内容的提问来源于stack exchange,提问作者ollo
相关产品推荐
相关产品推荐

