4

我在这里阅读了关于 saveIncremental 是如何工作的,我的最终结果需要类似于这里,因为我已经设法根据签名字段本身创建具有多个可视化的可见​​签名(不像在响应中,但是回应对我帮助很大)。为了详细说明标题,我现在的基本任务是在已经签名的文档上创建一个空的签名字段,而不破坏现有的签名。但是,此处的示例不适用于 saveIncremental。我已将以下代码段(已改编)添加到 main 函数的末尾,但没有结果:

    acroForm.setSignaturesExist(true);
    acroForm.setAppendOnly(true);
    acroForm.getCOSObject().setDirect(true);
// ...


COSDictionary pageTreeObject = pdPage.getCOSObject(); 
while (pageTreeObject != null) {
    pageTreeObject.setNeedToBeUpdated(true);
    pageTreeObject = (COSDictionary) pageTreeObject.getDictionaryObject(COSName.PARENT);
}

结果文件不包含任何签名字段。我试图将 COSObject.needToBeUpdated(true) 更新为 acroform、signatureField、pddocument、page、widget,但没有结果。签名字段仅在我通常保存时出现。

编辑:我设法添加了一个空的签名字段(在 COSObject.needToBeUpdated 链上编辑的代码),但它破坏了现有的签名。

在此处输入图像描述

我想念什么?谢谢!

我的实际代码:

public class CreateEmptySignatureForm {

public static void main(String[] args) throws IOException
{
    InputStream resource = new FileInputStream("test-semnat.pdf");
    PDDocument document = PDDocument.load(resource);
            
    PDPage page = document.getPage(0);

    // Add a new AcroForm and add that to the document
    PDAcroForm acroForm = new PDAcroForm(document);
    document.getDocumentCatalog().setAcroForm(acroForm);

    acroForm.setSignaturesExist(true);
    acroForm.setAppendOnly(true);
    acroForm.getCOSObject().setDirect(true);

    // Create empty signature field, it will get the name "Signature1"
    PDSignatureField signatureField = new PDSignatureField(acroForm);
    PDAnnotationWidget widget = signatureField.getWidgets().get(0);
    PDRectangle rect = new PDRectangle(50, 250, 200, 50);
    widget.setRectangle(rect);
    widget.getCOSObject().setNeedToBeUpdated(true);
    widget.setPage(page);
    page.getAnnotations().add(widget);
    page.getCOSObject().setNeedToBeUpdated(true);
    acroForm.getFields().add(signatureField);

    // general updates
    document.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);

    OutputStream os = new FileOutputStream("fooo.pdf");
    document.saveIncremental(os);
    System.out.println("done");
}
}

测试-semnat.pdf

4

1 回答 1

3

问题更新后的剩余问题是您替换了现有的AcroForm定义:

// Add a new AcroForm and add that to the document
PDAcroForm acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);

这变化太大了,超出了允许范围,超出了您的实际需要。

您想要的是检索现有的AcroForm定义,并仅将其及其字段条目标记为保存:

PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
acroForm.getCOSObject().setNeedToBeUpdated(true);
COSObject fields = acroForm.getCOSObject().getCOSObject(COSName.FIELDS);
if (fields != null)
    fields.setNeedToBeUpdated(true);

使用该代码,我为您的示例文档获得:

签名面板

(当然,对于没有现有AcroForm定义的文档,您可能需要添加一个新定义,因此

PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
    acroForm = new PDAcroForm(document);
    document.getDocumentCatalog().setAcroForm(acroForm);
}
acroForm.getCOSObject().setNeedToBeUpdated(true);
COSObject fields = acroForm.getCOSObject().getCOSObject(COSName.FIELDS);
if (fields != null)
    fields.setNeedToBeUpdated(true);

可能是完整的变体。)

于 2020-06-28T07:13:10.853 回答