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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:37:40