我正在使用一个包含文本表单的 pdf 模板。我的程序需要将文本插入这些表单中。出现问题的原因是插入文本是捷克语。我知道我需要安装特殊字体才能使用捷克语:
PDFont formFont = PDType0Font
.load(doc,
PDFGenerator.class.getResourceAsStream(
"/fonts/AbhayaLibre-Regular.ttf"),
false);
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDResources resources = acroForm.getDefaultResources();
String fontName = resources.add(formFont).getName();
字体设置为这样的字段:
PDTextField template = (PDTextField) acroForm.getField("main_text");
template.setMultiline(template.isMultiline());
template.setDefaultAppearance(template.getDefaultAppearance()
.replaceAll("/\\w+", "/"
+ fontName));
template.setValue("Ahoj světe");
例如,此代码适用于在 LibreOffice 中创建的模板。但是对于在 https://www.sejda.com/pdf-forms 中创建的模板,它会因编码错误而崩溃
线程“main”中的异常 java.lang.IllegalArgumentException:U+011B('ecaron')在 Helvetica 字体中不可用,编码:WinAnsiEncoding 在 org.apache.pdfbox.pdmodel.font.PDType1Font.encode(PDType1Font.java:410) 在 org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:337)
我可以在程序中创建新的PDTextField,为其设置字体和矩形。然后程序就可以正常运行了
PDFont formFont = PDType0Font
.load(doc,
PDFGenerator.class.getResourceAsStream(
"/fonts/AbhayaLibre-Regular.ttf"),
false);
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDResources resources = acroForm.getDefaultResources();
final String fontName = resources.add(formFont).getName();
PDPage page = doc.getPage(0);
PDTextField template = (PDTextField) acroForm.getField("main_text");
PDTextField implementation = new PDTextField(acroForm);
implementation.setPartialName(
template.getPartialName() + "_generated");
implementation.setMultiline(template.isMultiline());
implementation.setDefaultAppearance(template.getDefaultAppearance()
.replaceAll("/\\w+", "/"
+ fontName));
implementation.getWidgets().get(0).setRectangle(
template.getWidgets().get(0).getRectangle());
implementation.getWidgets().get(0).setPage(page);
implementation.setValue("Ahoj světe");
page.getAnnotations().add(implementation.getWidgets().get(0));
acroForm.getFields().add(implementation);
template.setReadOnly(true);
template.setValue(null);
doc.save("1.pdf");
我认为此行为是由于 DefaultAppearance 与 pdf 编辑器设置的值重叠所致,但我不知道在哪里寻找它。 我的推理正确吗?在pdfbox表单主体中处理外语的正确方法是什么?
将文件放入光盘。 https://drive.google.com/drive/folders/14Ko_55T9wyYaC6rj7uoH5AUYcTOgN7JC?usp=sharing *_new_font - 之后创建的文件
template.setDefaultAppearance(template.getDefaultAppearance()
.replaceAll("/\\w+", "/"
+ fontName));
执行。
我尝试调试默认外观更改,发现在 setDefaultAppearance 之后字段的默认外观发生了更改,而小部件的默认外观可能不会更改。
System.out.println("Old field default appearance: "
+ template.getDefaultAppearance());
System.out.println("Old widget default appearance: "
+ template.getWidgets().get(0).getCOSObject()
.getString(COSName.DA));
String newAppearance = template.getDefaultAppearance()
.replaceAll("/\\w+", "/"
+ fontName);
template.setDefaultAppearance(newAppearance);
System.out.println("Nef field default appearance: "
+ template.getDefaultAppearance());
System.out.println("New widget default appearance: "
+ template.getWidgets().get(0).getCOSObject()
.getString(COSName.DA));
这个代码给出了seiga
Old field default appearance: /Helv 18 Tf 0.129 0.129 0.129 rg
Old widget default appearance: /Helv 18 Tf 0.129 0.129 0.129 rg
Nef field default appearance: /F3 18 Tf 0.129 0.129 0.129 rg
New widget default appearance: /Helv 18 Tf 0.129 0.129 0.129 rg
为了自由
Old field default appearance: 1 1 1 rg /He 10.006 Tf
Old widget default appearance: 1 1 1 rg /He 10.006 Tf
Nef field default appearance: 1 1 1 rg /F4 10.006 Tf
New widget default appearance: 1 1 1 rg /F4 10.006 Tf
我可以在更改字段的外观之前删除小部件的 DA。这将解决我的问题。 不过,我还有疑问:
我使用的是pdfbox 3.0.2
正如 Tilman Hausherr 所评论的,当文件的小部件拥有自己的 DA 时,就会出现问题。解决这个问题的正确方法是在更改字体之前从 widget 中删除 DA
String newAppearance = template.getDefaultAppearance()
.replaceAll("/\\w+", "/"
+ fontName);
template.getWidgets().get(0).getCOSObject().removeItem(COSName.DA);
template.setDefaultAppearance(newAppearance);