PDFBox API:如何更改字体以处理 AcroForm 字段中的西里尔字母值
PDFBox API: How to change font to handle Cyrillic values in an AcroForm field
我需要帮助使用 PDFBox API
向字段添加西里尔文值。这是我目前所拥有的:
PDDocument document = PDDocument.load(file);
PDDocumentCatalog dc = document.getDocumentCatalog();
PDAcroForm acroForm = dc.getAcroForm();
PDField naziv = acroForm.getField("naziv");
naziv.setValue("Наслов"); // this part right here
naziv.setValue("Naslov"); // it works like this
当我输入的是拉丁字母时,它工作得很好。但我也需要处理西里尔字母输入。
我该怎么做?
p.s。这是我得到的例外:
Caused by: java.lang.IllegalArgumentException: U+043D ('afii10079') 在此字体中不可用 Helvetica 编码: WinAnsiEncoding
下面的代码在 acroform 默认资源字典中添加了合适的字体,并替换了默认外观中的名称。当您调用 setValue() 时,PDFBox 使用新字体重新创建字段的外观流。
public static void main(String[] args) throws IOException
{
PDDocument doc = PDDocument.load(new File("ZPe.pdf"));
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDResources dr = acroForm.getDefaultResources();
// Important: the font is Type0 (allows more than 256 glyphs) and NOT SUBSETTED
PDFont font = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/arial.ttf"), false);
COSName fontName = dr.add(font);
Iterator<PDField> it = acroForm.getFieldIterator();
while (it.hasNext())
{
PDField field = it.next();
if (field instanceof PDTextField)
{
PDTextField textField = (PDTextField) field;
String da = textField.getDefaultAppearance();
// replace font name in default appearance string
Pattern pattern = Pattern.compile("\/(\w+)\s.*");
Matcher matcher = pattern.matcher(da);
if (!matcher.find() || matcher.groupCount() < 2)
{
// oh-oh
}
String oldFontName = matcher.group(1);
da = da.replaceFirst(oldFontName, fontName.getName());
textField.setDefaultAppearance(da);
}
}
acroForm.getField("name1").setValue("Наслов");
doc.save("result.pdf");
doc.close();
}
2019 年 4 月 4 日更新:为了节省一些 space,在调用 setValue 之前删除外观可能会有用:
acroForm.getField("name1").getWidgets().get(0).setAppearance(null);
检查AcroForm默认资源中是否有未使用的字体,参见this answer。
2019 年 4 月 7 日更新:如果字体非常大(例如 ArialUni)并且要设置很多字段(PDFBOX-4508),您可能会遇到性能不佳的情况。在这种情况下,在调用 setValue
.
之前保存并重新加载文件
要了解字体是否支持预期的文本,请调用 PDFont.encode()
并检查 IllegalArgumentException
。
我需要帮助使用 PDFBox API
向字段添加西里尔文值。这是我目前所拥有的:
PDDocument document = PDDocument.load(file);
PDDocumentCatalog dc = document.getDocumentCatalog();
PDAcroForm acroForm = dc.getAcroForm();
PDField naziv = acroForm.getField("naziv");
naziv.setValue("Наслов"); // this part right here
naziv.setValue("Naslov"); // it works like this
当我输入的是拉丁字母时,它工作得很好。但我也需要处理西里尔字母输入。 我该怎么做?
p.s。这是我得到的例外: Caused by: java.lang.IllegalArgumentException: U+043D ('afii10079') 在此字体中不可用 Helvetica 编码: WinAnsiEncoding
下面的代码在 acroform 默认资源字典中添加了合适的字体,并替换了默认外观中的名称。当您调用 setValue() 时,PDFBox 使用新字体重新创建字段的外观流。
public static void main(String[] args) throws IOException
{
PDDocument doc = PDDocument.load(new File("ZPe.pdf"));
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDResources dr = acroForm.getDefaultResources();
// Important: the font is Type0 (allows more than 256 glyphs) and NOT SUBSETTED
PDFont font = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/arial.ttf"), false);
COSName fontName = dr.add(font);
Iterator<PDField> it = acroForm.getFieldIterator();
while (it.hasNext())
{
PDField field = it.next();
if (field instanceof PDTextField)
{
PDTextField textField = (PDTextField) field;
String da = textField.getDefaultAppearance();
// replace font name in default appearance string
Pattern pattern = Pattern.compile("\/(\w+)\s.*");
Matcher matcher = pattern.matcher(da);
if (!matcher.find() || matcher.groupCount() < 2)
{
// oh-oh
}
String oldFontName = matcher.group(1);
da = da.replaceFirst(oldFontName, fontName.getName());
textField.setDefaultAppearance(da);
}
}
acroForm.getField("name1").setValue("Наслов");
doc.save("result.pdf");
doc.close();
}
2019 年 4 月 4 日更新:为了节省一些 space,在调用 setValue 之前删除外观可能会有用:
acroForm.getField("name1").getWidgets().get(0).setAppearance(null);
检查AcroForm默认资源中是否有未使用的字体,参见this answer。
2019 年 4 月 7 日更新:如果字体非常大(例如 ArialUni)并且要设置很多字段(PDFBOX-4508),您可能会遇到性能不佳的情况。在这种情况下,在调用 setValue
.
要了解字体是否支持预期的文本,请调用 PDFont.encode()
并检查 IllegalArgumentException
。