我正在使用PDFBox 2.0.1。
我尝试动态添加一些(用户提供的)UTF8文本到表单字段中,并向用户显示结果。不幸的是,PDF库不能正确编码特殊字符,如“äöü”...或者我没有找到任何有用的文档来帮助我解决这个问题。
有人能告诉我给定代码示例有什么问题吗?
try (PDDocument document = PDDocument.load(pdfTemplate)) {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDAcroForm form = catalog.getAcroForm();
List<PDField> fields = form.getFields();
for (PDField field : fields) {
switch (field.getPartialName()) {
case "devices":
// Frontend (JS): userInput = btoa('Gerät')
String userInput = ...
String name = new String(Base64.getDecoder().decode(base64devices), "UTF-8");
field.setReadOnly(true);
break;
}
}
form.flatten(fields, true);
document.save(bos);
}
以下是错误的堆栈跟踪:
java.lang.IllegalArgumentException: U+FFFD is not available in this font's encoding: WinAnsiEncoding
org.apache.pdfbox.pdmodel.font.PDTrueTypeFont.encode(PDTrueTypeFont.java:368)
org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:286)
org.apache.pdfbox.pdmodel.font.PDFont.getStringWidth(PDFont.java:315)
org.apache.pdfbox.pdmodel.interactive.form.PlainText$Paragraph.getLines(PlainText.java:169)
org.apache.pdfbox.pdmodel.interactive.form.PlainTextFormatter.format(PlainTextFormatter.java:182)
org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.insertGeneratedAppearance(AppearanceGeneratorHelper.java:373)
org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceContent(AppearanceGeneratorHelper.java:237)
org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceValue(AppearanceGeneratorHelper.java:144)
org.apache.pdfbox.pdmodel.interactive.form.PDTextField.constructAppearances(PDTextField.java:263)
org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm.refreshAppearances(PDAcroForm.java:324)
org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm.flatten(PDAcroForm.java:213)
my.application.service.PDFService.generatePDF(PDFService.java:201)
我在SO上找到了一些相关问题:
pdfbox:...在此字体编码中不可用但这并没有帮助我选择正确的编码方式。 我记得Java在字符编码方面内部使用UTF16,为什么默认值不够呢? 这是PDF文档本身的问题还是我用来设置它的代码的问题?
PdfBox encode symbol currency euro好吧,它是动态用户输入,因此有太多东西需要我自己替换。
因此,如果PDFBox人员决定修复破损的PDFBox方法,则此处表面干净的解决方法代码将开始失败,因为它将向修复的方法提供破损的输入数据。
诚然,在2.0.0之前,我怀疑他们会修复这个错误(在2.0.0中,修复的方法具有不同的名称),但是人们永远不知道......
不幸的是,我无法找到此其他setter方法,但它可能适用于不同的范围。
编辑
更新示例代码以更好地表示问题。
PDFTrueTypeFont.setFontEncoding(new WinAnsiEncoding());
和~.setEncoding(COSName.WIN_ANSI_ENCODING);
两种设置字体编码的方式。 - Joop Eggen