如何使用 pdfbox 用特定字体填写 PDF 表单?

Posted

技术标签:

【中文标题】如何使用 pdfbox 用特定字体填写 PDF 表单?【英文标题】:How to fill PDF form with specific font using pdfbox? 【发布时间】:2017-04-27 13:50:37 【问题描述】:

我正在尝试填写 pdf 表单,我可以通过 PDFBox 库使用以下方法填写它。

val pdf: PDDocument = PDDocument.load(file)
pdf.setAllSecurityToBeRemoved(true)
val docCatalog: PDDocumentCatalog = pdf.getDocumentCatalog
val acroForm: PDAcroForm = docCatalog.getAcroForm

def populateFields(inputJson: String, targetPdfPath: String): Unit = 
    val valueMap: Array[Field] = gson.fromJson(inputJson, classOf[Array[Field]])
    valueMap.foreach((field) => 
      val pdField: PDField = acroForm.getField(field.name)

      if (pdField != null) 
        pdField.setValue(field.value)
       else 
        println(s"No field with name $field.name")
      
    )

    pdf.save(targetPdfPath)
    pdf.close()
  

唯一的问题是,在填写 pdf 之前,我没有看到任何设置字体的选项。你能帮帮我吗?

【问题讨论】:

字段的字体取自字段定义。你为什么要改变它?要更改它,您需要 a) 将字体添加到 AcroForm 默认资源和 b) 更改默认外观字符串以使用该字体。有关简单示例,请查看 CreateSimpleForm.java in org.apache.pdfbox.examples.interactive.form 【参考方案1】:

您可以使用这些方法来实现它(注意您必须使用 PDFBox 1.8.15,而不是较新的 2.0)。

// Set the field with custom font.
private void setField(String name, String value, String fontSource) throws IOException 
    PDDocumentCatalog docCatalog;
    PDAcroForm acroForm;
    PDField field;
    COSDictionary dict;
    COSString defaultAppearance;
    docCatalog = pdfTemplate.getDocumentCatalog();
    acroForm = docCatalog.getAcroForm();
    field = acroForm.getField(name);
    dict = (field).getDictionary();
    defaultAppearance = (COSString) dict.getDictionaryObject(COSName.DA);

    if (defaultAppearance != null)
    
        dict.setString(COSName.DA, "/" + fontName + " 10 Tf 0 g");
        if (name.equalsIgnoreCase("Field1")) 
            dict.setString(COSName.DA, "/" + fontName + " 12 Tf 0 g");
        
    
    if (field instanceof PDTextbox)
    
        field = new PDTextbox(acroForm, dict);
        (field).setValue(value);
    


// Set the field with custom font.
private List<String> prepareFont(PDDocument _pdfDocument, List<PDFont> fonts) 
    PDDocumentCatalog docCatalog = _pdfDocument.getDocumentCatalog();
    PDAcroForm acroForm = docCatalog.getAcroForm();

    PDResources res = acroForm.getDefaultResources();
    if (res == null)
        res = new PDResources();

    List<String> fontNames = new ArrayList<>();
    for (PDFont font: fonts)
    
        fontNames.add(res.addFont(font));
    

    acroForm.setDefaultResources(res);
    return fontNames;


// Set the field with custom font.
private PDFont loadTrueTypeFont(PDDocument _pdfDocument, String resourceName) throws IOException

    return PDTrueTypeFont.loadTTF(_pdfDocument, new File(resourceName));

现在,您只需使用字段名称、要插入的值和一个字符串(即您要使用的 TTF 字体的路径)来获取方法 setField

希望对你有帮助!

【讨论】:

当前1.8版本是1.8.15。以前的有安全问题。请更正您的答案(这很可能是好的)。 谢谢。有关 2.0 的示例,请参阅源代码下载中的 CreateSimpleFormWithEmbeddedFont.java 示例。

以上是关于如何使用 pdfbox 用特定字体填写 PDF 表单?的主要内容,如果未能解决你的问题,请参考以下文章

如果在 PDF 表单中多次出现,Java PDFBox 不会保持字段的字体外观

使用 PDFBOX 填写 PDF 表单中的多个字段并在填写后锁定编辑 pdf 文档

PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段

使用 pdfbox 编辑 pdf 页面

使用 PDFBox 从 PDF 文档中读取特定页面

PDFBox:通过重复添加包含表单的单页模板来填写 PDF