I have a Java application using PDFBox 2.0.28, and I'm facing a problem when trying to add a signature to a PDF document. The process involves preparing empty fields in the document, populating these fields, and finally adding a signature using the CreateVisibleSignature code example.
Here's a simplified overview of the relevant code:
// Write the content byte[] to the hard disk
_filesManipulator.writeFil(
documentToSigne.Content,
baseNameFiles + FilesManipilator.ORIGINAL_PDF);
// Test if the file contains a signature
boolean isConatinSignature = _pdfManipulator.isDocumentContainsSignature(content);
if (!isConatinSignature) {
// Add empty fields to the PDF document and save it to the hard disk
_pdfManipulator.PrepaireEmptyFieldsToDocument(baseNameFiles + FilesManipilator.ORIGINAL_PDF,
baseNameFiles + FilesManipilator.ORIGINAL_PDF, documentToSigne, event.CurrentMemberInfo);
}
// Populate the fields and save the incremental file to the hard disk
_pdfManipulator.populateFieldsInDocument(baseNameFiles + FilesManipilator.ORIGINAL_PDF,
baseNameFiles + FilesManipilator.ORIGINAL_PDF,
event.CurrentMemberInfo.Configs);
// Add a signature using the `CreateVisibleSignature` example
_pdfManipulator.addSignatureFormConfigs(baseNameFiles, event, event.CurrentMemberInfo, documentToSigne);
// ------------------------------------------------------------------
//and this is the code of PrepaireEmptyFieldsToDocument
public void PrepaireEmptyFieldsToDocument(String pathSource, String
pathdestination,
DocumentToSignDto
documentToSigne, MemberSignerConfigsDto CurrentMemberInfo) throws
IOException {
PDDocument document = PDDocument.load(new File(pathSource));
PDAcroForm acroForm =
document.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);
}
// get liste of configFilds to prepar the list of filds to add
in a document
List<DocumentMemberConfigDto> LastConfigList = documentToSigne.MemberSignerConfigs.stream()
.flatMap(doc -> doc.Configs.stream())
.collect(Collectors.toList());
creatFilds(document, acroForm, LastConfigList);
List<DocumentMemberConfigDto> CurrentConfigList = CurrentMemberInfo.Configs.stream()
.filter(p -> p.docOrder == documentToSigne.Order)
.collect(Collectors.toList());
creatFilds(document, acroForm, CurrentConfigList);
document.save(pathdestination);
document.close();
}
// ------------------------------------------------------------------
//and this is the code of populateFieldsInDocument
public void populateFieldsInDocument(String pathSource, String
pathdestination,
java.util.List<DocumentMemberConfigDto> configList)
throws IOException {
PDDocument document = PDDocument.load(new File(pathSource));
// Get the AcroForm from the document
PDAcroForm acroForm =
document.getDocumentCatalog().getAcroForm();
// Loop through the configList and populate fields
for (DocumentMemberConfigDto config : configList) {
PDField field = acroForm.getField(config.id);
if (field != null &&
!config.fieldLibelle.equals("Signature")) {
// set the value of fild
}
}
}
document.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);
document.getDocumentCatalog().getAcroForm().getCOSObject().setNeedToBeUpdated(true);
FileOutputStream fileOutputStream = new FileOutputStream(new
File(pathdestination));
document.saveIncremental(fileOutputStream);
document.close();
}
The issue arises when calling document.saveIncremental(fileOutputStream); in the populateFieldsInDocument method. This causes the second step to add a signature to fail, with the error message: "Error: Header doesn't contain versioninfo."
I suspect that the problem might be related to the use of document.saveIncremental, but I'm not entirely sure how to resolve it. Any insights or suggestions on how to fix this issue would be greatly appreciated.
Thank you in advance!
: message : [B@4d8a41c1Error while processing the message: Error: Header doesn't contain versioninfo java.io.IOException: Error: Header doesn't contain versioninfo at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:221) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1110) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1093) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1052) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1000) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner.calculatePageSizeFromFile(PDVisibleSignDesigner.java:171) ~[pdfbox-2.0.28.jar!/:2.0.28] at org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner.(PDVisibleSignDesigner.java:72) ~[pdfbox-2.0.28.jar!/:2.0.28] at co.netcom.signature.CreateVisibleSignature.setVisibleSignDesigner(CreateVisibleSignature.java:73) ~[classes!/:0.0.1-SNAPSHOT]
You use the same file for reading and writing:
// Populate the fields and save the incremental file to the hard disk
_pdfManipulator.populateFieldsInDocument(baseNameFiles + FilesManipilator.ORIGINAL_PDF,
baseNameFiles + FilesManipilator.ORIGINAL_PDF,
event.CurrentMemberInfo.Configs);
While this works fine for regular saves, incremental saves need the original file to copy from.
Thus, use different source and destination files, at least for incremental saves.