我正在尝试使用 PDFBox 2.0.8 填写一堆 PDF 表单。对于某些文档,在设置 PDTextField 的值时出现以下错误:
java.io.IOException: Could not find font: /ArialMT
Run Code Online (Sandbox Code Playgroud)
显然,该字体未正确嵌入,就像 Microsoft 专有字体经常出现的情况一样。
我如何告诉 PDFBox 用“普通”Arial 或其他字体替换字体?将字段 DA 字符串设置为"/Helv 0 tf 0 g"导致 NullPointerException。
根据 Tilman Hausherr 的评论,我构建了第一个修复程序,该修复程序独立于操作系统(在我的例子中是 Linux)工作。
acroForm.defaultResources.put(COSName.getPDFName("ArialMT"),
PDType0Font.load (pdDocument, this.javaClass.classLoader.getResourceAsStream("fonts/ARIALMT.ttf"), false))
Run Code Online (Sandbox Code Playgroud)
不过,这仅适用于该特定字体。仍然缺少的 - 实际上是我问题的主要目的 - 是告诉 PDFBox 回退到特定字体的选项。如果无法提供所需的字体,则为 DA。
在蒂尔曼再次前来救援之后,我现在可以提出完整的解决方案。再次强调,这是 Kotlin,不是 Java:
PDDocument.load(file).use { pdDocument ->
val acroForm = pdDocument.documentCatalog.acroForm
acroForm.defaultResources.put(COSName.getPDFName("ArialMT"),
PDType0Font.load (pdDocument, this.javaClass.classLoader.getResourceAsStream("fonts/ARIALMT.ttf"), false))
val pdField: PDField? = acroForm.getField(fieldname)
val value = ...
when (pdField) {
is PDCheckBox -> {
if (value is Boolean) {
when (value) {
true -> pdField.check()
false -> pdField.unCheck()
}
} else {
log.error("RENDER_FORM: Need Boolean for ${pdField.fullyQualifiedName} but got $value")
}
}
is PDTextField -> {
try {
pdField.value = value?.toString() ?: ""
} catch (ioException: IOException) {
pdField.cosObject.setString(COSName.DA, "/Helv 0 Tf 0 g")
pdField.value = value?.toString() ?: ""
log.error("RENDER_FORM: Writing text field failed: ${ioException.message}")
}
}
null -> {
log.error("RENDER_FORMULAR: Formfield $fieldname does not exist in $name")
}
else -> log.error("RENDER_FORMULAR: Formfield $pdField ($fieldname) is of unhandled type ${pdField.fieldType}")
}
val stream = ByteArrayOutputStream()
pdDocument.save(stream)
pdDocument.close()
return stream.toByteArray()
}
Run Code Online (Sandbox Code Playgroud)