You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:07:11