Add: Option to remove the digital signature when merging (#1424)
This commit is contained in:
@@ -10,11 +10,16 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.multipdf.PDFMergerUtility;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -38,6 +43,7 @@ public class MergeController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
|
||||
|
||||
// Merges a list of PDDocument objects into a single PDDocument
|
||||
public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
||||
PDDocument mergedDoc = new PDDocument();
|
||||
for (PDDocument doc : documents) {
|
||||
@@ -48,6 +54,7 @@ public class MergeController {
|
||||
return mergedDoc;
|
||||
}
|
||||
|
||||
// Returns a comparator for sorting MultipartFile arrays based on the given sort type
|
||||
private Comparator<MultipartFile> getSortComparator(String sortType) {
|
||||
switch (sortType) {
|
||||
case "byFileName":
|
||||
@@ -108,37 +115,78 @@ public class MergeController {
|
||||
"This endpoint merges multiple PDF files into a single PDF file. The merged file will contain all pages from the input files in the order they were provided. Input:PDF Output:PDF Type:MISO")
|
||||
public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest form)
|
||||
throws IOException {
|
||||
List<File> filesToDelete = new ArrayList<File>();
|
||||
List<File> filesToDelete = new ArrayList<>(); // List of temporary files to delete
|
||||
ByteArrayOutputStream docOutputstream =
|
||||
new ByteArrayOutputStream(); // Stream for the merged document
|
||||
PDDocument mergedDocument = null;
|
||||
|
||||
boolean removeCertSign = form.isRemoveCertSign();
|
||||
|
||||
try {
|
||||
MultipartFile[] files = form.getFileInput();
|
||||
Arrays.sort(files, getSortComparator(form.getSortType()));
|
||||
|
||||
PDFMergerUtility mergedDoc = new PDFMergerUtility();
|
||||
ByteArrayOutputStream docOutputstream = new ByteArrayOutputStream();
|
||||
Arrays.sort(
|
||||
files,
|
||||
getSortComparator(
|
||||
form.getSortType())); // Sort files based on the given sort type
|
||||
|
||||
PDFMergerUtility mergerUtility = new PDFMergerUtility();
|
||||
for (MultipartFile multipartFile : files) {
|
||||
File tempFile = GeneralUtils.convertMultipartFileToFile(multipartFile);
|
||||
filesToDelete.add(tempFile);
|
||||
mergedDoc.addSource(tempFile);
|
||||
File tempFile =
|
||||
GeneralUtils.convertMultipartFileToFile(
|
||||
multipartFile); // Convert MultipartFile to File
|
||||
filesToDelete.add(tempFile); // Add temp file to the list for later deletion
|
||||
mergerUtility.addSource(tempFile); // Add source file to the merger utility
|
||||
}
|
||||
mergerUtility.setDestinationStream(
|
||||
docOutputstream); // Set the output stream for the merged document
|
||||
mergerUtility.mergeDocuments(null); // Merge the documents
|
||||
|
||||
byte[] mergedPdfBytes = docOutputstream.toByteArray(); // Get merged document bytes
|
||||
|
||||
// Load the merged PDF document
|
||||
mergedDocument = Loader.loadPDF(mergedPdfBytes);
|
||||
|
||||
// Remove signatures if removeCertSign is true
|
||||
if (removeCertSign) {
|
||||
PDDocumentCatalog catalog = mergedDocument.getDocumentCatalog();
|
||||
PDAcroForm acroForm = catalog.getAcroForm();
|
||||
if (acroForm != null) {
|
||||
List<PDField> fieldsToRemove =
|
||||
acroForm.getFields().stream()
|
||||
.filter(field -> field instanceof PDSignatureField)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!fieldsToRemove.isEmpty()) {
|
||||
acroForm.flatten(
|
||||
fieldsToRemove,
|
||||
false); // Flatten the fields, effectively removing them
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mergedDoc.setDestinationFileName(
|
||||
files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_merged.pdf");
|
||||
mergedDoc.setDestinationStream(docOutputstream);
|
||||
|
||||
mergedDoc.mergeDocuments(null);
|
||||
// Save the modified document to a new ByteArrayOutputStream
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
mergedDocument.save(baos);
|
||||
|
||||
String mergedFileName =
|
||||
files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "")
|
||||
+ "_merged_unsigned.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
docOutputstream.toByteArray(), mergedDoc.getDestinationFileName());
|
||||
baos.toByteArray(), mergedFileName); // Return the modified PDF
|
||||
|
||||
} catch (Exception ex) {
|
||||
logger.error("Error in merge pdf process", ex);
|
||||
throw ex;
|
||||
} finally {
|
||||
for (File file : filesToDelete) {
|
||||
if (file != null) {
|
||||
Files.deleteIfExists(file.toPath());
|
||||
Files.deleteIfExists(file.toPath()); // Delete temporary files
|
||||
}
|
||||
}
|
||||
docOutputstream.close();
|
||||
if (mergedDocument != null) {
|
||||
mergedDocument.close(); // Close the merged document
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user