PDFBox 2.0:如何为PDField设置多字体默认外观?
为PDField设置多字体以支持特殊字符
PDF表单域的defaultAppearance属性只能指定单一默认字体,无法直接配置多个字体。但要让•(U+2022)和U+200B零宽空格这两个特殊字符分别用对应字体渲染,可通过以下几种方案实现:
方案1:合并字体(最优解)
如果两款字体均为TrueType/OpenType格式,可将它们合并为一个PDType0Font,这样单个字体就能覆盖所有需要的字符:
val subsetFont = true // 加载两款字体的输入流 val font1Stream = File(bulletSportFontPth).inputStream() val font2Stream = File(widhtSpaceFontPath).inputStream() // 先合并字体文件(可借助FontBox工具类操作字体表,或用第三方字体合并工具) // 合并后加载为PDType0Font val mergedFont = PDType0Font.load(inputPdf, mergedFontStream, subsetFont) inputPdf.documentCatalog?.acroForm?.defaultResources?.add(mergedFont) // 设置默认外观为合并后的字体 field.defaultAppearance = field.defaultAppearance.replace(Regex("/\\w*"), "/${mergedFont.name}")
方案2:富文本指定字符字体
通过给表单域设置富文本内容,单独为特殊字符指定对应字体:
- 确保两款字体已添加到AcroForm默认资源(你的代码已完成此步骤)
- 将表单内容改为富文本格式,为特殊字符绑定字体:
// 示例内容,包含目标特殊字符 val richTextContent = """ <body xmlns="http://www.w3.org/1999/xhtml"> <p>普通文本<span font="/${pdType0Font1.name}">•</span>更多文本<span font="/${pdType0Font2.name}"></span>结束</p> </body> """.trimIndent() // 将富文本设置到表单域 field.setValue(PDTextStream(richTextContent)) // 为普通字符设置默认字体 field.defaultAppearance = field.defaultAppearance.replace(Regex("/\\w*"), "/${yourDefaultFont.name}")
方案3:字体后代映射
利用PDF的字体替代机制,让默认字体在找不到字符时自动使用另一款字体:
// 以pdType0Font1作为默认字体,将pdType0Font2的后代字体添加到其中 val pdType0Font1Descendants = pdType0Font1.descendantFonts pdType0Font1Descendants.add(pdType0Font2.descendantFonts.first()) pdType0Font1.setDescendantFonts(pdType0Font1Descendants) // 设置默认外观为pdType0Font1 field.defaultAppearance = field.defaultAppearance.replace(Regex("/\\w*"), "/${pdType0Font1.name}")
关键注意点
- 所有字体必须正确添加到AcroForm的
defaultResources中,否则阅读器会无法找到字体 - 不同PDF阅读器对字体替代的支持存在差异,需测试渲染效果
- 富文本方案需确保表单域支持XFA或富文本渲染(主流阅读器均支持)
内容的提问来源于stack exchange,提问作者Shahid Ghafoor
相关产品推荐
相关产品推荐

