PDFBox API:如何更改字体以处理 AcroForm 字段中的西里尔文值

Nen*_*ikj 5 java fonts field pdfbox acrofields

我需要帮助使用以下命令向字段添加西里尔字母值PDFBox API. 这是我到目前为止所拥有的:

\n\n
PDDocument document = PDDocument.load(file);\nPDDocumentCatalog dc = document.getDocumentCatalog();\nPDAcroForm acroForm = dc.getAcroForm();\nPDField naziv = acroForm.getField("naziv");\nnaziv.setValue("\xd0\x9d\xd0\xb0\xd1\x81\xd0\xbb\xd0\xbe\xd0\xb2"); // this part right here\nnaziv.setValue("Naslov"); // it works like this\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我的输入是拉丁字母时,它工作得很好。但我还需要处理西里尔字母输入。\n我该怎么做?

\n\n

ps这是我得到的异常:\n由以下原因引起:java.lang.IllegalArgumentException:U+043D(\'afii10079\')在此字体Helvetica编码中不可用:WinAnsiEncoding

\n

Til*_*err 6

下面的代码在 acroform 默认资源字典中添加适当的字体,并替换默认外观中的名称。当您调用 setValue() 时,PDFBox 使用新字体重新创建字段的外观流。

\n\n
public static void main(String[] args) throws IOException\n{\n    PDDocument doc = PDDocument.load(new File("ZPe.pdf"));\n    PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();\n    PDResources dr = acroForm.getDefaultResources();\n\n    // Important: the font is Type0 (allows more than 256 glyphs) and NOT SUBSETTED\n    PDFont font = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/arial.ttf"), false);\n\n    COSName fontName = dr.add(font);\n    Iterator<PDField> it = acroForm.getFieldIterator();\n    while (it.hasNext())\n    {\n        PDField field = it.next();\n        if (field instanceof PDTextField)\n        {\n            PDTextField textField = (PDTextField) field;\n            String da = textField.getDefaultAppearance();\n\n            // replace font name in default appearance string\n            Pattern pattern = Pattern.compile("\\\\/(\\\\w+)\\\\s.*");\n            Matcher matcher = pattern.matcher(da);\n            if (!matcher.find() || matcher.groupCount() < 2)\n            {\n                // oh-oh\n            }\n            String oldFontName = matcher.group(1);\n            da = da.replaceFirst(oldFontName, fontName.getName());\n\n            textField.setDefaultAppearance(da);\n        }\n    }\n    acroForm.getField("name1").setValue("\xd0\x9d\xd0\xb0\xd1\x81\xd0\xbb\xd0\xbe\xd0\xb2");\n    doc.save("result.pdf");\n    doc.close();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

2019 年 4 月 4 日更新:为了节省一些空间,在调用 setValue 之前删除外观可能会很有用:

\n\n
acroForm.getField("name1").getWidgets().get(0).setAppearance(null);\n
Run Code Online (Sandbox Code Playgroud)\n\n

要检查 AcroForm 默认资源中是否有未使用的字体,请参阅此答案

\n\n

2019年4月7日更新:如果字体很大(例如ArialUni)并且要设置许多字段(PDFBOX-4508),您可能会遇到性能不佳的情况。在这种情况下,请在调用之前保存并重新加载文件setValue

\n\n

要查明字体是否支持预期文本,请调用PDFont.encode()并检查IllegalArgumentException.

\n