mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-23 07:55:07 +00:00
created AttachmentsController
This commit is contained in:
parent
5e20957048
commit
38edd9b173
@ -1,28 +1,132 @@
|
|||||||
package stirling.software.SPDF.controller.api.misc;
|
package stirling.software.SPDF.controller.api.misc;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import java.io.ByteArrayInputStream;
|
||||||
import lombok.RequiredArgsConstructor;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
|
||||||
|
import org.apache.pdfbox.pdmodel.PageMode;
|
||||||
|
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
|
||||||
|
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
import io.github.pixee.security.Filenames;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/api/v1/misc")
|
@RequestMapping("/api/v1/misc")
|
||||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
|
@Slf4j
|
||||||
public class AttachmentsController {
|
public class AttachmentsController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/add-attachments")
|
@PostMapping(consumes = "multipart/form-data", value = "/add-attachments")
|
||||||
|
@Operation(
|
||||||
|
summary = "Add attachments to PDF",
|
||||||
|
description = "This endpoint adds embedded files (attachments) to a PDF and sets the PageMode to UseAttachments to make them visible. Input:PDF + Files Output:PDF Type:MISO")
|
||||||
public ResponseEntity<byte[]> addAttachments(
|
public ResponseEntity<byte[]> addAttachments(
|
||||||
String fileName, String attachmentName, byte[] attachmentData) {
|
@RequestParam("fileInput") MultipartFile pdfFile,
|
||||||
// Implementation for adding attachments to a PDF file
|
@RequestParam("attachments") List<MultipartFile> attachments)
|
||||||
// This is a placeholder method and should be implemented as per requirements.
|
throws IOException {
|
||||||
return ResponseEntity.ok()
|
|
||||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
|
// Load the PDF document
|
||||||
.body(attachmentData);
|
PDDocument document = pdfDocumentFactory.load(pdfFile, true);
|
||||||
|
|
||||||
|
// Get or create the document catalog
|
||||||
|
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||||
|
|
||||||
|
// Create embedded files name tree if it doesn't exist
|
||||||
|
PDEmbeddedFilesNameTreeNode efTree = catalog.getNames().getEmbeddedFiles();
|
||||||
|
if (efTree == null) {
|
||||||
|
efTree = new PDEmbeddedFilesNameTreeNode();
|
||||||
|
catalog.getNames().setEmbeddedFiles(efTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add each attachment
|
||||||
|
for (MultipartFile attachment : attachments) {
|
||||||
|
if (attachment != null && !attachment.isEmpty()) {
|
||||||
|
addEmbeddedFile(document, efTree, attachment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set PageMode to UseAttachments to show the attachments panel
|
||||||
|
catalog.setPageMode(PageMode.USE_ATTACHMENTS);
|
||||||
|
|
||||||
|
// Return the modified PDF
|
||||||
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
document,
|
||||||
|
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||||
|
.replaceFirst("[.][^.]+$", "") + "_with_attachments.pdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-attachments")
|
||||||
|
@Operation(
|
||||||
|
summary = "Remove attachments from PDF",
|
||||||
|
description = "This endpoint removes all embedded files (attachments) from a PDF. Input:PDF Output:PDF Type:SISO")
|
||||||
|
public ResponseEntity<byte[]> removeAttachments(
|
||||||
|
@RequestParam("fileInput") MultipartFile pdfFile)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
// Load the PDF document
|
||||||
|
PDDocument document = pdfDocumentFactory.load(pdfFile, true);
|
||||||
|
|
||||||
|
// Get the document catalog
|
||||||
|
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||||
|
|
||||||
|
// Remove embedded files
|
||||||
|
if (catalog.getNames() != null) {
|
||||||
|
catalog.getNames().setEmbeddedFiles(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset PageMode to UseNone (default)
|
||||||
|
catalog.setPageMode(PageMode.USE_NONE);
|
||||||
|
|
||||||
|
// Return the modified PDF
|
||||||
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
document,
|
||||||
|
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||||
|
.replaceFirst("[.][^.]+$", "") + "_attachments_removed.pdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEmbeddedFile(PDDocument document, PDEmbeddedFilesNameTreeNode efTree, MultipartFile file)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
// Create file specification
|
||||||
|
PDComplexFileSpecification fs = new PDComplexFileSpecification();
|
||||||
|
fs.setFile(file.getOriginalFilename());
|
||||||
|
fs.setFileDescription("Embedded file: " + file.getOriginalFilename());
|
||||||
|
|
||||||
|
// Create embedded file
|
||||||
|
PDEmbeddedFile ef = new PDEmbeddedFile(document, new ByteArrayInputStream(file.getBytes()));
|
||||||
|
ef.setSize((int) file.getSize());
|
||||||
|
ef.setCreationDate(new java.util.GregorianCalendar());
|
||||||
|
ef.setModDate(new java.util.GregorianCalendar());
|
||||||
|
|
||||||
|
// Set MIME type if available
|
||||||
|
String contentType = file.getContentType();
|
||||||
|
if (contentType != null && !contentType.isEmpty()) {
|
||||||
|
ef.setSubtype(contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associate embedded file with file specification
|
||||||
|
fs.setEmbeddedFile(ef);
|
||||||
|
|
||||||
|
// Add to the name tree
|
||||||
|
efTree.setNames(java.util.Collections.singletonMap(file.getOriginalFilename(), fs));
|
||||||
|
|
||||||
|
log.info("Added embedded file: {} ({} bytes)", file.getOriginalFilename(), file.getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,4 +191,11 @@ public class OtherWebController {
|
|||||||
model.addAttribute("currentPage", "auto-rename");
|
model.addAttribute("currentPage", "auto-rename");
|
||||||
return "misc/auto-rename";
|
return "misc/auto-rename";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/attachments")
|
||||||
|
@Hidden
|
||||||
|
public String attachmentsForm(Model model) {
|
||||||
|
model.addAttribute("currentPage", "attachments");
|
||||||
|
return "misc/attachments";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,6 +525,10 @@ home.addImage.title=Add image
|
|||||||
home.addImage.desc=Adds a image onto a set location on the PDF
|
home.addImage.desc=Adds a image onto a set location on the PDF
|
||||||
addImage.tags=img,jpg,picture,photo
|
addImage.tags=img,jpg,picture,photo
|
||||||
|
|
||||||
|
home.attachments.title=Attachments
|
||||||
|
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
|
||||||
|
attachments.tags=embed,attach,file,attachment
|
||||||
|
|
||||||
home.watermark.title=Add Watermark
|
home.watermark.title=Add Watermark
|
||||||
home.watermark.desc=Add a custom watermark to your PDF document.
|
home.watermark.desc=Add a custom watermark to your PDF document.
|
||||||
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
|
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
|
||||||
@ -1206,6 +1210,18 @@ addImage.upload=Add image
|
|||||||
addImage.submit=Add image
|
addImage.submit=Add image
|
||||||
|
|
||||||
|
|
||||||
|
#attachments
|
||||||
|
attachments.title=Attachments
|
||||||
|
attachments.header=Add attachments to PDF
|
||||||
|
attachments.removeHeader=Remove attachments from PDF
|
||||||
|
attachments.selectFiles=Select files to attach
|
||||||
|
attachments.description=Allows you to add attachments to the PDF
|
||||||
|
attachments.descriptionPlaceholder=Enter a description for the attachments...
|
||||||
|
attachments.addButton=Add Attachments
|
||||||
|
attachments.removeDescription=This will remove all embedded files from the PDF.
|
||||||
|
attachments.removeButton=Remove All Attachments
|
||||||
|
|
||||||
|
|
||||||
#merge
|
#merge
|
||||||
merge.title=Merge
|
merge.title=Merge
|
||||||
merge.header=Merge multiple PDFs (2+)
|
merge.header=Merge multiple PDFs (2+)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user