Add: Option to remove the digital signature when merging (#1424)

This commit is contained in:
Ludy 2024-06-09 14:58:05 +02:00 committed by GitHub
parent 2e11b632dd
commit 7543f49ba4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 106 additions and 16 deletions

View file

@ -10,11 +10,16 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.apache.pdfbox.Loader; import org.apache.pdfbox.Loader;
import org.apache.pdfbox.multipdf.PDFMergerUtility; import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDPage; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -38,6 +43,7 @@ public class MergeController {
private static final Logger logger = LoggerFactory.getLogger(MergeController.class); 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 { public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
PDDocument mergedDoc = new PDDocument(); PDDocument mergedDoc = new PDDocument();
for (PDDocument doc : documents) { for (PDDocument doc : documents) {
@ -48,6 +54,7 @@ public class MergeController {
return mergedDoc; return mergedDoc;
} }
// Returns a comparator for sorting MultipartFile arrays based on the given sort type
private Comparator<MultipartFile> getSortComparator(String sortType) { private Comparator<MultipartFile> getSortComparator(String sortType) {
switch (sortType) { switch (sortType) {
case "byFileName": 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") "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) public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest form)
throws IOException { 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 { try {
MultipartFile[] files = form.getFileInput(); MultipartFile[] files = form.getFileInput();
Arrays.sort(files, getSortComparator(form.getSortType())); Arrays.sort(
files,
PDFMergerUtility mergedDoc = new PDFMergerUtility(); getSortComparator(
ByteArrayOutputStream docOutputstream = new ByteArrayOutputStream(); form.getSortType())); // Sort files based on the given sort type
PDFMergerUtility mergerUtility = new PDFMergerUtility();
for (MultipartFile multipartFile : files) { for (MultipartFile multipartFile : files) {
File tempFile = GeneralUtils.convertMultipartFileToFile(multipartFile); File tempFile =
filesToDelete.add(tempFile); GeneralUtils.convertMultipartFileToFile(
mergedDoc.addSource(tempFile); 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( // Save the modified document to a new ByteArrayOutputStream
files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_merged.pdf"); ByteArrayOutputStream baos = new ByteArrayOutputStream();
mergedDoc.setDestinationStream(docOutputstream); mergedDocument.save(baos);
mergedDoc.mergeDocuments(null);
String mergedFileName =
files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "")
+ "_merged_unsigned.pdf";
return WebResponseUtils.bytesToWebResponse( return WebResponseUtils.bytesToWebResponse(
docOutputstream.toByteArray(), mergedDoc.getDestinationFileName()); baos.toByteArray(), mergedFileName); // Return the modified PDF
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Error in merge pdf process", ex); logger.error("Error in merge pdf process", ex);
throw ex; throw ex;
} finally { } finally {
for (File file : filesToDelete) { for (File file : filesToDelete) {
if (file != null) { 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
}
} }
} }
} }

View file

@ -21,4 +21,10 @@ public class MergePdfsRequest extends MultiplePDFFiles {
}, },
defaultValue = "orderProvided") defaultValue = "orderProvided")
private String sortType = "orderProvided"; private String sortType = "orderProvided";
@Schema(
description =
"Flag indicating whether to remove certification signatures from the merged PDF. If true, all certification signatures will be removed from the final merged document.",
example = "true")
private boolean isRemoveCertSign;
} }

View file

@ -803,6 +803,7 @@ merge.title=دمج
merge.header=دمج ملفات PDF متعددة (2+) merge.header=دمج ملفات PDF متعددة (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=دمج merge.submit=دمج

View file

@ -803,6 +803,7 @@ merge.title=Обединяване
merge.header=Обединяване на множество PDF файлове (2+) merge.header=Обединяване на множество PDF файлове (2+)
merge.sortByName=Сортиране по име merge.sortByName=Сортиране по име
merge.sortByDate=Сортиране по дата merge.sortByDate=Сортиране по дата
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Обединяване merge.submit=Обединяване

View file

@ -803,6 +803,7 @@ merge.title=Fusiona
merge.header=Fusiona múltiples PDFs (2+) merge.header=Fusiona múltiples PDFs (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Fusiona merge.submit=Fusiona

View file

@ -803,6 +803,7 @@ merge.title=Sloučit
merge.header=Sloučit více PDF (2+) merge.header=Sloučit více PDF (2+)
merge.sortByName=Seřadit podle názvu merge.sortByName=Seřadit podle názvu
merge.sortByDate=Seřadit podle data merge.sortByDate=Seřadit podle data
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Sloučit merge.submit=Sloučit

View file

@ -803,6 +803,7 @@ merge.title=Zusammenführen
merge.header=Mehrere PDFs zusammenführen (2+) merge.header=Mehrere PDFs zusammenführen (2+)
merge.sortByName=Nach Namen sortieren merge.sortByName=Nach Namen sortieren
merge.sortByDate=Nach Datum sortieren merge.sortByDate=Nach Datum sortieren
merge.removeCertSign=Digitale Signatur in der zusammengeführten Datei entfernen?
merge.submit=Zusammenführen merge.submit=Zusammenführen

View file

@ -803,6 +803,7 @@ merge.title=Συγχώνευση
merge.header=Συγχώνευση πολλαπλών PDFs (2+) merge.header=Συγχώνευση πολλαπλών PDFs (2+)
merge.sortByName=Ταξινόμηση με βάση το Όνομα merge.sortByName=Ταξινόμηση με βάση το Όνομα
merge.sortByDate=Ταξινόμηση με βάση την Ημερομηνία merge.sortByDate=Ταξινόμηση με βάση την Ημερομηνία
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Συγχώνευση merge.submit=Συγχώνευση

View file

@ -803,6 +803,7 @@ merge.title=Merge
merge.header=Merge multiple PDFs (2+) merge.header=Merge multiple PDFs (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Merge merge.submit=Merge

View file

@ -803,6 +803,7 @@ merge.title=Merge
merge.header=Merge multiple PDFs (2+) merge.header=Merge multiple PDFs (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Merge merge.submit=Merge

View file

@ -803,6 +803,7 @@ merge.title=Unir
merge.header=Unir múltiples PDFs (2+) merge.header=Unir múltiples PDFs (2+)
merge.sortByName=Ordenar por nombre merge.sortByName=Ordenar por nombre
merge.sortByDate=Ordenar por fecha merge.sortByDate=Ordenar por fecha
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Unir merge.submit=Unir

View file

@ -803,6 +803,7 @@ merge.title=Elkartu
merge.header=Elkartu zenbait PDF (2+) merge.header=Elkartu zenbait PDF (2+)
merge.sortByName=Sort by nameOrdenatu izenaren arabera merge.sortByName=Sort by nameOrdenatu izenaren arabera
merge.sortByDate=Ordenatu dataren arabera merge.sortByDate=Ordenatu dataren arabera
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Elkartu merge.submit=Elkartu

View file

@ -803,6 +803,7 @@ merge.title=Fusionner
merge.header=Fusionner plusieurs PDF merge.header=Fusionner plusieurs PDF
merge.sortByName=Trier par nom merge.sortByName=Trier par nom
merge.sortByDate=Trier par date merge.sortByDate=Trier par date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Fusionner merge.submit=Fusionner

View file

@ -803,6 +803,7 @@ merge.title=मर्ज
merge.header=एक से अधिक PDF एक साथ मर्ज करें (2+) merge.header=एक से अधिक PDF एक साथ मर्ज करें (2+)
merge.sortByName=नाम से क्रमबद्ध करें merge.sortByName=नाम से क्रमबद्ध करें
merge.sortByDate=तारीख से क्रमबद्ध करें merge.sortByDate=तारीख से क्रमबद्ध करें
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=मर्ज करें merge.submit=मर्ज करें

View file

@ -803,6 +803,7 @@ merge.title=Spajanje
merge.header=Spajanje više PDF-ova (2+) merge.header=Spajanje više PDF-ova (2+)
merge.sortByName=Poredaj po imenu merge.sortByName=Poredaj po imenu
merge.sortByDate=Poredaj po datumu merge.sortByDate=Poredaj po datumu
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Spajanje merge.submit=Spajanje

View file

@ -803,6 +803,7 @@ merge.title=Összevonás
merge.header=Több PDF összevonása (2+) merge.header=Több PDF összevonása (2+)
merge.sortByName=Név szerinti rendezés merge.sortByName=Név szerinti rendezés
merge.sortByDate=Dátum szerinti rendezés merge.sortByDate=Dátum szerinti rendezés
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Összevonás merge.submit=Összevonás

View file

@ -803,6 +803,7 @@ merge.title=Gabungkan
merge.header=Gabungkan beberapa PDFs (2+) merge.header=Gabungkan beberapa PDFs (2+)
merge.sortByName=Sortir berdasarkan nama merge.sortByName=Sortir berdasarkan nama
merge.sortByDate=Sortir berdasrkan tanggal merge.sortByDate=Sortir berdasrkan tanggal
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Gabungkan merge.submit=Gabungkan

View file

@ -803,6 +803,7 @@ merge.title=Unisci
merge.header=Unisci 2 o più PDF merge.header=Unisci 2 o più PDF
merge.sortByName=Ordina per nome merge.sortByName=Ordina per nome
merge.sortByDate=Ordina per data merge.sortByDate=Ordina per data
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Unisci merge.submit=Unisci

View file

@ -803,6 +803,7 @@ merge.title=結合
merge.header=複数のPDFを結合 (2ファイル以上) merge.header=複数のPDFを結合 (2ファイル以上)
merge.sortByName=名前で並べ替え merge.sortByName=名前で並べ替え
merge.sortByDate=日付で並べ替え merge.sortByDate=日付で並べ替え
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=結合 merge.submit=結合

View file

@ -803,6 +803,7 @@ merge.title=병합
merge.header=여러 개의 PDF 병합 (2개 이상) merge.header=여러 개의 PDF 병합 (2개 이상)
merge.sortByName=이름순 정렬 merge.sortByName=이름순 정렬
merge.sortByDate=날짜순 정렬 merge.sortByDate=날짜순 정렬
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=병합 merge.submit=병합

View file

@ -803,6 +803,7 @@ merge.title=Samenvoegen
merge.header=Meerdere PDF's samenvoegen (2+) merge.header=Meerdere PDF's samenvoegen (2+)
merge.sortByName=Sorteer op naam merge.sortByName=Sorteer op naam
merge.sortByDate=Sorteer op datum merge.sortByDate=Sorteer op datum
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Samenvoegen merge.submit=Samenvoegen

View file

@ -803,6 +803,7 @@ merge.title=Slå sammen
merge.header=Slå sammen flere PDF-er (2+) merge.header=Slå sammen flere PDF-er (2+)
merge.sortByName=Sorter etter navn merge.sortByName=Sorter etter navn
merge.sortByDate=Sorter etter dato merge.sortByDate=Sorter etter dato
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Slå sammen merge.submit=Slå sammen

View file

@ -803,6 +803,7 @@ merge.title=Połącz
merge.header=Połącz wiele dokumentów PDF (2+) merge.header=Połącz wiele dokumentów PDF (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Połącz merge.submit=Połącz

View file

@ -803,6 +803,7 @@ merge.title=Mesclar
merge.header=Mesclar Vários PDFs (2+) merge.header=Mesclar Vários PDFs (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Mesclar merge.submit=Mesclar

View file

@ -803,6 +803,7 @@ merge.title=Juntar
merge.header=Juntar Vários PDFs (2+) merge.header=Juntar Vários PDFs (2+)
merge.sortByName=Ordenar por nome merge.sortByName=Ordenar por nome
merge.sortByDate=Ordenar por data merge.sortByDate=Ordenar por data
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Juntar merge.submit=Juntar

View file

@ -803,6 +803,7 @@ merge.title=Unire
merge.header=Unirea mai multor PDF-uri (2+) merge.header=Unirea mai multor PDF-uri (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Unire merge.submit=Unire

View file

@ -803,6 +803,7 @@ merge.title=Объединить
merge.header=Объединение нескольких PDF-файлов (2+) merge.header=Объединение нескольких PDF-файлов (2+)
merge.sortByName=Сортировка по имени merge.sortByName=Сортировка по имени
merge.sortByDate=Сортировка по дате merge.sortByDate=Сортировка по дате
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Объединить merge.submit=Объединить

View file

@ -803,6 +803,7 @@ merge.title=Zlúčiť
merge.header=Zlúčiť viacero PDF (2+) merge.header=Zlúčiť viacero PDF (2+)
merge.sortByName=Zoradiť podľa názvu merge.sortByName=Zoradiť podľa názvu
merge.sortByDate=Zoradiť podľa dátumu merge.sortByDate=Zoradiť podľa dátumu
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Zlúčiť merge.submit=Zlúčiť

View file

@ -803,6 +803,7 @@ merge.title=Spajanje
merge.header=Spajanje više PDF fajlova (2+) merge.header=Spajanje više PDF fajlova (2+)
merge.sortByName=Sortiraj po imenu merge.sortByName=Sortiraj po imenu
merge.sortByDate=Sortiraj po datumu merge.sortByDate=Sortiraj po datumu
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Spajanje merge.submit=Spajanje

View file

@ -803,6 +803,7 @@ merge.title=Sammanfoga
merge.header=Slå samman flera PDF-filer (2+) merge.header=Slå samman flera PDF-filer (2+)
merge.sortByName=Sort by name merge.sortByName=Sort by name
merge.sortByDate=Sort by date merge.sortByDate=Sort by date
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Slå samman merge.submit=Slå samman

View file

@ -803,6 +803,7 @@ merge.title=Birleştir
merge.header=Çoklu PDF'leri Birleştir (2+) merge.header=Çoklu PDF'leri Birleştir (2+)
merge.sortByName=İsme göre sırala merge.sortByName=İsme göre sırala
merge.sortByDate=Tarihe göre sırala merge.sortByDate=Tarihe göre sırala
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Birleştir merge.submit=Birleştir

View file

@ -803,6 +803,7 @@ merge.title=Об'єднати
merge.header=Об'єднання кількох PDF-файлів (2+) merge.header=Об'єднання кількох PDF-файлів (2+)
merge.sortByName=Сортування за ім'ям merge.sortByName=Сортування за ім'ям
merge.sortByDate=Сортування за датою merge.sortByDate=Сортування за датою
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Об'єднати merge.submit=Об'єднати

View file

@ -803,6 +803,7 @@ merge.title=合并
merge.header=合并多个PDF2个以上 merge.header=合并多个PDF2个以上
merge.sortByName=按名称排序 merge.sortByName=按名称排序
merge.sortByDate=按日期排序 merge.sortByDate=按日期排序
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=合并 merge.submit=合并

View file

@ -803,6 +803,7 @@ merge.title=合併
merge.header=合併多個 PDF merge.header=合併多個 PDF
merge.sortByName=依名稱排序 merge.sortByName=依名稱排序
merge.sortByDate=依日期排序 merge.sortByDate=依日期排序
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=合併 merge.submit=合併

View file

@ -19,9 +19,13 @@
</div> </div>
<form action="api/v1/general/merge-pdfs" method="post" enctype="multipart/form-data"> <form action="api/v1/general/merge-pdfs" method="post" enctype="multipart/form-data">
<div class="mb-3"> <div class="mb-3">
<label th:text="#{multiPdfDropPrompt}"></label> <label th:text="#{multiPdfDropPrompt}" for="fileInput-input"></label>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true, accept='application/pdf')}"></div>
</div> </div>
<div class="mb-3">
<input type="checkbox" name="removeCertSign" id="removeCertSign">
<label for="removeCertSign" th:text="#{merge.removeCertSign}">Remove digital signature in the merged file?</label>
</div>
<div class="mb-3"> <div class="mb-3">
<ul id="selectedFiles" class="list-group"></ul> <ul id="selectedFiles" class="list-group"></ul>
</div> </div>