1

我有一个加密的 PDF 表单文档,需要在表单中填写所需的值,最后需要保存文档这是我尝试过的一段代码

            PDDocument document;
            document = PDDocument.load(sourcePath);
            if( document.isEncrypted() )
            {
                try
                {
                    document.decrypt( "" );
                }
                catch( InvalidPasswordException e )
                {

                }
            }
            PDAcroForm form = document.getDocumentCatalog().getAcroForm();
            PDField Field_1= form.getField("topmostSubform[0].CMS1500Form[0].PatientName[0]");          
            Field_1.setValue("ABC");    
            document.save("C:\\Users\\347702\\Desktop\\21.pdf");
            document.close();

但这给我带来了以下异常

org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.prepareDocumentForEncryption 处的 java.lang.NullPointerException(StandardSecurityHandler.java:303)

我还尝试在 doc.save(""); 上方添加以下语句

document.setAllSecurityToBeRemoved(true);

现在我可以执行程序而不会出现任何错误,但是保存的文档中没有填写所需的值(值:“ABC”).. 它看起来是空白的

任何人都可以帮助我吗?

谢谢

4

1 回答 1

1

我查看了 StandardSecurityHandler.java 的代码,这里是。在此方法中,我们看到以下代码:

    version = computeVersionNumber();
    revision = computeRevisionNumber();
    encryptionDictionary.setFilter(FILTER);
    encryptionDictionary.setVersion(version);
    encryptionDictionary.setRevision(revision);
    encryptionDictionary.setLength(keyLength);

    String ownerPassword = policy.getOwnerPassword();
    String userPassword = policy.getUserPassword();

考虑到我们正在查看的版本可能与您的不同,最可能的原因是策略对象为空(这是第 305 行,而不是 303,但这是之后的第一行,这可能会从空指针异常。

现在对于未填写的表单字段,您应该不加密保存并查找 string (PatientName[0]),它应该是您尝试编辑的字段的字段名称。如果找到它,您应该检查字典是否包含/V具有关联值的键(ABC),这意味着代码正确设置了字段。如果是这种情况,我敢打赌您的文档中也包含 XFA,这意味着表单的实际数据可能不一定存储在表单中,但也可能需要存储在 XFA 数据中包。好消息是 XFA 规范可从 Adob​​e 获得。坏消息是 XFA 规范是 1500 页。好消息是 XFA 是一个带有可下载模式的大型 XML 节点套件。坏消息是模式不是典型的标准格式,并且可用的使用它的工具(显然)没有维护。

于 2013-11-07T15:04:59.277 回答