Fragment中加载Assets字体生成PDF遇FileNotFoundException问题
解决Android Fragment中iText加载自定义字体时FileNotFoundException的问题
问题原因排查与修复方案
1. 确认assets目录结构与文件匹配
- 首先检查项目中是否存在
src/main/assets/font/目录,且yekanbakh.ttf确实放在该路径下。Android的assets路径严格区分大小写,文件名、文件夹名必须和代码里的完全一致(比如不能写成YekanBakh.ttf或者Font/)。 - 如果字体直接放在
assets根目录下,代码里的路径要改成"yekanbakh.ttf",而不是"font/yekanbakh.ttf"。
2. 利用res/font目录的字体加载(更可靠)
既然你已经通过ResourcesCompat.getFont(requireContext(), R.font.yekanbakh)获取了Typeface,说明字体已经放在res/font目录下——Android会自动把res/font里的字体打包到APK的assets/fonts/路径下,直接用这个路径加载即可:
val fontData = requireContext().assets.open("fonts/yekanbakh.ttf").readBytes() val fontProgram = FontProgramFactory.createFont(fontData) val myFont = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, true)
3. 额外检查项
- 确保
build.gradle(Module级)没有排除ttf文件,添加以下配置保证assets目录被正确识别:
android { sourceSets { main { assets.srcDirs = ['src/main/assets'] } } }
- 执行Clean Project后再Rebuild Project,避免缓存导致文件找不到。
修改后的完整代码示例
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val name = "hoghugh${Random.nextInt(1..1000)}" val myFile = File(dir, "$name.pdf") try { val fileOutputStream = FileOutputStream(myFile) val pdfWriter = PdfWriter(fileOutputStream) val pdfDocument = PdfDocument(pdfWriter) val context = requireContext() var myFont: PdfFont? = null try { // 从assets/fonts/加载res/font目录下的字体 val fontData = context.assets.open("fonts/yekanbakh.ttf").readBytes() val fontProgram = FontProgramFactory.createFont(fontData) myFont = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, true) } catch (e: IOException) { e.printStackTrace() // 加载失败时使用默认字体兜底 myFont = PdfFontFactory.createFont() } val document = Document(pdfDocument, PageSize.A4) // 段落应用自定义字体 document.add(Paragraph(line1).setFont(myFont)) document.add(Paragraph(line2).setFont(myFont)) // 表格也应用自定义字体,避免波斯/阿拉伯字符显示异常 val table1 = Table(subHeaders1.size) .useAllAvailableWidth() .setFontSize(10f) .setFont(myFont) subHeaders1.forEach { col -> table1.addHeaderCell(col) } body1.forEach { row -> row.forEach { col -> table1.addCell(col.toString()) } } document.add(table1) val table2 = Table(subHeaders2.size) .useAllAvailableWidth() .setFontSize(10f) .setFont(myFont) subHeaders2.forEach { col -> table2.addHeaderCell(col.toString()) } body2.forEach { row -> row.forEach { col -> table2.addCell(col.toString()) } } document.add(table2) val table3 = Table(subHeaders3.size) .useAllAvailableWidth() .setFontSize(10f) .setFont(myFont) subHeaders3.forEach { col -> table3.addHeaderCell(col) } body1.forEach { row -> row.forEach { col -> table3.addCell(col.toString()) } } document.add(table3) // 最后一段也建议应用自定义字体 document.add(Paragraph(line3).setFont(myFont)) document.close() fileOutputStream.close() } catch (e: Exception) { e.printStackTrace() }
内容的提问来源于stack exchange,提问作者pouya
相关产品推荐
相关产品推荐

