这个字形(U+FFFD)在该字体编码(WinAnsiEncoding)中不可用。

3

我正在使用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
@JoopEggen 对不起,我不知道你在这里想要告诉我什么。我需要设置一个还是两个?或者我应该将其设置为其他内容? - ST-DDT
1
请使用2.0.3版本重试。如果仍然无法正常工作,请在JIRA中打开一个问题,并附上您的PDF和代码。我想知道U+FFFD来自哪里。在WinAnsi编码中支持“ä”。 - Tilman Hausherr
1
@ST-DDT 我刚刚尝试复现这个问题,但我无法做到。因此,要么您的PDF文件非常特殊,要么您的Java编辑器和Java编译器在代码编码方面有不同的假设。为了调查前者,请分享相关的PDF文件。为了检查后者,请像Simone的回答中所建议的那样,将 'ä' 替换为 '\u00E4'。 - mkl
1
你可能也对这个答案感兴趣 https://dev59.com/Zl0a5IYBdhLWcg3woZ83 - Simone Rondelli
显示剩余6条评论
1个回答

3

U+FFFD 用于替换一个未知或不可表示的Unicode字符,与使用U+001A作为控制字符表示替代函数进行比较(来源)。

尽管如此,很可能该字符在某些地方出现了问题。也许文件的编码不是UTF-8,这就是字符出现问题的原因。

总的来说,您应该只在源代码中编写ASCII字符。您仍然可以使用转义形式\uXXXX 表示整个Unicode范围。在这种情况下,ä- > \u00E4

-- 更新 --

显然,问题是用户输入如何使用JS函数btoa 从客户端/服务器端进行编码/解码而产生的。可以在以下链接找到解决此问题的方法:

使用Javascript的atob解码base64不能正确解码utf-8字符串


抱歉我的示例不够精确。"Gerät"的值由用户提供,通过Base64编码。请参见更新的示例。 - ST-DDT
请查看我上面的评论,问题可能在字符串的编码/解码上。您尝试在控制台上打印出字符串的解码值了吗? - Simone Rondelli
JS前端的输入以某种方式编码为ISO-8859-1。我会尝试在那里修复它。感谢您的支持。有什么想法可以从我的字符串中去除任何坏字符吗?Pattern.compile(new String({0xFF, 0xFD},"UTF-8").replaceAll(input) - ST-DDT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接