Compare commits

..

No commits in common. "71d673b4eb8b1e5460c50bb2a8db0a34c3706cf7" and "8c01425eeed94ae40b4903183ae75eb6af4be8a6" have entirely different histories.

58 changed files with 336 additions and 763 deletions

View file

@ -174,35 +174,35 @@ Stirling PDF currently supports 38!
| ------------------------------------------- | -------------------------------------- | | ------------------------------------------- | -------------------------------------- |
| Arabic (العربية) (ar_AR) | ![99%](https://geps.dev/progress/99) | | Arabic (العربية) (ar_AR) | ![99%](https://geps.dev/progress/99) |
| Basque (Euskara) (eu_ES) | ![60%](https://geps.dev/progress/60) | | Basque (Euskara) (eu_ES) | ![60%](https://geps.dev/progress/60) |
| Bulgarian (Български) (bg_BG) | ![91%](https://geps.dev/progress/91) | | Bulgarian (Български) (bg_BG) | ![92%](https://geps.dev/progress/92) |
| Catalan (Català) (ca_CA) | ![47%](https://geps.dev/progress/47) | | Catalan (Català) (ca_CA) | ![47%](https://geps.dev/progress/47) |
| Croatian (Hrvatski) (hr_HR) | ![91%](https://geps.dev/progress/91) | | Croatian (Hrvatski) (hr_HR) | ![92%](https://geps.dev/progress/92) |
| Czech (Česky) (cs_CZ) | ![87%](https://geps.dev/progress/87) | | Czech (Česky) (cs_CZ) | ![88%](https://geps.dev/progress/88) |
| Danish (Dansk) (da_DK) | ![96%](https://geps.dev/progress/96) | | Danish (Dansk) (da_DK) | ![97%](https://geps.dev/progress/97) |
| Dutch (Nederlands) (nl_NL) | ![93%](https://geps.dev/progress/93) | | Dutch (Nederlands) (nl_NL) | ![93%](https://geps.dev/progress/93) |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| French (Français) (fr_FR) | ![90%](https://geps.dev/progress/90) | | French (Français) (fr_FR) | ![91%](https://geps.dev/progress/91) |
| German (Deutsch) (de_DE) | ![98%](https://geps.dev/progress/98) | | German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
| Greek (Ελληνικά) (el_GR) | ![79%](https://geps.dev/progress/79) | | Greek (Ελληνικά) (el_GR) | ![80%](https://geps.dev/progress/80) |
| Hindi (हिंदी) (hi_IN) | ![76%](https://geps.dev/progress/76) | | Hindi (हिंदी) (hi_IN) | ![76%](https://geps.dev/progress/76) |
| Hungarian (Magyar) (hu_HU) | ![73%](https://geps.dev/progress/73) | | Hungarian (Magyar) (hu_HU) | ![74%](https://geps.dev/progress/74) |
| Indonesia (Bahasa Indonesia) (id_ID) | ![74%](https://geps.dev/progress/74) | | Indonesia (Bahasa Indonesia) (id_ID) | ![74%](https://geps.dev/progress/74) |
| Irish (Gaeilge) (ga_IE) | ![95%](https://geps.dev/progress/95) | | Irish (Gaeilge) (ga_IE) | ![96%](https://geps.dev/progress/96) |
| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) | | Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) |
| Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) | | Japanese (日本語) (ja_JP) | ![90%](https://geps.dev/progress/90) |
| Korean (한국어) (ko_KR) | ![81%](https://geps.dev/progress/81) | | Korean (한국어) (ko_KR) | ![82%](https://geps.dev/progress/82) |
| Norwegian (Norsk) (no_NB) | ![95%](https://geps.dev/progress/95) | | Norwegian (Norsk) (no_NB) | ![95%](https://geps.dev/progress/95) |
| Polish (Polski) (pl_PL) | ![89%](https://geps.dev/progress/89) | | Polish (Polski) (pl_PL) | ![90%](https://geps.dev/progress/90) |
| Portuguese (Português) (pt_PT) | ![76%](https://geps.dev/progress/76) | | Portuguese (Português) (pt_PT) | ![76%](https://geps.dev/progress/76) |
| Portuguese Brazilian (Português) (pt_BR) | ![98%](https://geps.dev/progress/98) | | Portuguese Brazilian (Português) (pt_BR) | ![99%](https://geps.dev/progress/99) |
| Romanian (Română) (ro_RO) | ![97%](https://geps.dev/progress/97) | | Romanian (Română) (ro_RO) | ![98%](https://geps.dev/progress/98) |
| Russian (Русский) (ru_RU) | ![81%](https://geps.dev/progress/81) | | Russian (Русский) (ru_RU) | ![82%](https://geps.dev/progress/82) |
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![76%](https://geps.dev/progress/76) | | Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![76%](https://geps.dev/progress/76) |
| Simplified Chinese (简体中文) (zh_CN) | ![98%](https://geps.dev/progress/98) | | Simplified Chinese (简体中文) (zh_CN) | ![99%](https://geps.dev/progress/99) |
| Slovakian (Slovensky) (sk_SK) | ![89%](https://geps.dev/progress/89) | | Slovakian (Slovensky) (sk_SK) | ![90%](https://geps.dev/progress/90) |
| Spanish (Español) (es_ES) | ![98%](https://geps.dev/progress/98) | | Spanish (Español) (es_ES) | ![99%](https://geps.dev/progress/99) |
| Swedish (Svenska) (sv_SE) | ![97%](https://geps.dev/progress/97) | | Swedish (Svenska) (sv_SE) | ![98%](https://geps.dev/progress/98) |
| Thai (ไทย) (th_TH) | ![96%](https://geps.dev/progress/96) | | Thai (ไทย) (th_TH) | ![96%](https://geps.dev/progress/96) |
| Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) | | Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) |
| Turkish (Türkçe) (tr_TR) | ![96%](https://geps.dev/progress/96) | | Turkish (Türkçe) (tr_TR) | ![96%](https://geps.dev/progress/96) |

View file

@ -22,7 +22,7 @@ ext {
} }
group = "stirling.software" group = "stirling.software"
version = "0.29.0" version = "0.28.3"
java { java {
// 17 is lowest but we support and recommend 21 // 17 is lowest but we support and recommend 21

View file

@ -1,5 +1,5 @@
apiVersion: v2 apiVersion: v2
appVersion: 0.29.0 appVersion: 0.28.3
description: locally hosted web application that allows you to perform various operations description: locally hosted web application that allows you to perform various operations
on PDF files on PDF files
home: https://github.com/Stirling-Tools/Stirling-PDF home: https://github.com/Stirling-Tools/Stirling-PDF

View file

@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface; import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.PdfMetadata; import stirling.software.SPDF.model.PdfMetadata;
@ -14,6 +15,8 @@ import stirling.software.SPDF.model.PdfMetadata;
@Service @Service
public class PdfMetadataService { public class PdfMetadataService {
private static PdfMetadataService instance;
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final String appVersion; private final String appVersion;
private final UserServiceInterface userService; private final UserServiceInterface userService;
@ -28,7 +31,33 @@ public class PdfMetadataService {
this.userService = userService; this.userService = userService;
} }
public PdfMetadata extractMetadataFromPdf(PDDocument pdf) { @PostConstruct
public void init() {
instance = this;
}
// Static methods for easy access
public static PdfMetadata extractMetadataFromPdf(PDDocument pdf) {
return instance.extractMetadataFromPdfInstance(pdf);
}
public static void setDefaultMetadata(PDDocument pdf) {
instance.setDefaultMetadataInstance(pdf);
}
public static void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata) {
instance.setMetadataToPdfInstance(pdf, pdfMetadata);
}
public static void setMetadataToPdf(
PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) {
instance.setMetadataToPdfInstance(pdf, pdfMetadata, newlyCreated);
}
// Instance methods
private PdfMetadata extractMetadataFromPdfInstance(PDDocument pdf) {
return PdfMetadata.builder() return PdfMetadata.builder()
.author(pdf.getDocumentInformation().getAuthor()) .author(pdf.getDocumentInformation().getAuthor())
.producer(pdf.getDocumentInformation().getProducer()) .producer(pdf.getDocumentInformation().getProducer())
@ -41,16 +70,17 @@ public class PdfMetadataService {
.build(); .build();
} }
public void setDefaultMetadata(PDDocument pdf) { private void setDefaultMetadataInstance(PDDocument pdf) {
PdfMetadata metadata = extractMetadataFromPdf(pdf); PdfMetadata metadata = extractMetadataFromPdfInstance(pdf);
setMetadataToPdf(pdf, metadata); setMetadataToPdfInstance(pdf, metadata);
} }
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata) { private void setMetadataToPdfInstance(PDDocument pdf, PdfMetadata pdfMetadata) {
setMetadataToPdf(pdf, pdfMetadata, false); setMetadataToPdfInstance(pdf, pdfMetadata, true);
} }
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) { private void setMetadataToPdfInstance(
PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) {
if (newlyCreated || pdfMetadata.getCreationDate() == null) { if (newlyCreated || pdfMetadata.getCreationDate() == null) {
setNewDocumentMetadata(pdf, pdfMetadata); setNewDocumentMetadata(pdf, pdfMetadata);
} }
@ -59,6 +89,7 @@ public class PdfMetadataService {
private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) { private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
String title = pdfMetadata.getTitle();
String creator = "Stirling-PDF"; String creator = "Stirling-PDF";
// if (applicationProperties // if (applicationProperties
@ -80,14 +111,13 @@ public class PdfMetadataService {
// } // }
// } // }
pdf.getDocumentInformation().setTitle(title);
pdf.getDocumentInformation().setCreator(creator + " " + appVersion); pdf.getDocumentInformation().setCreator(creator + " " + appVersion);
pdf.getDocumentInformation().setCreationDate(Calendar.getInstance()); pdf.getDocumentInformation().setCreationDate(Calendar.getInstance());
} }
private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) { private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
String producer = "Stirling-PDF"; String producer = "Stirling-PDF";
String title = pdfMetadata.getTitle();
pdf.getDocumentInformation().setTitle(title);
pdf.getDocumentInformation().setProducer(producer + " " + appVersion); pdf.getDocumentInformation().setProducer(producer + " " + appVersion);
pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject()); pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject());
pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords()); pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords());

View file

@ -13,7 +13,6 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -24,7 +23,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.CropPdfForm; import stirling.software.SPDF.model.api.general.CropPdfForm;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -34,13 +32,6 @@ public class CropController {
private static final Logger logger = LoggerFactory.getLogger(CropController.class); private static final Logger logger = LoggerFactory.getLogger(CropController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public CropController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/crop", consumes = "multipart/form-data") @PostMapping(value = "/crop", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Crops a PDF document", summary = "Crops a PDF document",
@ -49,8 +40,7 @@ public class CropController {
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException { public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException {
PDDocument sourceDocument = Loader.loadPDF(form.getFileInput().getBytes()); PDDocument sourceDocument = Loader.loadPDF(form.getFileInput().getBytes());
PDDocument newDocument = PDDocument newDocument = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
int totalPages = sourceDocument.getNumberOfPages(); int totalPages = sourceDocument.getNumberOfPages();

View file

@ -22,7 +22,6 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; 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.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -34,7 +33,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.MergePdfsRequest; import stirling.software.SPDF.model.api.general.MergePdfsRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -45,16 +43,9 @@ public class MergeController {
private static final Logger logger = LoggerFactory.getLogger(MergeController.class); private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public MergeController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
// Merges a list of PDDocument objects into a single PDDocument // 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 = pdfDocumentFactory.createNewDocument(); PDDocument mergedDoc = new PDDocument();
for (PDDocument doc : documents) { for (PDDocument doc : documents) {
for (PDPage page : doc.getPages()) { for (PDPage page : doc.getPages()) {
mergedDoc.addPage(page); mergedDoc.addPage(page);

View file

@ -14,7 +14,6 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -27,7 +26,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest; import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -37,13 +35,6 @@ public class MultiPageLayoutController {
private static final Logger logger = LoggerFactory.getLogger(MultiPageLayoutController.class); private static final Logger logger = LoggerFactory.getLogger(MultiPageLayoutController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public MultiPageLayoutController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data") @PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Merge multiple pages of a PDF document into a single page", summary = "Merge multiple pages of a PDF document into a single page",
@ -69,8 +60,7 @@ public class MultiPageLayoutController {
int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet); int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet);
PDDocument sourceDocument = Loader.loadPDF(file.getBytes()); PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
PDDocument newDocument = PDDocument newDocument = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
PDPage newPage = new PDPage(PDRectangle.A4); PDPage newPage = new PDPage(PDRectangle.A4);
newDocument.addPage(newPage); newDocument.addPage(newPage);

View file

@ -3,15 +3,16 @@ package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.service.PdfImageRemovalService; import stirling.software.SPDF.service.PdfImageRemovalService;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -24,21 +25,15 @@ import stirling.software.SPDF.utils.WebResponseUtils;
public class PdfImageRemovalController { public class PdfImageRemovalController {
// Service for removing images from PDFs // Service for removing images from PDFs
private final PdfImageRemovalService pdfImageRemovalService; @Autowired private PdfImageRemovalService pdfImageRemovalService;
private final CustomPDDocumentFactory pdfDocumentFactory;
/** /**
* Constructor for dependency injection of PdfImageRemovalService. * Constructor for dependency injection of PdfImageRemovalService.
* *
* @param pdfImageRemovalService The service used for removing images from PDFs. * @param pdfImageRemovalService The service used for removing images from PDFs.
*/ */
@Autowired public PdfImageRemovalController(PdfImageRemovalService pdfImageRemovalService) {
public PdfImageRemovalController(
PdfImageRemovalService pdfImageRemovalService,
CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfImageRemovalService = pdfImageRemovalService; this.pdfImageRemovalService = pdfImageRemovalService;
this.pdfDocumentFactory = pdfDocumentFactory;
} }
/** /**
@ -58,8 +53,14 @@ public class PdfImageRemovalController {
description = description =
"This endpoint remove images from file to reduce the file size.Input:PDF Output:PDF Type:MISO") "This endpoint remove images from file to reduce the file size.Input:PDF Output:PDF Type:MISO")
public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException { public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException {
// Load the PDF document
PDDocument document = pdfDocumentFactory.load(file); MultipartFile pdf = file.getFileInput();
// Convert the MultipartFile to a byte array
byte[] pdfBytes = pdf.getBytes();
// Load the PDF document from the byte array
PDDocument document = Loader.loadPDF(pdfBytes);
// Remove images from the PDF document using the service // Remove images from the PDF document using the service
PDDocument modifiedDocument = pdfImageRemovalService.removeImagesFromPdf(document); PDDocument modifiedDocument = pdfImageRemovalService.removeImagesFromPdf(document);
@ -73,8 +74,7 @@ public class PdfImageRemovalController {
// Generate a new filename for the modified PDF // Generate a new filename for the modified PDF
String mergedFileName = String mergedFileName =
file.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "") pdf.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_removed_images.pdf";
+ "_removed_images.pdf";
// Convert the byte array to a web response and return it // Convert the byte array to a web response and return it
return WebResponseUtils.bytesToWebResponse(outputStream.toByteArray(), mergedFileName); return WebResponseUtils.bytesToWebResponse(outputStream.toByteArray(), mergedFileName);

View file

@ -12,7 +12,6 @@ import java.util.Map;
import org.apache.pdfbox.Loader; import org.apache.pdfbox.Loader;
import org.apache.pdfbox.multipdf.Overlay; import org.apache.pdfbox.multipdf.Overlay;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -26,7 +25,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest; import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -35,13 +33,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@Tag(name = "General", description = "General APIs") @Tag(name = "General", description = "General APIs")
public class PdfOverlayController { public class PdfOverlayController {
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public PdfOverlayController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data") @PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Overlay PDF files in various modes", summary = "Overlay PDF files in various modes",
@ -65,7 +56,7 @@ public class PdfOverlayController {
// "FixedRepeatOverlay" // "FixedRepeatOverlay"
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
try (PDDocument basePdf = pdfDocumentFactory.load(baseFile); try (PDDocument basePdf = Loader.loadPDF(baseFile.getBytes());
Overlay overlay = new Overlay()) { Overlay overlay = new Overlay()) {
Map<Integer, String> overlayGuide = Map<Integer, String> overlayGuide =
prepareOverlayGuide( prepareOverlayGuide(

View file

@ -10,7 +10,6 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -25,7 +24,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.SortTypes; import stirling.software.SPDF.model.SortTypes;
import stirling.software.SPDF.model.api.PDFWithPageNums; import stirling.software.SPDF.model.api.PDFWithPageNums;
import stirling.software.SPDF.model.api.general.RearrangePagesRequest; import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -36,13 +34,6 @@ public class RearrangePagesPDFController {
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class); private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public RearrangePagesPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages") @PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
@Operation( @Operation(
summary = "Remove pages from a PDF file", summary = "Remove pages from a PDF file",
@ -54,7 +45,7 @@ public class RearrangePagesPDFController {
MultipartFile pdfFile = request.getFileInput(); MultipartFile pdfFile = request.getFileInput();
String pagesToDelete = request.getPageNumbers(); String pagesToDelete = request.getPageNumbers();
PDDocument document = pdfDocumentFactory.load(pdfFile); PDDocument document = Loader.loadPDF(pdfFile.getBytes());
// Split the page order string into an array of page numbers or range of numbers // Split the page order string into an array of page numbers or range of numbers
String[] pageOrderArr = pagesToDelete.split(","); String[] pageOrderArr = pagesToDelete.split(",");

View file

@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api;
import java.io.IOException; import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageTree; import org.apache.pdfbox.pdmodel.PDPageTree;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -20,7 +20,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.RotatePDFRequest; import stirling.software.SPDF.model.api.general.RotatePDFRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -30,13 +29,6 @@ public class RotationController {
private static final Logger logger = LoggerFactory.getLogger(RotationController.class); private static final Logger logger = LoggerFactory.getLogger(RotationController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public RotationController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf") @PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
@Operation( @Operation(
summary = "Rotate a PDF file", summary = "Rotate a PDF file",
@ -47,7 +39,7 @@ public class RotationController {
MultipartFile pdfFile = request.getFileInput(); MultipartFile pdfFile = request.getFileInput();
Integer angle = request.getAngle(); Integer angle = request.getAngle();
// Load the PDF document // Load the PDF document
PDDocument document = pdfDocumentFactory.load(request); PDDocument document = Loader.loadPDF(pdfFile.getBytes());
// Get the list of pages in the document // Get the list of pages in the document
PDPageTree pages = document.getPages(); PDPageTree pages = document.getPages();

View file

@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -28,7 +27,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.ScalePagesRequest; import stirling.software.SPDF.model.api.general.ScalePagesRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -38,13 +36,6 @@ public class ScalePagesController {
private static final Logger logger = LoggerFactory.getLogger(ScalePagesController.class); private static final Logger logger = LoggerFactory.getLogger(ScalePagesController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ScalePagesController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/scale-pages", consumes = "multipart/form-data") @PostMapping(value = "/scale-pages", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Change the size of a PDF page/document", summary = "Change the size of a PDF page/document",
@ -57,8 +48,7 @@ public class ScalePagesController {
float scaleFactor = request.getScaleFactor(); float scaleFactor = request.getScaleFactor();
PDDocument sourceDocument = Loader.loadPDF(file.getBytes()); PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
PDDocument outputDocument = PDDocument outputDocument = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
PDRectangle targetSize = getTargetSize(targetPDRectangle, sourceDocument); PDRectangle targetSize = getTargetSize(targetPDRectangle, sourceDocument);

View file

@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -28,8 +27,9 @@ import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.config.PdfMetadataService;
import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.PDFWithPageNums; import stirling.software.SPDF.model.api.PDFWithPageNums;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -38,12 +38,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
public class SplitPDFController { public class SplitPDFController {
private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class); private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public SplitPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/split-pages") @PostMapping(consumes = "multipart/form-data", value = "/split-pages")
@Operation( @Operation(
@ -57,7 +51,7 @@ public class SplitPDFController {
// open the pdf document // open the pdf document
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());
// PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document); PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
int totalPages = document.getNumberOfPages(); int totalPages = document.getNumberOfPages();
List<Integer> pageNumbers = request.getPageNumbersList(document, false); List<Integer> pageNumbers = request.getPageNumbersList(document, false);
System.out.println( System.out.println(
@ -76,8 +70,7 @@ public class SplitPDFController {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>(); List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
int previousPageNumber = 0; int previousPageNumber = 0;
for (int splitPoint : pageNumbers) { for (int splitPoint : pageNumbers) {
try (PDDocument splitDocument = try (PDDocument splitDocument = new PDDocument()) {
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document)) {
for (int i = previousPageNumber; i <= splitPoint; i++) { for (int i = previousPageNumber; i <= splitPoint; i++) {
PDPage page = document.getPage(i); PDPage page = document.getPage(i);
splitDocument.addPage(page); splitDocument.addPage(page);
@ -86,7 +79,7 @@ public class SplitPDFController {
previousPageNumber = splitPoint + 1; previousPageNumber = splitPoint + 1;
// Transfer metadata to split pdf // Transfer metadata to split pdf
// PdfMetadataService.setMetadataToPdf(splitDocument, metadata); PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDocument.save(baos); splitDocument.save(baos);

View file

@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocume
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -45,13 +44,6 @@ public class SplitPdfByChaptersController {
private static final Logger logger = private static final Logger logger =
LoggerFactory.getLogger(SplitPdfByChaptersController.class); LoggerFactory.getLogger(SplitPdfByChaptersController.class);
private final PdfMetadataService pdfMetadataService;
@Autowired
public SplitPdfByChaptersController(PdfMetadataService pdfMetadataService) {
this.pdfMetadataService = pdfMetadataService;
}
@PostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data") @PostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Split PDFs by Chapters", summary = "Split PDFs by Chapters",
@ -266,7 +258,7 @@ public class SplitPdfByChaptersController {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>(); List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
PdfMetadata metadata = null; PdfMetadata metadata = null;
if (includeMetadata) { if (includeMetadata) {
metadata = pdfMetadataService.extractMetadataFromPdf(sourceDocument); metadata = PdfMetadataService.extractMetadataFromPdf(sourceDocument);
} }
for (Bookmark bookmark : bookmarks) { for (Bookmark bookmark : bookmarks) {
try (PDDocument splitDocument = new PDDocument()) { try (PDDocument splitDocument = new PDDocument()) {
@ -281,7 +273,7 @@ public class SplitPdfByChaptersController {
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (includeMetadata) { if (includeMetadata) {
pdfMetadataService.setMetadataToPdf(splitDocument, metadata); PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
} }
splitDocument.save(baos); splitDocument.save(baos);

View file

@ -20,7 +20,6 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -34,7 +33,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest; import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -45,13 +43,6 @@ public class SplitPdfBySectionsController {
private static final Logger logger = private static final Logger logger =
LoggerFactory.getLogger(SplitPdfBySectionsController.class); LoggerFactory.getLogger(SplitPdfBySectionsController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public SplitPdfBySectionsController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data") @PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Split PDF pages into smaller sections", summary = "Split PDF pages into smaller sections",
@ -74,7 +65,7 @@ public class SplitPdfBySectionsController {
Filenames.toSimpleFileName(file.getOriginalFilename()) Filenames.toSimpleFileName(file.getOriginalFilename())
.replaceFirst("[.][^.]+$", ""); .replaceFirst("[.][^.]+$", "");
if (merge) { if (merge) {
MergeController mergeController = new MergeController(pdfDocumentFactory); MergeController mergeController = new MergeController();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
mergeController.mergeDocuments(splitDocuments).save(baos); mergeController.mergeDocuments(splitDocuments).save(baos);
return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), filename + "_split.pdf"); return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), filename + "_split.pdf");

View file

@ -12,7 +12,6 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -26,7 +25,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest; import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -36,12 +34,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
public class SplitPdfBySizeController { public class SplitPdfBySizeController {
private static final Logger logger = LoggerFactory.getLogger(SplitPdfBySizeController.class); private static final Logger logger = LoggerFactory.getLogger(SplitPdfBySizeController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public SplitPdfBySizeController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data") @PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
@Operation( @Operation(
@ -92,8 +84,7 @@ public class SplitPdfBySizeController {
PDDocument sourceDocument, long maxBytes, ZipOutputStream zipOut, String baseFilename) PDDocument sourceDocument, long maxBytes, ZipOutputStream zipOut, String baseFilename)
throws IOException { throws IOException {
long currentSize = 0; long currentSize = 0;
PDDocument currentDoc = PDDocument currentDoc = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
int fileIndex = 1; int fileIndex = 1;
for (int pageIndex = 0; pageIndex < sourceDocument.getNumberOfPages(); pageIndex++) { for (int pageIndex = 0; pageIndex < sourceDocument.getNumberOfPages(); pageIndex++) {
@ -130,8 +121,7 @@ public class SplitPdfBySizeController {
PDDocument sourceDocument, int pageCount, ZipOutputStream zipOut, String baseFilename) PDDocument sourceDocument, int pageCount, ZipOutputStream zipOut, String baseFilename)
throws IOException { throws IOException {
int currentPageCount = 0; int currentPageCount = 0;
PDDocument currentDoc = PDDocument currentDoc = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
int fileIndex = 1; int fileIndex = 1;
for (PDPage page : sourceDocument.getPages()) { for (PDPage page : sourceDocument.getPages()) {
currentDoc.addPage(page); currentDoc.addPage(page);
@ -162,8 +152,7 @@ public class SplitPdfBySizeController {
int currentPageIndex = 0; int currentPageIndex = 0;
int fileIndex = 1; int fileIndex = 1;
for (int i = 0; i < documentCount; i++) { for (int i = 0; i < documentCount; i++) {
PDDocument currentDoc = PDDocument currentDoc = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0); int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
for (int j = 0; j < pagesToAdd; j++) { for (int j = 0; j < pagesToAdd; j++) {

View file

@ -13,7 +13,6 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -24,7 +23,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -34,13 +32,6 @@ public class ToSinglePageController {
private static final Logger logger = LoggerFactory.getLogger(ToSinglePageController.class); private static final Logger logger = LoggerFactory.getLogger(ToSinglePageController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ToSinglePageController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page") @PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
@Operation( @Operation(
summary = "Convert a multi-page PDF into a single long page PDF", summary = "Convert a multi-page PDF into a single long page PDF",
@ -62,8 +53,7 @@ public class ToSinglePageController {
} }
// Create new document and page with calculated dimensions // Create new document and page with calculated dimensions
PDDocument newDocument = PDDocument newDocument = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
PDPage newPage = new PDPage(new PDRectangle(maxWidth, totalHeight)); PDPage newPage = new PDPage(new PDRectangle(maxWidth, totalHeight));
newDocument.addPage(newPage); newDocument.addPage(newPage);

View file

@ -1,36 +1,30 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.GeneralFile; import stirling.software.SPDF.model.api.GeneralFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertBookToPDFController { public class ConvertBookToPDFController {
private final boolean bookAndHtmlFormatsInstalled; @Autowired
@Qualifier("bookAndHtmlFormatsInstalled")
private final CustomPDDocumentFactory pdfDocumentFactory; private boolean bookAndHtmlFormatsInstalled;
// @Autowired
public ConvertBookToPDFController(
CustomPDDocumentFactory pdfDocumentFactory,
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
this.pdfDocumentFactory = pdfDocumentFactory;
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
}
@PostMapping(consumes = "multipart/form-data", value = "/book/pdf") @PostMapping(consumes = "multipart/form-data", value = "/book/pdf")
@Operation( @Operation(

View file

@ -1,25 +1,28 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest; import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertHtmlToPDF { public class ConvertHtmlToPDF {
// @Autowired @Autowired
@Qualifier("bookAndHtmlFormatsInstalled") @Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private boolean bookAndHtmlFormatsInstalled;

View file

@ -16,7 +16,6 @@ import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.ImageType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -31,7 +30,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest; import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest; import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.CheckProgramInstall; import stirling.software.SPDF.utils.CheckProgramInstall;
import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
@ -45,13 +43,6 @@ public class ConvertImgPDFController {
private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class); private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertImgPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/pdf/img") @PostMapping(consumes = "multipart/form-data", value = "/pdf/img")
@Operation( @Operation(
summary = "Convert PDF to image(s)", summary = "Convert PDF to image(s)",
@ -187,8 +178,7 @@ public class ConvertImgPDFController {
boolean autoRotate = request.isAutoRotate(); boolean autoRotate = request.isAutoRotate();
// Convert the file to PDF and get the resulting bytes // Convert the file to PDF and get the resulting bytes
byte[] bytes = byte[] bytes = PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType);
PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType, pdfDocumentFactory);
return WebResponseUtils.bytesToWebResponse( return WebResponseUtils.bytesToWebResponse(
bytes, bytes,
file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_converted.pdf"); file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_converted.pdf");

View file

@ -10,26 +10,29 @@ import org.commonmark.node.Node;
import org.commonmark.parser.Parser; import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.AttributeProvider; import org.commonmark.renderer.html.AttributeProvider;
import org.commonmark.renderer.html.HtmlRenderer; import org.commonmark.renderer.html.HtmlRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.GeneralFile; import stirling.software.SPDF.model.api.GeneralFile;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertMarkdownToPdf { public class ConvertMarkdownToPdf {
// @Autowired @Autowired
@Qualifier("bookAndHtmlFormatsInstalled") @Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private boolean bookAndHtmlFormatsInstalled;

View file

@ -1,6 +1,5 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -9,8 +8,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -23,7 +20,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.GeneralFile; import stirling.software.SPDF.model.api.GeneralFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -33,7 +29,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@RequestMapping("/api/v1/convert") @RequestMapping("/api/v1/convert")
public class ConvertOfficeController { public class ConvertOfficeController {
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException { public byte[] convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
// Check for valid file extension // Check for valid file extension
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename()); String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
if (originalFilename == null if (originalFilename == null
@ -66,10 +62,12 @@ public class ConvertOfficeController {
.runCommandWithOutputHandling(command); .runCommandWithOutputHandling(command);
// Read the converted PDF file // Read the converted PDF file
return tempOutputFile.toFile(); byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
return pdfBytes;
} finally { } finally {
// Clean up the temporary files // Clean up the temporary files
if (tempInputFile != null) Files.deleteIfExists(tempInputFile); if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
Files.deleteIfExists(tempOutputFile);
} }
} }
@ -78,13 +76,6 @@ public class ConvertOfficeController {
return fileExtension.matches(extensionPattern); return fileExtension.matches(extensionPattern);
} }
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertOfficeController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/file/pdf") @PostMapping(consumes = "multipart/form-data", value = "/file/pdf")
@Operation( @Operation(
summary = "Convert a file to a PDF using LibreOffice", summary = "Convert a file to a PDF using LibreOffice",
@ -95,18 +86,12 @@ public class ConvertOfficeController {
MultipartFile inputFile = request.getFileInput(); MultipartFile inputFile = request.getFileInput();
// unused but can start server instance if startup time is to long // unused but can start server instance if startup time is to long
// LibreOfficeListener.getInstance().start(); // LibreOfficeListener.getInstance().start();
File file = null;
try {
file = convertToPdf(inputFile);
PDDocument doc = pdfDocumentFactory.load(file); byte[] pdfByteArray = convertToPdf(inputFile);
return WebResponseUtils.pdfDocToWebResponse( return WebResponseUtils.bytesToWebResponse(
doc, pdfByteArray,
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "") .replaceFirst("[.][^.]+$", "")
+ "_convertedToPDF.pdf"); + "_convertedToPDF.pdf");
} finally {
if (file != null) file.delete();
}
} }
} }

View file

@ -6,27 +6,30 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.PdfToBookRequest; import stirling.software.SPDF.model.api.converters.PdfToBookRequest;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertPDFToBookController { public class ConvertPDFToBookController {
// @Autowired @Autowired
@Qualifier("bookAndHtmlFormatsInstalled") @Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private boolean bookAndHtmlFormatsInstalled;

View file

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
@ -16,7 +17,6 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; 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.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -29,7 +29,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest; import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -41,13 +40,6 @@ public class ConvertPDFToPDFA {
private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class); private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertPDFToPDFA(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa") @PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
@Operation( @Operation(
summary = "Convert a PDF to a PDF/A", summary = "Convert a PDF to a PDF/A",
@ -62,7 +54,7 @@ public class ConvertPDFToPDFA {
byte[] pdfBytes = inputFile.getBytes(); byte[] pdfBytes = inputFile.getBytes();
// Load the PDF document // Load the PDF document
PDDocument document = pdfDocumentFactory.load(pdfBytes); PDDocument document = Loader.loadPDF(pdfBytes);
// Get the document catalog // Get the document catalog
PDDocumentCatalog catalog = document.getDocumentCatalog(); PDDocumentCatalog catalog = document.getDocumentCatalog();
@ -109,18 +101,18 @@ public class ConvertPDFToPDFA {
ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF) ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF)
.runCommandWithOutputHandling(command); .runCommandWithOutputHandling(command);
try { // Read the optimized PDF file
PDDocument doc = pdfDocumentFactory.load(tempOutputFile.toFile()); byte[] optimizedPdfBytes = Files.readAllBytes(tempOutputFile);
// Clean up the temporary files
Files.deleteIfExists(tempInputFile);
Files.deleteIfExists(tempOutputFile);
// Return the optimized PDF as a response // Return the optimized PDF as a response
String outputFilename = String outputFilename =
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "") .replaceFirst("[.][^.]+$", "")
+ "_PDFA.pdf"; + "_PDFA.pdf";
return WebResponseUtils.pdfDocToWebResponse(doc, outputFilename); return WebResponseUtils.bytesToWebResponse(optimizedPdfBytes, outputFilename);
} finally {
// Clean up the temporary files
Files.deleteIfExists(tempInputFile);
Files.deleteIfExists(tempOutputFile);
}
} }
} }

View file

@ -6,10 +6,6 @@ import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -20,7 +16,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest; import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
@ -31,15 +26,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@RequestMapping("/api/v1/convert") @RequestMapping("/api/v1/convert")
public class ConvertWebsiteToPDF { public class ConvertWebsiteToPDF {
private static final Logger logger = LoggerFactory.getLogger(ConvertWebsiteToPDF.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertWebsiteToPDF(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf") @PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
@Operation( @Operation(
summary = "Convert a URL to a PDF", summary = "Convert a URL to a PDF",
@ -60,12 +46,12 @@ public class ConvertWebsiteToPDF {
} }
Path tempOutputFile = null; Path tempOutputFile = null;
PDDocument doc = null; byte[] pdfBytes;
try { try {
// Prepare the output file path // Prepare the output file path
tempOutputFile = Files.createTempFile("output_", ".pdf"); tempOutputFile = Files.createTempFile("output_", ".pdf");
// Prepare the WeasyPrint command // Prepare the OCRmyPDF command
List<String> command = new ArrayList<>(); List<String> command = new ArrayList<>();
command.add("weasyprint"); command.add("weasyprint");
command.add(URL); command.add(URL);
@ -75,23 +61,16 @@ public class ConvertWebsiteToPDF {
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT) ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
.runCommandWithOutputHandling(command); .runCommandWithOutputHandling(command);
// Load the PDF using pdfDocumentFactory // Read the optimized PDF file
doc = pdfDocumentFactory.load(tempOutputFile.toFile()); pdfBytes = Files.readAllBytes(tempOutputFile);
} finally {
// Clean up the temporary files
Files.deleteIfExists(tempOutputFile);
}
// Convert URL to a safe filename // Convert URL to a safe filename
String outputFilename = convertURLToFileName(URL); String outputFilename = convertURLToFileName(URL);
return WebResponseUtils.pdfDocToWebResponse(doc, outputFilename); return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
} finally {
if (tempOutputFile != null) {
try {
Files.deleteIfExists(tempOutputFile);
} catch (IOException e) {
logger.error("Error deleting temporary output file", e);
}
}
}
} }
private String convertURLToFileName(String url) { private String convertURLToFileName(String url) {

View file

@ -30,13 +30,13 @@ import stirling.software.SPDF.model.api.extract.PDFFilePage;
@RestController @RestController
@RequestMapping("/api/v1/convert") @RequestMapping("/api/v1/convert")
@Tag(name = "Convert", description = "Convert APIs") @Tag(name = "Convert", description = "Convert APIs")
public class ExtractCSVController { public class ExtractController {
private static final Logger logger = LoggerFactory.getLogger(CropController.class); private static final Logger logger = LoggerFactory.getLogger(CropController.class);
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data") @PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Extracts a CSV document from a PDF", summary = "Extracts a PDF document to csv",
description = description =
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO") "This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception { public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {

View file

@ -12,11 +12,11 @@ import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -38,7 +38,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest; import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -50,13 +49,6 @@ public class AutoSplitPdfController {
private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF"; private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF";
private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF"; private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF";
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public AutoSplitPdfController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data") @PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Auto split PDF pages into separate documents", summary = "Auto split PDF pages into separate documents",
@ -67,15 +59,11 @@ public class AutoSplitPdfController {
MultipartFile file = request.getFileInput(); MultipartFile file = request.getFileInput();
boolean duplexMode = request.isDuplexMode(); boolean duplexMode = request.isDuplexMode();
PDDocument document = null; PDDocument document = Loader.loadPDF(file.getBytes());
List<PDDocument> splitDocuments = new ArrayList<>();
Path zipFile = null;
byte[] data = null;
try {
document = pdfDocumentFactory.load(file.getInputStream());
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true); pdfRenderer.setSubsamplingAllowed(true);
List<PDDocument> splitDocuments = new ArrayList<>();
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
for (int page = 0; page < document.getNumberOfPages(); ++page) { for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150); BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
@ -103,18 +91,25 @@ public class AutoSplitPdfController {
// Remove split documents that have no pages // Remove split documents that have no pages
splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0); splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0);
zipFile = Files.createTempFile("split_documents", ".zip"); for (PDDocument splitDocument : splitDocuments) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDocument.save(baos);
splitDocumentsBoas.add(baos);
splitDocument.close();
}
document.close();
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = String filename =
Filenames.toSimpleFileName(file.getOriginalFilename()) Filenames.toSimpleFileName(file.getOriginalFilename())
.replaceFirst("[.][^.]+$", ""); .replaceFirst("[.][^.]+$", "");
byte[] data;
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) { try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
for (int i = 0; i < splitDocuments.size(); i++) { for (int i = 0; i < splitDocumentsBoas.size(); i++) {
String fileName = filename + "_" + (i + 1) + ".pdf"; String fileName = filename + "_" + (i + 1) + ".pdf";
PDDocument splitDocument = splitDocuments.get(i); ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDocument.save(baos);
byte[] pdf = baos.toByteArray(); byte[] pdf = baos.toByteArray();
ZipEntry pdfEntry = new ZipEntry(fileName); ZipEntry pdfEntry = new ZipEntry(fileName);
@ -122,38 +117,15 @@ public class AutoSplitPdfController {
zipOut.write(pdf); zipOut.write(pdf);
zipOut.closeEntry(); zipOut.closeEntry();
} }
} } catch (Exception e) {
logger.error("exception", e);
} finally {
data = Files.readAllBytes(zipFile); data = Files.readAllBytes(zipFile);
Files.deleteIfExists(zipFile);
}
return WebResponseUtils.bytesToWebResponse( return WebResponseUtils.bytesToWebResponse(
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM); data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
} finally {
// Clean up resources
if (document != null) {
try {
document.close();
} catch (IOException e) {
logger.error("Error closing main PDDocument", e);
}
}
for (PDDocument splitDoc : splitDocuments) {
try {
splitDoc.close();
} catch (IOException e) {
logger.error("Error closing split PDDocument", e);
}
}
if (zipFile != null) {
try {
Files.deleteIfExists(zipFile);
} catch (IOException e) {
logger.error("Error deleting temporary zip file", e);
}
}
}
} }
private static String decodeQRCode(BufferedImage bufferedImage) { private static String decodeQRCode(BufferedImage bufferedImage) {

View file

@ -16,7 +16,6 @@ import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper; import org.apache.pdfbox.text.PDFTextStripper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -31,7 +30,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest; import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -42,13 +40,6 @@ public class BlankPageController {
private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class); private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public BlankPageController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/remove-blanks") @PostMapping(consumes = "multipart/form-data", value = "/remove-blanks")
@Operation( @Operation(
summary = "Remove blank pages from a PDF file", summary = "Remove blank pages from a PDF file",
@ -133,7 +124,7 @@ public class BlankPageController {
public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName) public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName)
throws IOException { throws IOException {
try (PDDocument document = pdfDocumentFactory.createNewDocument()) { try (PDDocument document = new PDDocument()) {
for (PDPage page : pages) { for (PDPage page : pages) {
document.addPage(page); document.addPage(page);

View file

@ -20,7 +20,6 @@ import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -33,7 +32,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest; import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
@ -46,13 +44,6 @@ public class CompressController {
private static final Logger logger = LoggerFactory.getLogger(CompressController.class); private static final Logger logger = LoggerFactory.getLogger(CompressController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public CompressController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf") @PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
@Operation( @Operation(
summary = "Optimize PDF file", summary = "Optimize PDF file",
@ -267,7 +258,7 @@ public class CompressController {
} }
// Read the optimized PDF file // Read the optimized PDF file
pdfBytes = Files.readAllBytes(tempOutputFile); pdfBytes = Files.readAllBytes(tempOutputFile);
Path finalFile = tempOutputFile;
// Check if optimized file is larger than the original // Check if optimized file is larger than the original
if (pdfBytes.length > inputFileSize) { if (pdfBytes.length > inputFileSize) {
// Log the occurrence // Log the occurrence
@ -275,15 +266,14 @@ public class CompressController {
"Optimized file is larger than the original. Returning the original file instead."); "Optimized file is larger than the original. Returning the original file instead.");
// Read the original file again // Read the original file again
finalFile = tempInputFile; pdfBytes = Files.readAllBytes(tempInputFile);
} }
// Return the optimized PDF as a response // Return the optimized PDF as a response
String outputFilename = String outputFilename =
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "") .replaceFirst("[.][^.]+$", "")
+ "_Optimized.pdf"; + "_Optimized.pdf";
return WebResponseUtils.pdfDocToWebResponse( return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
pdfDocumentFactory.load(finalFile.toFile()), outputFilename);
} finally { } finally {
// Clean up the temporary files // Clean up the temporary files

View file

@ -14,7 +14,6 @@ import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -26,8 +25,9 @@ import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.config.PdfMetadataService;
import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.misc.FlattenRequest; import stirling.software.SPDF.model.api.misc.FlattenRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -37,13 +37,6 @@ public class FlattenController {
private static final Logger logger = LoggerFactory.getLogger(FlattenController.class); private static final Logger logger = LoggerFactory.getLogger(FlattenController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public FlattenController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/flatten") @PostMapping(consumes = "multipart/form-data", value = "/flatten")
@Operation( @Operation(
summary = "Flatten PDF form fields or full page", summary = "Flatten PDF form fields or full page",
@ -53,6 +46,7 @@ public class FlattenController {
MultipartFile file = request.getFileInput(); MultipartFile file = request.getFileInput();
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());
PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
Boolean flattenOnlyForms = request.getFlattenOnlyForms(); Boolean flattenOnlyForms = request.getFlattenOnlyForms();
if (Boolean.TRUE.equals(flattenOnlyForms)) { if (Boolean.TRUE.equals(flattenOnlyForms)) {
@ -66,8 +60,7 @@ public class FlattenController {
// flatten whole page aka convert each page to image and readd it (making text // flatten whole page aka convert each page to image and readd it (making text
// unselectable) // unselectable)
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
PDDocument newDocument = PDDocument newDocument = new PDDocument();
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document);
int numPages = document.getNumberOfPages(); int numPages = document.getNumberOfPages();
for (int i = 0; i < numPages; i++) { for (int i = 0; i < numPages; i++) {
try { try {
@ -87,6 +80,7 @@ public class FlattenController {
logger.error("exception", e); logger.error("exception", e);
} }
} }
PdfMetadataService.setMetadataToPdf(newDocument, metadata);
return WebResponseUtils.pdfDocToWebResponse( return WebResponseUtils.pdfDocToWebResponse(
newDocument, Filenames.toSimpleFileName(file.getOriginalFilename())); newDocument, Filenames.toSimpleFileName(file.getOriginalFilename()));
} }

View file

@ -1,6 +1,5 @@
package stirling.software.SPDF.controller.api.misc; package stirling.software.SPDF.controller.api.misc;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -29,7 +28,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest; import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -54,13 +52,6 @@ public class OCRController {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public OCRController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf") @PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
@Operation( @Operation(
summary = "Process a PDF file with OCR", summary = "Process a PDF file with OCR",
@ -184,7 +175,7 @@ public class OCRController {
tempOutputFile = tempPdfWithoutImages; tempOutputFile = tempPdfWithoutImages;
} }
// Read the OCR processed PDF file // Read the OCR processed PDF file
byte[] pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile()); byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
// Return the OCR processed PDF as a response // Return the OCR processed PDF as a response
String outputFilename = String outputFilename =
@ -205,13 +196,7 @@ public class OCRController {
// Add PDF file to the zip // Add PDF file to the zip
ZipEntry pdfEntry = new ZipEntry(outputFilename); ZipEntry pdfEntry = new ZipEntry(outputFilename);
zipOut.putNextEntry(pdfEntry); zipOut.putNextEntry(pdfEntry);
try (ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes)) { Files.copy(tempOutputFile, zipOut);
byte[] buffer = new byte[1024];
int length;
while ((length = pdfInputStream.read(buffer)) != -1) {
zipOut.write(buffer, 0, length);
}
}
zipOut.closeEntry(); zipOut.closeEntry();
// Add text file to the zip // Add text file to the zip

View file

@ -4,7 +4,6 @@ import java.io.IOException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -18,7 +17,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.OverlayImageRequest; import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -29,13 +27,6 @@ public class OverlayImageController {
private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class); private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public OverlayImageController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/add-image") @PostMapping(consumes = "multipart/form-data", value = "/add-image")
@Operation( @Operation(
summary = "Overlay image onto a PDF file", summary = "Overlay image onto a PDF file",
@ -50,9 +41,7 @@ public class OverlayImageController {
try { try {
byte[] pdfBytes = pdfFile.getBytes(); byte[] pdfBytes = pdfFile.getBytes();
byte[] imageBytes = imageFile.getBytes(); byte[] imageBytes = imageFile.getBytes();
byte[] result = byte[] result = PdfUtils.overlayImage(pdfBytes, imageBytes, x, y, everyPage);
PdfUtils.overlayImage(
pdfDocumentFactory, pdfBytes, imageBytes, x, y, everyPage);
return WebResponseUtils.bytesToWebResponse( return WebResponseUtils.bytesToWebResponse(
result, result,

View file

@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -12,7 +13,6 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts; import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -26,7 +26,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest; import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -37,13 +36,6 @@ public class PageNumbersController {
private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class); private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public PageNumbersController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data") @PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Add page numbers to a PDF document", summary = "Add page numbers to a PDF document",
@ -60,7 +52,7 @@ public class PageNumbersController {
String customText = request.getCustomText(); String customText = request.getCustomText();
int pageNumber = startingNumber; int pageNumber = startingNumber;
byte[] fileBytes = file.getBytes(); byte[] fileBytes = file.getBytes();
PDDocument document = pdfDocumentFactory.load(fileBytes); PDDocument document = Loader.loadPDF(fileBytes);
float font_size = request.getFontSize(); float font_size = request.getFontSize();
String font_type = request.getFontType(); String font_type = request.getFontType();
float marginFactor; float marginFactor;

View file

@ -8,7 +8,6 @@ import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -21,7 +20,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -33,13 +31,6 @@ public class RepairController {
private static final Logger logger = LoggerFactory.getLogger(RepairController.class); private static final Logger logger = LoggerFactory.getLogger(RepairController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public RepairController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/repair") @PostMapping(consumes = "multipart/form-data", value = "/repair")
@Operation( @Operation(
summary = "Repair a PDF file", summary = "Repair a PDF file",
@ -67,7 +58,7 @@ public class RepairController {
.runCommandWithOutputHandling(command); .runCommandWithOutputHandling(command);
// Read the optimized PDF file // Read the optimized PDF file
pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile()); pdfBytes = Files.readAllBytes(tempOutputFile);
// Return the optimized PDF as a response // Return the optimized PDF as a response
String outputFilename = String outputFilename =

View file

@ -12,6 +12,7 @@ import java.util.List;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -24,7 +25,6 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -38,7 +38,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.AddStampRequest; import stirling.software.SPDF.model.api.misc.AddStampRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -46,13 +45,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@Tag(name = "Misc", description = "Miscellaneous APIs") @Tag(name = "Misc", description = "Miscellaneous APIs")
public class StampController { public class StampController {
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public StampController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp") @PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
@Operation( @Operation(
summary = "Add stamp to a PDF file", summary = "Add stamp to a PDF file",
@ -94,7 +86,7 @@ public class StampController {
} }
// Load the input PDF // Load the input PDF
PDDocument document = pdfDocumentFactory.load(pdfFile); PDDocument document = Loader.loadPDF(pdfFile.getBytes());
List<Integer> pageNumbers = request.getPageNumbersList(document, true); List<Integer> pageNumbers = request.getPageNumbersList(document, true);

View file

@ -16,6 +16,7 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.util.Calendar; import java.util.Calendar;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.examples.signature.CreateSignatureBase; import org.apache.pdfbox.examples.signature.CreateSignatureBase;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
@ -34,7 +35,6 @@ import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException; import org.bouncycastle.pkcs.PKCSException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -47,7 +47,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest; import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -72,13 +71,6 @@ public class CertSignController {
} }
} }
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public CertSignController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign") @PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
@Operation( @Operation(
summary = "Sign PDF with a Digital Certificate", summary = "Sign PDF with a Digital Certificate",
@ -130,7 +122,7 @@ public class CertSignController {
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray()); CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, name, location, reason); sign(pdf.getBytes(), baos, createSignature, name, location, reason);
return WebResponseUtils.boasToWebResponse( return WebResponseUtils.boasToWebResponse(
baos, baos,
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "") Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
@ -138,14 +130,13 @@ public class CertSignController {
} }
private static void sign( private static void sign(
CustomPDDocumentFactory pdfDocumentFactory,
byte[] input, byte[] input,
OutputStream output, OutputStream output,
CreateSignature instance, CreateSignature instance,
String name, String name,
String location, String location,
String reason) { String reason) {
try (PDDocument doc = pdfDocumentFactory.load(input)) { try (PDDocument doc = Loader.loadPDF(input)) {
PDSignature signature = new PDSignature(); PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);

View file

@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api.security;
import java.io.IOException; import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission; import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy; import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -21,7 +21,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.security.AddPasswordRequest; import stirling.software.SPDF.model.api.security.AddPasswordRequest;
import stirling.software.SPDF.model.api.security.PDFPasswordRequest; import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -31,13 +30,6 @@ public class PasswordController {
private static final Logger logger = LoggerFactory.getLogger(PasswordController.class); private static final Logger logger = LoggerFactory.getLogger(PasswordController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public PasswordController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/remove-password") @PostMapping(consumes = "multipart/form-data", value = "/remove-password")
@Operation( @Operation(
summary = "Remove password from a PDF file", summary = "Remove password from a PDF file",
@ -47,7 +39,8 @@ public class PasswordController {
throws IOException { throws IOException {
MultipartFile fileInput = request.getFileInput(); MultipartFile fileInput = request.getFileInput();
String password = request.getPassword(); String password = request.getPassword();
PDDocument document = pdfDocumentFactory.load(fileInput, password);
PDDocument document = Loader.loadPDF(fileInput.getBytes(), password);
document.setAllSecurityToBeRemoved(true); document.setAllSecurityToBeRemoved(true);
return WebResponseUtils.pdfDocToWebResponse( return WebResponseUtils.pdfDocToWebResponse(
document, document,
@ -76,7 +69,7 @@ public class PasswordController {
boolean canPrint = request.isCanPrint(); boolean canPrint = request.isCanPrint();
boolean canPrintFaithful = request.isCanPrintFaithful(); boolean canPrintFaithful = request.isCanPrintFaithful();
PDDocument document = pdfDocumentFactory.load(fileInput); PDDocument document = Loader.loadPDF(fileInput.getBytes());
AccessPermission ap = new AccessPermission(); AccessPermission ap = new AccessPermission();
ap.setCanAssembleDocument(!canAssembleDocument); ap.setCanAssembleDocument(!canAssembleDocument);
ap.setCanExtractContent(!canExtractContent); ap.setCanExtractContent(!canExtractContent);

View file

@ -5,12 +5,12 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.PDFText; import stirling.software.SPDF.model.PDFText;
import stirling.software.SPDF.model.api.security.RedactPdfRequest; import stirling.software.SPDF.model.api.security.RedactPdfRequest;
import stirling.software.SPDF.pdf.TextFinder; import stirling.software.SPDF.pdf.TextFinder;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -36,13 +35,6 @@ public class RedactController {
private static final Logger logger = LoggerFactory.getLogger(RedactController.class); private static final Logger logger = LoggerFactory.getLogger(RedactController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public RedactController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(value = "/auto-redact", consumes = "multipart/form-data") @PostMapping(value = "/auto-redact", consumes = "multipart/form-data")
@Operation( @Operation(
summary = "Redacts listOfText in a PDF document", summary = "Redacts listOfText in a PDF document",
@ -60,7 +52,8 @@ public class RedactController {
System.out.println(listOfTextString); System.out.println(listOfTextString);
String[] listOfText = listOfTextString.split("\n"); String[] listOfText = listOfTextString.split("\n");
PDDocument document = pdfDocumentFactory.load(file); byte[] bytes = file.getBytes();
PDDocument document = Loader.loadPDF(bytes);
Color redactColor; Color redactColor;
try { try {

View file

@ -1,8 +1,10 @@
package stirling.software.SPDF.controller.api.security; package stirling.software.SPDF.controller.api.security;
import java.io.ByteArrayOutputStream;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
@ -10,7 +12,6 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; 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.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -23,7 +24,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -33,13 +33,6 @@ public class RemoveCertSignController {
private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class); private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class);
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public RemoveCertSignController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign") @PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
@Operation( @Operation(
summary = "Remove digital signature from PDF", summary = "Remove digital signature from PDF",
@ -49,8 +42,14 @@ public class RemoveCertSignController {
throws Exception { throws Exception {
MultipartFile pdf = request.getFileInput(); MultipartFile pdf = request.getFileInput();
// Convert MultipartFile to byte[]
byte[] pdfBytes = pdf.getBytes();
// Create a ByteArrayOutputStream to hold the resulting PDF
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Load the PDF document // Load the PDF document
PDDocument document = pdfDocumentFactory.load(pdf); PDDocument document = Loader.loadPDF(pdfBytes);
// Get the document catalog // Get the document catalog
PDDocumentCatalog catalog = document.getDocumentCatalog(); PDDocumentCatalog catalog = document.getDocumentCatalog();
@ -68,9 +67,14 @@ public class RemoveCertSignController {
acroForm.flatten(fieldsToRemove, false); acroForm.flatten(fieldsToRemove, false);
} }
} }
// Save the modified document to the ByteArrayOutputStream
document.save(baos);
document.close();
// Return the modified PDF as a response // Return the modified PDF as a response
return WebResponseUtils.pdfDocToWebResponse( return WebResponseUtils.boasToWebResponse(
document, baos,
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "") Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
+ "_unsigned.pdf"); + "_unsigned.pdf");
} }

View file

@ -2,6 +2,7 @@ package stirling.software.SPDF.controller.api.security;
import java.io.IOException; import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
@ -20,7 +21,6 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField; import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -33,7 +33,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.security.SanitizePdfRequest; import stirling.software.SPDF.model.api.security.SanitizePdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -41,13 +40,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@Tag(name = "Security", description = "Security APIs") @Tag(name = "Security", description = "Security APIs")
public class SanitizeController { public class SanitizeController {
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public SanitizeController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf") @PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf")
@Operation( @Operation(
summary = "Sanitize a PDF file", summary = "Sanitize a PDF file",
@ -62,7 +54,7 @@ public class SanitizeController {
boolean removeLinks = request.isRemoveLinks(); boolean removeLinks = request.isRemoveLinks();
boolean removeFonts = request.isRemoveFonts(); boolean removeFonts = request.isRemoveFonts();
PDDocument document = pdfDocumentFactory.load(inputFile); PDDocument document = Loader.loadPDF(inputFile.getBytes());
if (removeJavaScript) { if (removeJavaScript) {
sanitizeJavaScript(document); sanitizeJavaScript(document);
} }

View file

@ -11,6 +11,7 @@ import java.nio.file.Files;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -22,7 +23,6 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -36,7 +36,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.security.AddWatermarkRequest; import stirling.software.SPDF.model.api.security.AddWatermarkRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@ -45,13 +44,6 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@Tag(name = "Security", description = "Security APIs") @Tag(name = "Security", description = "Security APIs")
public class WatermarkController { public class WatermarkController {
private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public WatermarkController(CustomPDDocumentFactory pdfDocumentFactory) {
this.pdfDocumentFactory = pdfDocumentFactory;
}
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark") @PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
@Operation( @Operation(
summary = "Add watermark to a PDF file", summary = "Add watermark to a PDF file",
@ -72,7 +64,7 @@ public class WatermarkController {
boolean convertPdfToImage = request.isConvertPDFToImage(); boolean convertPdfToImage = request.isConvertPDFToImage();
// Load the input PDF // Load the input PDF
PDDocument document = pdfDocumentFactory.load(pdfFile); PDDocument document = Loader.loadPDF(pdfFile.getBytes());
// Create a page in the document // Create a page in the document
for (PDPage page : document.getPages()) { for (PDPage page : document.getPages()) {

View file

@ -1,100 +0,0 @@
package stirling.software.SPDF.service;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import stirling.software.SPDF.config.PdfMetadataService;
import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.PDFFile;
@Component
public class CustomPDDocumentFactory {
private final PdfMetadataService pdfMetadataService;
@Autowired
public CustomPDDocumentFactory(PdfMetadataService pdfMetadataService) {
this.pdfMetadataService = pdfMetadataService;
}
public PDDocument createNewDocument() throws IOException {
PDDocument document = new PDDocument();
pdfMetadataService.setMetadataToPdf(document, PdfMetadata.builder().build(), true);
return document;
}
public PDDocument createNewDocumentBasedOnOldDocument(PDDocument oldDocument)
throws IOException {
PDDocument document = new PDDocument();
pdfMetadataService.setMetadataToPdf(
document, pdfMetadataService.extractMetadataFromPdf(oldDocument), true);
return document;
}
public byte[] loadToBytes(File file) throws IOException {
PDDocument document = load(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
// Close the document
document.close();
return baos.toByteArray();
}
public byte[] loadToBytes(byte[] bytes) throws IOException {
PDDocument document = load(bytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
// Close the document
document.close();
return baos.toByteArray();
}
// if loading from a file, assume the file has been made with Stirling-PDF
public PDDocument load(File file) throws IOException {
PDDocument document = Loader.loadPDF(file);
pdfMetadataService.setMetadataToPdf(document, PdfMetadata.builder().build(), true);
return document;
}
public PDDocument load(InputStream input) throws IOException {
return load(input.readAllBytes());
}
public PDDocument load(byte[] input) throws IOException {
PDDocument document = Loader.loadPDF(input);
pdfMetadataService.setDefaultMetadata(document);
return document;
}
public PDDocument load(PDFFile pdfFile) throws IOException {
return load(pdfFile.getFileInput());
}
public PDDocument load(MultipartFile pdfFile) throws IOException {
return load(pdfFile.getBytes());
}
public PDDocument load(String path) throws IOException {
return load(new File(path));
}
public PDDocument load(MultipartFile fileInput, String password) throws IOException {
return load(fileInput.getBytes(), password);
}
private PDDocument load(byte[] bytes, String password) throws IOException {
PDDocument document = Loader.loadPDF(bytes, password);
pdfMetadataService.setDefaultMetadata(document);
return document;
}
// Add other load methods as needed, following the same pattern
}

View file

@ -36,8 +36,6 @@ import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
public class PdfUtils { public class PdfUtils {
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class); private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
@ -382,13 +380,9 @@ public class PdfUtils {
} }
public static byte[] imageToPdf( public static byte[] imageToPdf(
MultipartFile[] files, MultipartFile[] files, String fitOption, boolean autoRotate, String colorType)
String fitOption,
boolean autoRotate,
String colorType,
CustomPDDocumentFactory pdfDocumentFactory)
throws IOException { throws IOException {
try (PDDocument doc = pdfDocumentFactory.createNewDocument()) { try (PDDocument doc = new PDDocument()) {
for (MultipartFile file : files) { for (MultipartFile file : files) {
String contentType = file.getContentType(); String contentType = file.getContentType();
String originalFilename = Filenames.toSimpleFileName(file.getOriginalFilename()); String originalFilename = Filenames.toSimpleFileName(file.getOriginalFilename());
@ -476,15 +470,10 @@ public class PdfUtils {
} }
public static byte[] overlayImage( public static byte[] overlayImage(
CustomPDDocumentFactory pdfDocumentFactory, byte[] pdfBytes, byte[] imageBytes, float x, float y, boolean everyPage)
byte[] pdfBytes,
byte[] imageBytes,
float x,
float y,
boolean everyPage)
throws IOException { throws IOException {
PDDocument document = pdfDocumentFactory.load(pdfBytes); PDDocument document = Loader.loadPDF(pdfBytes);
// Get the first page of the PDF // Get the first page of the PDF
int pages = document.getNumberOfPages(); int pages = document.getNumberOfPages();

View file

@ -77,10 +77,10 @@ color=Colore
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
legal.privacy=Informativa sulla privacy legal.privacy=Privacy Policy
legal.terms=Termini e Condizioni legal.terms=Terms and Conditions
legal.accessibility=Accessibilità legal.accessibility=Accessibility
legal.cookie=Informativa sui cookie legal.cookie=Cookie Policy
legal.impressum=Impressum legal.impressum=Impressum
############### ###############

View file

@ -75,7 +75,6 @@
<script th:src="@{'/js/cacheFormInputs.js'}" th:if="${currentPage != 'home'}"></script> <script th:src="@{'/js/cacheFormInputs.js'}" th:if="${currentPage != 'home'}"></script>
<script th:src="@{'/js/tab-container.js'}"></script> <script th:src="@{'/js/tab-container.js'}"></script>
<script th:src="@{'/js/darkmode.js'}"></script> <script th:src="@{'/js/darkmode.js'}"></script>
<script defer data-domain="pdf.dgnum.eu" src="https://analytics.dgnum.eu/js/script.js"></script>
</th:block> </th:block>
<th:block th:fragment="game"> <th:block th:fragment="game">

View file

@ -1,13 +1,22 @@
<footer th:fragment="footer" id="footer" class="text-center py-5"> <footer th:fragment="footer" id="footer" class="text-center pt-5">
<div class="footer-center"> <div class="footer-center pb-4">
<div class="footer-powered-by"> <!-- Links section -->
<span>Application proposée par la&nbsp;<b><a href="https://dgnum.eu">DGNum</a></b>.</span> <div class="d-flex justify-content-center">
<ul class="list-unstyled d-flex">
<li><a class="footer-link px-2" id="licenses" target="_blank" th:href="@{'/licenses'}" th:text="#{licenses.nav}">Licenses</a></li>
<li><a class="footer-link px-2" id="survey" target="_blank" href="https://stirlingpdf.info/s/clwzgtfw7000gltkmwz1n212m" th:text="#{survey.nav}">Survey</a></li>
<li th:if="${@privacyPolicy != ''}"><a class="footer-link px-2" target="_blank" th:href="${@privacyPolicy}" th:text="#{legal.privacy}">privacyPolicy</a></li>
<li th:if="${@termsAndConditions != ''}"><a class="footer-link px-2" target="_blank" th:href="${@termsAndConditions}" th:text="#{legal.terms}">termsAndConditions</a></li>
<li th:if="${@accessibilityStatement != ''}"><a class="footer-link px-2" target="_blank" th:href="${@accessibilityStatement}" th:text="#{legal.accessibility}">accessibilityStatement</a></li>
<li th:if="${@cookiePolicy != ''}"><a class="footer-link px-2" target="_blank" th:href="${@cookiePolicy}" th:text="#{legal.cookie}">cookiePolicy</a></li>
<li th:if="${@impressum != ''}"><a class="footer-link px-2" target="_blank" th:href="${@impressum}" th:text="#{legal.impressum}">impressum</a></li>
</ul>
</div>
<!-- powered by section -->
<div class="footer-powered-by">
<span th:text="#{poweredBy}"></span>
<a href="https://stirlingpdf.com" class="stirling-link">Stirling PDF</a>
</div> </div>
<a href="licenses" id="licenses" target="_blank" class="mx-1" title="" th:text="#{licenses.nav}">Licenses</a>
<a th:if="${@privacyPolicy != ''}" class="footer-link px-2" target="_blank" th:href="${@privacyPolicy}" th:text="#{legal.privacy}">privacyPolicy</a>
<a th:if="${@termsAndConditions != ''}" class="footer-link px-2" target="_blank" th:href="${@termsAndConditions}" th:text="#{legal.terms}">termsAndConditions</a>
<a th:if="${@accessibilityStatement != ''}" class="footer-link px-2" target="_blank" th:href="${@accessibilityStatement}" th:text="#{legal.accessibility}">accessibilityStatement</a>
<a th:if="${@cookiePolicy != ''}" class="footer-link px-2" target="_blank" th:href="${@cookiePolicy}" th:text="#{legal.cookie}">cookiePolicy</a>
<a th:if="${@impressum != ''}" class="footer-link px-2" target="_blank" th:href="${@impressum}" th:text="#{legal.impressum}">impressum</a>
</div> </div>
</footer> </footer>

View file

@ -21,9 +21,7 @@
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-12 bg-card"> <div class="col-md-12 bg-card">
<form>
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-3"> <div class="col-md-3">
<div id="sliders-container" style="display:none;"> <div id="sliders-container" style="display:none;">
<h4><span th:text="#{adjustContrast.contrast}"></span> <span id="contrast-val">100</span>%</h4> <h4><span th:text="#{adjustContrast.contrast}"></span> <span id="contrast-val">100</span>%</h4>
@ -46,14 +44,10 @@
</div> </div>
<br> <br>
<canvas id="contrast-pdf-canvas"></canvas> <canvas id="contrast-pdf-canvas"></canvas>
<div class="mb-3 text-left">
<button id="download-button" class="btn btn-primary" th:text="#{adjustContrast.download}"></button> <button id="download-button" class="btn btn-primary" th:text="#{adjustContrast.download}"></button>
</div> </div>
</div> </div>
</div>
</form>
<script> <script>
var canvas = document.getElementById('contrast-pdf-canvas'); var canvas = document.getElementById('contrast-pdf-canvas');
var context = canvas.getContext('2d'); var context = canvas.getContext('2d');
@ -223,7 +217,7 @@
function adjustBrightnessForPixel(pixel, brightness) { function adjustBrightnessForPixel(pixel, brightness) {
return Math.max(0, Math.min(255, pixel * brightness)); return Math.max(0, Math.min(255, pixel * brightness));
} }
let inputFileName = '';
async function downloadPDF() { async function downloadPDF() {
for (var i = 0; i < allPages.length; i++) { for (var i = 0; i < allPages.length; i++) {
await renderPageAndAdjustImageProperties(allPages[i]); await renderPageAndAdjustImageProperties(allPages[i]);
@ -252,10 +246,7 @@
// Create download link // Create download link
const downloadLink = document.createElement('a'); const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob); downloadLink.href = URL.createObjectURL(blob);
let newFileName = inputFileName ? inputFileName.replace('.pdf', '') : 'download'; downloadLink.download = "download.pdf";
newFileName += '_adjusted_color.pdf';
downloadLink.download = newFileName;
downloadLink.click(); downloadLink.click();
// After download, reset the viewer and clear stored data // After download, reset the viewer and clear stored data
@ -271,7 +262,6 @@
// Event listeners // Event listeners
document.getElementById('fileInput-input').addEventListener('change', function(e) { document.getElementById('fileInput-input').addEventListener('change', function(e) {
if (e.target.files.length > 0) { if (e.target.files.length > 0) {
inputFileName = e.target.files[0].name;
renderPDFAndSaveOriginalImageData(e.target.files[0]); renderPDFAndSaveOriginalImageData(e.target.files[0]);
} }
}); });

View file

@ -172,23 +172,16 @@
}); });
function toggleFileOption() { function toggleFileOption() {
const stampImage = document.getElementById('stampImage');
const stampType = document.getElementById('stampType').value; const stampType = document.getElementById('stampType').value;
const stampTextGroup = document.getElementById('stampTextGroup'); const stampTextGroup = document.getElementById('stampTextGroup');
const stampImageGroup = document.getElementById('stampImageGroup'); const stampImageGroup = document.getElementById('stampImageGroup');
const alphabetGroup = document.getElementById('alphabetGroup'); const alphabetGroup = document.getElementById('alphabetGroup');
if (stampType === 'text') { if (stampType === 'text') {
if (stampImage.hasAttribute('required')) {
stampImage.removeAttribute('required');
}
stampTextGroup.style.display = 'block'; stampTextGroup.style.display = 'block';
stampImageGroup.style.display = 'none'; stampImageGroup.style.display = 'none';
alphabetGroup.style.display = 'block'; alphabetGroup.style.display = 'block';
} else if (stampType === 'image') { } else if (stampType === 'image') {
if (!stampImage.hasAttribute('required')) {
stampImage.setAttribute('required', '');
}
stampTextGroup.style.display = 'none'; stampTextGroup.style.display = 'none';
stampImageGroup.style.display = 'block'; stampImageGroup.style.display = 'block';
alphabetGroup.style.display = 'none'; alphabetGroup.style.display = 'none';

View file

@ -67,7 +67,7 @@
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=true)}" th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=true)}"
></div> ></div>
</div> </div>
<div class="element-margin text-start"> <div class="element-margin">
<button <button
class="btn btn-primary" class="btn btn-primary"
id="submitConfigBtn" id="submitConfigBtn"

View file

@ -74,7 +74,7 @@
</div> </div>
</div> </div>
<br> <br>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{addPassword.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
</div> </div>
</form> </form>

View file

@ -108,7 +108,7 @@
<input type="checkbox" id="convertPDFToImage" name="convertPDFToImage"> <input type="checkbox" id="convertPDFToImage" name="convertPDFToImage">
<label for="convertPDFToImage" th:text="#{watermark.selectText.10}"></label> <label for="convertPDFToImage" th:text="#{watermark.selectText.10}"></label>
</div> </div>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<input type="submit" id="submitBtn" th:value="#{watermark.submit}" class="btn btn-primary"> <input type="submit" id="submitBtn" th:value="#{watermark.submit}" class="btn btn-primary">
</div> </div>
</form> </form>
@ -123,18 +123,12 @@
const watermarkImage = document.getElementById('watermarkImage'); const watermarkImage = document.getElementById('watermarkImage');
if (watermarkType === 'text') { if (watermarkType === 'text') {
if (watermarkImage.hasAttribute('required')) {
watermarkImage.removeAttribute('required');
}
watermarkTextGroup.style.display = 'block'; watermarkTextGroup.style.display = 'block';
watermarkText.required = true; watermarkText.required = true;
watermarkImageGroup.style.display = 'none'; watermarkImageGroup.style.display = 'none';
watermarkImage.required = false; watermarkImage.required = false;
alphabetGroup.style.display = 'block'; alphabetGroup.style.display = 'block';
} else if (watermarkType === 'image') { } else if (watermarkType === 'image') {
if (watermarkImage.hasAttribute('required')) {
watermarkImage.removeAttribute('required');
}
watermarkTextGroup.style.display = 'none'; watermarkTextGroup.style.display = 'none';
watermarkText.required = false; watermarkText.required = false;
watermarkImageGroup.style.display = 'block'; watermarkImageGroup.style.display = 'block';

View file

@ -74,7 +74,7 @@
<label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1" disabled> <label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1" disabled>
</div> </div>
</div> </div>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{certSign.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{certSign.submit}"></button>
</div> </div>
</form> </form>

View file

@ -58,7 +58,7 @@
</div> </div>
</div> </div>
<br> <br>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{permissions.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{permissions.submit}"></button>
</div> </div>
</form> </form>

View file

@ -21,7 +21,7 @@
<label th:text="#{removeCertSign.selectPDF}"></label> <label th:text="#{removeCertSign.selectPDF}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div> <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
</div> </div>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeCertSign.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeCertSign.submit}"></button>
</div> </div>
</form> </form>

View file

@ -26,7 +26,7 @@
<input type="password" class="form-control" id="password" name="password"> <input type="password" class="form-control" id="password" name="password">
</div> </div>
<br> <br>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removePassword.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
</div> </div>
</form> </form>

View file

@ -41,7 +41,7 @@
<label for="removeFonts" th:text="#{sanitizePDF.selectText.5}"></label> <label for="removeFonts" th:text="#{sanitizePDF.selectText.5}"></label>
</div> </div>
<br> <br>
<div class="mb-3 text-left"> <div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{sanitizePDF.submit}"></button> <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{sanitizePDF.submit}"></button>
</div> </div>
</form> </form>

View file

@ -8,33 +8,15 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;import org.junit.jupiter.api.BeforeEach;
class RearrangePagesPDFControllerTest { class RearrangePagesPDFControllerTest {
@Mock
private CustomPDDocumentFactory mockPdfDocumentFactory;
private RearrangePagesPDFController sut;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
sut = new RearrangePagesPDFController(mockPdfDocumentFactory);
}
/** /**
* Tests the behavior of the oddEvenMerge method when there are no pages in the document. * Tests the behavior of the oddEvenMerge method when there are no pages in the document.
*/ */
@Test @Test
void oddEvenMerge_noPages() { void oddEvenMerge_noPages() {
RearrangePagesPDFController sut = new RearrangePagesPDFController();
int totalNumberOfPages = 0; int totalNumberOfPages = 0;
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages); List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
@ -48,6 +30,7 @@ class RearrangePagesPDFControllerTest {
*/ */
@Test @Test
void oddEvenMerge_oddTotalPageNumber() { void oddEvenMerge_oddTotalPageNumber() {
RearrangePagesPDFController sut = new RearrangePagesPDFController();
int totalNumberOfPages = 5; int totalNumberOfPages = 5;
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages); List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
@ -61,6 +44,7 @@ class RearrangePagesPDFControllerTest {
*/ */
@Test @Test
void oddEvenMerge_evenTotalPageNumber() { void oddEvenMerge_evenTotalPageNumber() {
RearrangePagesPDFController sut = new RearrangePagesPDFController();
int totalNumberOfPages = 6; int totalNumberOfPages = 6;
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages); List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
@ -88,6 +72,8 @@ class RearrangePagesPDFControllerTest {
"22,47,23,48,24,49'" "22,47,23,48,24,49'"
}) })
void oddEvenMerge_multi_test(int totalNumberOfPages, String expectedPageOrder) { void oddEvenMerge_multi_test(int totalNumberOfPages, String expectedPageOrder) {
RearrangePagesPDFController sut = new RearrangePagesPDFController();
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages); List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
assertNotNull(newPageOrder, "Returning null instead of page order list"); assertNotNull(newPageOrder, "Returning null instead of page order list");

View file

@ -1,36 +1,18 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import stirling.software.SPDF.controller.api.RearrangePagesPDFController;
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest; import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class ConvertWebsiteToPdfTest { public class ConvertWebsiteToPdfTest {
@Mock
private CustomPDDocumentFactory mockPdfDocumentFactory;
private ConvertWebsiteToPDF convertWebsiteToPDF;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
convertWebsiteToPDF = new ConvertWebsiteToPDF(mockPdfDocumentFactory);
}
@Test @Test
public void test_exemption_is_thrown_when_invalid_url_format_provided() { public void test_exemption_is_thrown_when_invalid_url_format_provided() {
String invalid_format_Url = "invalid-url"; String invalid_format_Url = "invalid-url";
// Arrange
ConvertWebsiteToPDF convertWebsiteToPDF = new ConvertWebsiteToPDF();
UrlToPdfRequest request = new UrlToPdfRequest(); UrlToPdfRequest request = new UrlToPdfRequest();
request.setUrlInput(invalid_format_Url); request.setUrlInput(invalid_format_Url);
// Act // Act
@ -46,6 +28,7 @@ public class ConvertWebsiteToPdfTest {
String unreachable_Url = "https://www.googleeeexyz.com"; String unreachable_Url = "https://www.googleeeexyz.com";
// Arrange // Arrange
ConvertWebsiteToPDF convertWebsiteToPDF = new ConvertWebsiteToPDF();
UrlToPdfRequest request = new UrlToPdfRequest(); UrlToPdfRequest request = new UrlToPdfRequest();
request.setUrlInput(unreachable_Url); request.setUrlInput(unreachable_Url);
// Act // Act