下面的代码在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();}更新4.4.2019:为节省空间,在调用setValue之前删除外观可能很有用:
acroForm.getField("name1").getWidgets().get(0).setAppearance(null);要检查AcroForm默认资源中是否有未使用的字体,请参见此答案。
更新7.4.2019:如果字体很大(例如ArialUni)并且要设置许多字段(PDFBOX-4508),则可能会遇到性能不佳的情况。在这种情况下,请在调用之前保存并重新加载文件
setValue。
要查明字体是否支持预期的文本,请调用
PDFont.enpre()并检查
IllegalArgumentException。



