使用iText填充PDF表单触发PDF header not found异常,求解决方案
解决iText读取PDF表单的问题
一、先搞定assets目录下的PDF读取报错
出现PDF header not found基本是这几个原因,挨个排查:
- 核对文件名:确认assets里的文件确实叫
valoracion_01.pdf,Android assets目录对大小写敏感,别写错字母;如果文件在assets的子文件夹里,要写完整路径,比如forms/valoracion_01.pdf。 - 检查文件完整性:把assets里的PDF导出来用阅读器打开,确认文件没损坏,是标准PDF格式——别把空文件或者非PDF的文件塞进去了。
- 重置流指针:有时候打开流后指针不在起始位置,导致iText读不到PDF头,加个重置操作:
val src: InputStream = am.open("valoracion_01.pdf") src.reset() // 确保流从开头读 val reader = PdfReader(src)
二、把PDF移到data目录的实现步骤
要是你打算把PDF放在app私有data目录(不用申请存储权限,更安全),按下面来:
- 先把assets里的PDF复制到data目录
首次启动app时执行复制逻辑,避免重复复制:
private fun copyAssetToFilesDir(context: Context, assetName: String) { val targetFile = File(context.filesDir, assetName) if (targetFile.exists()) return try { context.assets.open(assetName).use { input -> FileOutputStream(targetFile).use { output -> input.copyTo(output) } } } catch (e: IOException) { e.printStackTrace() } }
- 从data目录读取并填充表单
复制完成后,直接用文件路径创建PdfReader,避免流的问题:
// 获取data目录下的PDF文件 val pdfSource = File(filesDir, "valoracion_01.pdf") // 创建输出文件(填充后的PDF) val pdfDest = File(filesDir, "filled_form.pdf") val reader = PdfReader(pdfSource.absolutePath) val writer = PdfWriter(pdfDest) val pdfDoc = PdfDocument(reader, writer) // 填充表单的示例代码 val acroForm = PdfAcroForm.getAcroForm(pdfDoc, true) acroForm.getField("your_field_name")?.setValue("要填充的内容") // 别忘了关闭资源 pdfDoc.close() reader.close()
额外提醒
- 所有文件操作都要捕获IOException,避免app崩溃。
- Android 10及以上,私有data目录(
filesDir对应的路径)不需要申请任何存储权限,完全合规。 - 填充后的PDF存在同一个目录里,后续可以通过文件流或者ContentProvider分享给其他应用。
内容的提问来源于stack exchange,提问作者Pablo AR
相关产品推荐
相关产品推荐

