Compare commits
10 commits
8c01425eee
...
71d673b4eb
Author | SHA1 | Date | |
---|---|---|---|
|
71d673b4eb | ||
|
d389b5e2f3 | ||
|
de97492f39 | ||
|
9661e94092 | ||
|
2cfb553320 | ||
|
909a3347a0 | ||
|
de4144a1a4 | ||
|
bb1c859e0d | ||
|
b2862a3fc4 | ||
|
8788a7ee34 |
58 changed files with 764 additions and 337 deletions
38
README.md
38
README.md
|
@ -174,35 +174,35 @@ Stirling PDF currently supports 38!
|
|||
| ------------------------------------------- | -------------------------------------- |
|
||||
| Arabic (العربية) (ar_AR) | ![99%](https://geps.dev/progress/99) |
|
||||
| Basque (Euskara) (eu_ES) | ![60%](https://geps.dev/progress/60) |
|
||||
| Bulgarian (Български) (bg_BG) | ![92%](https://geps.dev/progress/92) |
|
||||
| Bulgarian (Български) (bg_BG) | ![91%](https://geps.dev/progress/91) |
|
||||
| Catalan (Català) (ca_CA) | ![47%](https://geps.dev/progress/47) |
|
||||
| Croatian (Hrvatski) (hr_HR) | ![92%](https://geps.dev/progress/92) |
|
||||
| Czech (Česky) (cs_CZ) | ![88%](https://geps.dev/progress/88) |
|
||||
| Danish (Dansk) (da_DK) | ![97%](https://geps.dev/progress/97) |
|
||||
| Croatian (Hrvatski) (hr_HR) | ![91%](https://geps.dev/progress/91) |
|
||||
| Czech (Česky) (cs_CZ) | ![87%](https://geps.dev/progress/87) |
|
||||
| Danish (Dansk) (da_DK) | ![96%](https://geps.dev/progress/96) |
|
||||
| Dutch (Nederlands) (nl_NL) | ![93%](https://geps.dev/progress/93) |
|
||||
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
|
||||
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
|
||||
| French (Français) (fr_FR) | ![91%](https://geps.dev/progress/91) |
|
||||
| German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
|
||||
| Greek (Ελληνικά) (el_GR) | ![80%](https://geps.dev/progress/80) |
|
||||
| French (Français) (fr_FR) | ![90%](https://geps.dev/progress/90) |
|
||||
| German (Deutsch) (de_DE) | ![98%](https://geps.dev/progress/98) |
|
||||
| Greek (Ελληνικά) (el_GR) | ![79%](https://geps.dev/progress/79) |
|
||||
| Hindi (हिंदी) (hi_IN) | ![76%](https://geps.dev/progress/76) |
|
||||
| Hungarian (Magyar) (hu_HU) | ![74%](https://geps.dev/progress/74) |
|
||||
| Hungarian (Magyar) (hu_HU) | ![73%](https://geps.dev/progress/73) |
|
||||
| Indonesia (Bahasa Indonesia) (id_ID) | ![74%](https://geps.dev/progress/74) |
|
||||
| Irish (Gaeilge) (ga_IE) | ![96%](https://geps.dev/progress/96) |
|
||||
| Irish (Gaeilge) (ga_IE) | ![95%](https://geps.dev/progress/95) |
|
||||
| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) |
|
||||
| Japanese (日本語) (ja_JP) | ![90%](https://geps.dev/progress/90) |
|
||||
| Korean (한국어) (ko_KR) | ![82%](https://geps.dev/progress/82) |
|
||||
| Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) |
|
||||
| Korean (한국어) (ko_KR) | ![81%](https://geps.dev/progress/81) |
|
||||
| Norwegian (Norsk) (no_NB) | ![95%](https://geps.dev/progress/95) |
|
||||
| Polish (Polski) (pl_PL) | ![90%](https://geps.dev/progress/90) |
|
||||
| Polish (Polski) (pl_PL) | ![89%](https://geps.dev/progress/89) |
|
||||
| Portuguese (Português) (pt_PT) | ![76%](https://geps.dev/progress/76) |
|
||||
| Portuguese Brazilian (Português) (pt_BR) | ![99%](https://geps.dev/progress/99) |
|
||||
| Romanian (Română) (ro_RO) | ![98%](https://geps.dev/progress/98) |
|
||||
| Russian (Русский) (ru_RU) | ![82%](https://geps.dev/progress/82) |
|
||||
| Portuguese Brazilian (Português) (pt_BR) | ![98%](https://geps.dev/progress/98) |
|
||||
| Romanian (Română) (ro_RO) | ![97%](https://geps.dev/progress/97) |
|
||||
| Russian (Русский) (ru_RU) | ![81%](https://geps.dev/progress/81) |
|
||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![76%](https://geps.dev/progress/76) |
|
||||
| Simplified Chinese (简体中文) (zh_CN) | ![99%](https://geps.dev/progress/99) |
|
||||
| Slovakian (Slovensky) (sk_SK) | ![90%](https://geps.dev/progress/90) |
|
||||
| Spanish (Español) (es_ES) | ![99%](https://geps.dev/progress/99) |
|
||||
| Swedish (Svenska) (sv_SE) | ![98%](https://geps.dev/progress/98) |
|
||||
| Simplified Chinese (简体中文) (zh_CN) | ![98%](https://geps.dev/progress/98) |
|
||||
| Slovakian (Slovensky) (sk_SK) | ![89%](https://geps.dev/progress/89) |
|
||||
| Spanish (Español) (es_ES) | ![98%](https://geps.dev/progress/98) |
|
||||
| Swedish (Svenska) (sv_SE) | ![97%](https://geps.dev/progress/97) |
|
||||
| Thai (ไทย) (th_TH) | ![96%](https://geps.dev/progress/96) |
|
||||
| Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) |
|
||||
| Turkish (Türkçe) (tr_TR) | ![96%](https://geps.dev/progress/96) |
|
||||
|
|
|
@ -22,7 +22,7 @@ ext {
|
|||
}
|
||||
|
||||
group = "stirling.software"
|
||||
version = "0.28.3"
|
||||
version = "0.29.0"
|
||||
|
||||
java {
|
||||
// 17 is lowest but we support and recommend 21
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
apiVersion: v2
|
||||
appVersion: 0.28.3
|
||||
appVersion: 0.29.0
|
||||
description: locally hosted web application that allows you to perform various operations
|
||||
on PDF files
|
||||
home: https://github.com/Stirling-Tools/Stirling-PDF
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.PdfMetadata;
|
||||
|
@ -15,8 +14,6 @@ import stirling.software.SPDF.model.PdfMetadata;
|
|||
@Service
|
||||
public class PdfMetadataService {
|
||||
|
||||
private static PdfMetadataService instance;
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final String appVersion;
|
||||
private final UserServiceInterface userService;
|
||||
|
@ -31,33 +28,7 @@ public class PdfMetadataService {
|
|||
this.userService = userService;
|
||||
}
|
||||
|
||||
@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) {
|
||||
public PdfMetadata extractMetadataFromPdf(PDDocument pdf) {
|
||||
return PdfMetadata.builder()
|
||||
.author(pdf.getDocumentInformation().getAuthor())
|
||||
.producer(pdf.getDocumentInformation().getProducer())
|
||||
|
@ -70,17 +41,16 @@ public class PdfMetadataService {
|
|||
.build();
|
||||
}
|
||||
|
||||
private void setDefaultMetadataInstance(PDDocument pdf) {
|
||||
PdfMetadata metadata = extractMetadataFromPdfInstance(pdf);
|
||||
setMetadataToPdfInstance(pdf, metadata);
|
||||
public void setDefaultMetadata(PDDocument pdf) {
|
||||
PdfMetadata metadata = extractMetadataFromPdf(pdf);
|
||||
setMetadataToPdf(pdf, metadata);
|
||||
}
|
||||
|
||||
private void setMetadataToPdfInstance(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||
setMetadataToPdfInstance(pdf, pdfMetadata, true);
|
||||
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||
setMetadataToPdf(pdf, pdfMetadata, false);
|
||||
}
|
||||
|
||||
private void setMetadataToPdfInstance(
|
||||
PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) {
|
||||
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) {
|
||||
if (newlyCreated || pdfMetadata.getCreationDate() == null) {
|
||||
setNewDocumentMetadata(pdf, pdfMetadata);
|
||||
}
|
||||
|
@ -89,35 +59,35 @@ public class PdfMetadataService {
|
|||
|
||||
private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||
|
||||
String title = pdfMetadata.getTitle();
|
||||
String creator = "Stirling-PDF";
|
||||
|
||||
// if (applicationProperties
|
||||
// .getEnterpriseEdition()
|
||||
// .getCustomMetadata()
|
||||
// .isAutoUpdateMetadata()) {
|
||||
// if (applicationProperties
|
||||
// .getEnterpriseEdition()
|
||||
// .getCustomMetadata()
|
||||
// .isAutoUpdateMetadata()) {
|
||||
|
||||
// producer =
|
||||
//
|
||||
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getProducer();
|
||||
// creator =
|
||||
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator();
|
||||
// title = applicationProperties.getEnterpriseEdition().getCustomMetadata().getTitle();
|
||||
// producer =
|
||||
//
|
||||
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getProducer();
|
||||
// creator =
|
||||
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator();
|
||||
// title = applicationProperties.getEnterpriseEdition().getCustomMetadata().getTitle();
|
||||
|
||||
// if ("{filename}".equals(title)) {
|
||||
// title = "Filename"; // Replace with actual filename logic
|
||||
// } else if ("{unchanged}".equals(title)) {
|
||||
// title = pdfMetadata.getTitle(); // Keep the original title
|
||||
// }
|
||||
// }
|
||||
// if ("{filename}".equals(title)) {
|
||||
// title = "Filename"; // Replace with actual filename logic
|
||||
// } else if ("{unchanged}".equals(title)) {
|
||||
// title = pdfMetadata.getTitle(); // Keep the original title
|
||||
// }
|
||||
// }
|
||||
|
||||
pdf.getDocumentInformation().setTitle(title);
|
||||
pdf.getDocumentInformation().setCreator(creator + " " + appVersion);
|
||||
pdf.getDocumentInformation().setCreationDate(Calendar.getInstance());
|
||||
}
|
||||
|
||||
private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||
String producer = "Stirling-PDF";
|
||||
String title = pdfMetadata.getTitle();
|
||||
pdf.getDocumentInformation().setTitle(title);
|
||||
pdf.getDocumentInformation().setProducer(producer + " " + appVersion);
|
||||
pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject());
|
||||
pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords());
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -23,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -32,6 +34,13 @@ public class CropController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Crops a PDF document",
|
||||
|
@ -40,7 +49,8 @@ public class CropController {
|
|||
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException {
|
||||
PDDocument sourceDocument = Loader.loadPDF(form.getFileInput().getBytes());
|
||||
|
||||
PDDocument newDocument = new PDDocument();
|
||||
PDDocument newDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
|
||||
int totalPages = sourceDocument.getNumberOfPages();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -33,6 +34,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -43,9 +45,16 @@ public class MergeController {
|
|||
|
||||
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
|
||||
public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
||||
PDDocument mergedDoc = new PDDocument();
|
||||
PDDocument mergedDoc = pdfDocumentFactory.createNewDocument();
|
||||
for (PDDocument doc : documents) {
|
||||
for (PDPage page : doc.getPages()) {
|
||||
mergedDoc.addPage(page);
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -26,6 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -35,6 +37,13 @@ public class MultiPageLayoutController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Merge multiple pages of a PDF document into a single page",
|
||||
|
@ -60,7 +69,8 @@ public class MultiPageLayoutController {
|
|||
int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet);
|
||||
|
||||
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
||||
PDDocument newDocument = new PDDocument();
|
||||
PDDocument newDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
PDPage newPage = new PDPage(PDRectangle.A4);
|
||||
newDocument.addPage(newPage);
|
||||
|
||||
|
|
|
@ -3,16 +3,15 @@ package stirling.software.SPDF.controller.api;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.service.PdfImageRemovalService;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
|
@ -25,15 +24,21 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
public class PdfImageRemovalController {
|
||||
|
||||
// Service for removing images from PDFs
|
||||
@Autowired private PdfImageRemovalService pdfImageRemovalService;
|
||||
private final PdfImageRemovalService pdfImageRemovalService;
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
/**
|
||||
* Constructor for dependency injection of PdfImageRemovalService.
|
||||
*
|
||||
* @param pdfImageRemovalService The service used for removing images from PDFs.
|
||||
*/
|
||||
public PdfImageRemovalController(PdfImageRemovalService pdfImageRemovalService) {
|
||||
@Autowired
|
||||
public PdfImageRemovalController(
|
||||
PdfImageRemovalService pdfImageRemovalService,
|
||||
CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfImageRemovalService = pdfImageRemovalService;
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,14 +58,8 @@ public class PdfImageRemovalController {
|
|||
description =
|
||||
"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 {
|
||||
|
||||
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);
|
||||
// Load the PDF document
|
||||
PDDocument document = pdfDocumentFactory.load(file);
|
||||
|
||||
// Remove images from the PDF document using the service
|
||||
PDDocument modifiedDocument = pdfImageRemovalService.removeImagesFromPdf(document);
|
||||
|
@ -74,7 +73,8 @@ public class PdfImageRemovalController {
|
|||
|
||||
// Generate a new filename for the modified PDF
|
||||
String mergedFileName =
|
||||
pdf.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_removed_images.pdf";
|
||||
file.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "")
|
||||
+ "_removed_images.pdf";
|
||||
|
||||
// Convert the byte array to a web response and return it
|
||||
return WebResponseUtils.bytesToWebResponse(outputStream.toByteArray(), mergedFileName);
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.multipdf.Overlay;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -25,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -33,6 +35,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@Tag(name = "General", description = "General APIs")
|
||||
public class PdfOverlayController {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public PdfOverlayController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Overlay PDF files in various modes",
|
||||
|
@ -56,7 +65,7 @@ public class PdfOverlayController {
|
|||
// "FixedRepeatOverlay"
|
||||
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
|
||||
|
||||
try (PDDocument basePdf = Loader.loadPDF(baseFile.getBytes());
|
||||
try (PDDocument basePdf = pdfDocumentFactory.load(baseFile);
|
||||
Overlay overlay = new Overlay()) {
|
||||
Map<Integer, String> overlayGuide =
|
||||
prepareOverlayGuide(
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -24,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
import stirling.software.SPDF.model.SortTypes;
|
||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -34,6 +36,13 @@ public class RearrangePagesPDFController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Remove pages from a PDF file",
|
||||
|
@ -45,7 +54,7 @@ public class RearrangePagesPDFController {
|
|||
MultipartFile pdfFile = request.getFileInput();
|
||||
String pagesToDelete = request.getPageNumbers();
|
||||
|
||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||
|
||||
// Split the page order string into an array of page numbers or range of numbers
|
||||
String[] pageOrderArr = pagesToDelete.split(",");
|
||||
|
|
|
@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -20,6 +20,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -29,6 +30,13 @@ public class RotationController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Rotate a PDF file",
|
||||
|
@ -39,7 +47,7 @@ public class RotationController {
|
|||
MultipartFile pdfFile = request.getFileInput();
|
||||
Integer angle = request.getAngle();
|
||||
// Load the PDF document
|
||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(request);
|
||||
|
||||
// Get the list of pages in the document
|
||||
PDPageTree pages = document.getPages();
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -27,6 +28,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -36,6 +38,13 @@ public class ScalePagesController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Change the size of a PDF page/document",
|
||||
|
@ -48,7 +57,8 @@ public class ScalePagesController {
|
|||
float scaleFactor = request.getScaleFactor();
|
||||
|
||||
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
||||
PDDocument outputDocument = new PDDocument();
|
||||
PDDocument outputDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
|
||||
PDRectangle targetSize = getTargetSize(targetPDRectangle, sourceDocument);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -27,9 +28,8 @@ import io.github.pixee.security.Filenames;
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
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.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -38,6 +38,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
public class SplitPDFController {
|
||||
|
||||
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")
|
||||
@Operation(
|
||||
|
@ -51,7 +57,7 @@ public class SplitPDFController {
|
|||
// open the pdf document
|
||||
|
||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||
PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
|
||||
// PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
|
||||
int totalPages = document.getNumberOfPages();
|
||||
List<Integer> pageNumbers = request.getPageNumbersList(document, false);
|
||||
System.out.println(
|
||||
|
@ -70,7 +76,8 @@ public class SplitPDFController {
|
|||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
||||
int previousPageNumber = 0;
|
||||
for (int splitPoint : pageNumbers) {
|
||||
try (PDDocument splitDocument = new PDDocument()) {
|
||||
try (PDDocument splitDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document)) {
|
||||
for (int i = previousPageNumber; i <= splitPoint; i++) {
|
||||
PDPage page = document.getPage(i);
|
||||
splitDocument.addPage(page);
|
||||
|
@ -79,7 +86,7 @@ public class SplitPDFController {
|
|||
previousPageNumber = splitPoint + 1;
|
||||
|
||||
// Transfer metadata to split pdf
|
||||
PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||
// PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
splitDocument.save(baos);
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocume
|
|||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -44,6 +45,13 @@ public class SplitPdfByChaptersController {
|
|||
private static final Logger logger =
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Split PDFs by Chapters",
|
||||
|
@ -258,7 +266,7 @@ public class SplitPdfByChaptersController {
|
|||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
||||
PdfMetadata metadata = null;
|
||||
if (includeMetadata) {
|
||||
metadata = PdfMetadataService.extractMetadataFromPdf(sourceDocument);
|
||||
metadata = pdfMetadataService.extractMetadataFromPdf(sourceDocument);
|
||||
}
|
||||
for (Bookmark bookmark : bookmarks) {
|
||||
try (PDDocument splitDocument = new PDDocument()) {
|
||||
|
@ -273,7 +281,7 @@ public class SplitPdfByChaptersController {
|
|||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
if (includeMetadata) {
|
||||
PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||
pdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||
}
|
||||
|
||||
splitDocument.save(baos);
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -33,6 +34,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -43,6 +45,13 @@ public class SplitPdfBySectionsController {
|
|||
private static final Logger logger =
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Split PDF pages into smaller sections",
|
||||
|
@ -65,7 +74,7 @@ public class SplitPdfBySectionsController {
|
|||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
if (merge) {
|
||||
MergeController mergeController = new MergeController();
|
||||
MergeController mergeController = new MergeController(pdfDocumentFactory);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
mergeController.mergeDocuments(splitDocuments).save(baos);
|
||||
return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), filename + "_split.pdf");
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -25,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -34,6 +36,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
public class SplitPdfBySizeController {
|
||||
|
||||
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")
|
||||
@Operation(
|
||||
|
@ -84,7 +92,8 @@ public class SplitPdfBySizeController {
|
|||
PDDocument sourceDocument, long maxBytes, ZipOutputStream zipOut, String baseFilename)
|
||||
throws IOException {
|
||||
long currentSize = 0;
|
||||
PDDocument currentDoc = new PDDocument();
|
||||
PDDocument currentDoc =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
int fileIndex = 1;
|
||||
|
||||
for (int pageIndex = 0; pageIndex < sourceDocument.getNumberOfPages(); pageIndex++) {
|
||||
|
@ -121,7 +130,8 @@ public class SplitPdfBySizeController {
|
|||
PDDocument sourceDocument, int pageCount, ZipOutputStream zipOut, String baseFilename)
|
||||
throws IOException {
|
||||
int currentPageCount = 0;
|
||||
PDDocument currentDoc = new PDDocument();
|
||||
PDDocument currentDoc =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
int fileIndex = 1;
|
||||
for (PDPage page : sourceDocument.getPages()) {
|
||||
currentDoc.addPage(page);
|
||||
|
@ -152,7 +162,8 @@ public class SplitPdfBySizeController {
|
|||
int currentPageIndex = 0;
|
||||
int fileIndex = 1;
|
||||
for (int i = 0; i < documentCount; i++) {
|
||||
PDDocument currentDoc = new PDDocument();
|
||||
PDDocument currentDoc =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
|
||||
|
||||
for (int j = 0; j < pagesToAdd; j++) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -23,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -32,6 +34,13 @@ public class ToSinglePageController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Convert a multi-page PDF into a single long page PDF",
|
||||
|
@ -53,7 +62,8 @@ public class ToSinglePageController {
|
|||
}
|
||||
|
||||
// Create new document and page with calculated dimensions
|
||||
PDDocument newDocument = new PDDocument();
|
||||
PDDocument newDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||
PDPage newPage = new PDPage(new PDRectangle(maxWidth, totalHeight));
|
||||
newDocument.addPage(newPage);
|
||||
|
||||
|
|
|
@ -1,30 +1,36 @@
|
|||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
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 io.github.pixee.security.Filenames;
|
||||
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.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.FileToPdf;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
// Disabled for now
|
||||
// @RestController
|
||||
// @Tag(name = "Convert", description = "Convert APIs")
|
||||
// @RequestMapping("/api/v1/convert")
|
||||
public class ConvertBookToPDFController {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
private final boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
// @Autowired
|
||||
public ConvertBookToPDFController(
|
||||
CustomPDDocumentFactory pdfDocumentFactory,
|
||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/book/pdf")
|
||||
@Operation(
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
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 io.github.pixee.security.Filenames;
|
||||
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.utils.FileToPdf;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
// Disabled for now
|
||||
// @RestController
|
||||
// @Tag(name = "Convert", description = "Convert APIs")
|
||||
// @RequestMapping("/api/v1/convert")
|
||||
public class ConvertHtmlToPDF {
|
||||
|
||||
@Autowired
|
||||
// @Autowired
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.apache.pdfbox.rendering.ImageType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -30,6 +31,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
|
||||
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
||||
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.PdfUtils;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||
|
@ -43,6 +45,13 @@ public class ConvertImgPDFController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Convert PDF to image(s)",
|
||||
|
@ -178,7 +187,8 @@ public class ConvertImgPDFController {
|
|||
boolean autoRotate = request.isAutoRotate();
|
||||
|
||||
// Convert the file to PDF and get the resulting bytes
|
||||
byte[] bytes = PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType);
|
||||
byte[] bytes =
|
||||
PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType, pdfDocumentFactory);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
bytes,
|
||||
file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_converted.pdf");
|
||||
|
|
|
@ -10,29 +10,26 @@ import org.commonmark.node.Node;
|
|||
import org.commonmark.parser.Parser;
|
||||
import org.commonmark.renderer.html.AttributeProvider;
|
||||
import org.commonmark.renderer.html.HtmlRenderer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
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 io.github.pixee.security.Filenames;
|
||||
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.utils.FileToPdf;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
// Disabled for now
|
||||
// @RestController
|
||||
// @Tag(name = "Convert", description = "Convert APIs")
|
||||
// @RequestMapping("/api/v1/convert")
|
||||
public class ConvertMarkdownToPdf {
|
||||
|
||||
@Autowired
|
||||
// @Autowired
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -8,6 +9,8 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
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.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -20,6 +23,7 @@ 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.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
@ -29,7 +33,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@RequestMapping("/api/v1/convert")
|
||||
public class ConvertOfficeController {
|
||||
|
||||
public byte[] convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||
// Check for valid file extension
|
||||
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
|
||||
if (originalFilename == null
|
||||
|
@ -62,12 +66,10 @@ public class ConvertOfficeController {
|
|||
.runCommandWithOutputHandling(command);
|
||||
|
||||
// Read the converted PDF file
|
||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
return pdfBytes;
|
||||
return tempOutputFile.toFile();
|
||||
} finally {
|
||||
// Clean up the temporary files
|
||||
if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
|
||||
Files.deleteIfExists(tempOutputFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +78,13 @@ public class ConvertOfficeController {
|
|||
return fileExtension.matches(extensionPattern);
|
||||
}
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ConvertOfficeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/file/pdf")
|
||||
@Operation(
|
||||
summary = "Convert a file to a PDF using LibreOffice",
|
||||
|
@ -86,12 +95,18 @@ public class ConvertOfficeController {
|
|||
MultipartFile inputFile = request.getFileInput();
|
||||
// unused but can start server instance if startup time is to long
|
||||
// LibreOfficeListener.getInstance().start();
|
||||
File file = null;
|
||||
try {
|
||||
file = convertToPdf(inputFile);
|
||||
|
||||
byte[] pdfByteArray = convertToPdf(inputFile);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
pdfByteArray,
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_convertedToPDF.pdf");
|
||||
PDDocument doc = pdfDocumentFactory.load(file);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
doc,
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_convertedToPDF.pdf");
|
||||
} finally {
|
||||
if (file != null) file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,30 +6,27 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
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 io.github.pixee.security.Filenames;
|
||||
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.utils.ProcessExecutor;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
// Disabled for now
|
||||
// @RestController
|
||||
// @Tag(name = "Convert", description = "Convert APIs")
|
||||
// @RequestMapping("/api/v1/convert")
|
||||
public class ConvertPDFToBookController {
|
||||
|
||||
@Autowired
|
||||
// @Autowired
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
|
@ -17,6 +16,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -29,6 +29,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.ProcessExecutorResult;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
@ -40,6 +41,13 @@ public class ConvertPDFToPDFA {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Convert a PDF to a PDF/A",
|
||||
|
@ -54,7 +62,7 @@ public class ConvertPDFToPDFA {
|
|||
byte[] pdfBytes = inputFile.getBytes();
|
||||
|
||||
// Load the PDF document
|
||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
||||
PDDocument document = pdfDocumentFactory.load(pdfBytes);
|
||||
|
||||
// Get the document catalog
|
||||
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||
|
@ -101,18 +109,18 @@ public class ConvertPDFToPDFA {
|
|||
ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF)
|
||||
.runCommandWithOutputHandling(command);
|
||||
|
||||
// Read the optimized PDF file
|
||||
byte[] optimizedPdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
|
||||
// Clean up the temporary files
|
||||
Files.deleteIfExists(tempInputFile);
|
||||
Files.deleteIfExists(tempOutputFile);
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_PDFA.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(optimizedPdfBytes, outputFilename);
|
||||
try {
|
||||
PDDocument doc = pdfDocumentFactory.load(tempOutputFile.toFile());
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_PDFA.pdf";
|
||||
return WebResponseUtils.pdfDocToWebResponse(doc, outputFilename);
|
||||
} finally {
|
||||
// Clean up the temporary files
|
||||
Files.deleteIfExists(tempInputFile);
|
||||
Files.deleteIfExists(tempOutputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
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.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -16,6 +20,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.ProcessExecutor;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
|
@ -26,6 +31,15 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@RequestMapping("/api/v1/convert")
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Convert a URL to a PDF",
|
||||
|
@ -46,12 +60,12 @@ public class ConvertWebsiteToPDF {
|
|||
}
|
||||
|
||||
Path tempOutputFile = null;
|
||||
byte[] pdfBytes;
|
||||
PDDocument doc = null;
|
||||
try {
|
||||
// Prepare the output file path
|
||||
tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||
|
||||
// Prepare the OCRmyPDF command
|
||||
// Prepare the WeasyPrint command
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("weasyprint");
|
||||
command.add(URL);
|
||||
|
@ -61,16 +75,23 @@ public class ConvertWebsiteToPDF {
|
|||
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
||||
.runCommandWithOutputHandling(command);
|
||||
|
||||
// Read the optimized PDF file
|
||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
} finally {
|
||||
// Clean up the temporary files
|
||||
Files.deleteIfExists(tempOutputFile);
|
||||
}
|
||||
// Convert URL to a safe filename
|
||||
String outputFilename = convertURLToFileName(URL);
|
||||
// Load the PDF using pdfDocumentFactory
|
||||
doc = pdfDocumentFactory.load(tempOutputFile.toFile());
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||
// Convert URL to a safe filename
|
||||
String outputFilename = convertURLToFileName(URL);
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(doc, 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) {
|
||||
|
|
|
@ -30,13 +30,13 @@ import stirling.software.SPDF.model.api.extract.PDFFilePage;
|
|||
@RestController
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
public class ExtractController {
|
||||
public class ExtractCSVController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
||||
|
||||
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Extracts a PDF document to csv",
|
||||
summary = "Extracts a CSV document from a PDF",
|
||||
description =
|
||||
"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 {
|
|
@ -12,11 +12,11 @@ import java.util.List;
|
|||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -38,6 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -49,6 +50,13 @@ public class AutoSplitPdfController {
|
|||
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 final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public AutoSplitPdfController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Auto split PDF pages into separate documents",
|
||||
|
@ -59,73 +67,93 @@ public class AutoSplitPdfController {
|
|||
MultipartFile file = request.getFileInput();
|
||||
boolean duplexMode = request.isDuplexMode();
|
||||
|
||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||
pdfRenderer.setSubsamplingAllowed(true);
|
||||
PDDocument document = null;
|
||||
List<PDDocument> splitDocuments = new ArrayList<>();
|
||||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
||||
Path zipFile = null;
|
||||
byte[] data = null;
|
||||
|
||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||
String result = decodeQRCode(bim);
|
||||
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
||||
splitDocuments.add(new PDDocument());
|
||||
try {
|
||||
document = pdfDocumentFactory.load(file.getInputStream());
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||
pdfRenderer.setSubsamplingAllowed(true);
|
||||
|
||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||
String result = decodeQRCode(bim);
|
||||
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
||||
splitDocuments.add(new PDDocument());
|
||||
}
|
||||
|
||||
if (!splitDocuments.isEmpty()
|
||||
&& !QR_CONTENT.equals(result)
|
||||
&& !QR_CONTENT_OLD.equals(result)) {
|
||||
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
||||
} else if (page == 0) {
|
||||
PDDocument firstDocument = new PDDocument();
|
||||
firstDocument.addPage(document.getPage(page));
|
||||
splitDocuments.add(firstDocument);
|
||||
}
|
||||
|
||||
// If duplexMode is true and current page is a divider, then skip next page
|
||||
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
||||
page++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!splitDocuments.isEmpty()
|
||||
&& !QR_CONTENT.equals(result)
|
||||
&& !QR_CONTENT_OLD.equals(result)) {
|
||||
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
||||
} else if (page == 0) {
|
||||
PDDocument firstDocument = new PDDocument();
|
||||
firstDocument.addPage(document.getPage(page));
|
||||
splitDocuments.add(firstDocument);
|
||||
// Remove split documents that have no pages
|
||||
splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0);
|
||||
|
||||
zipFile = Files.createTempFile("split_documents", ".zip");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
for (int i = 0; i < splitDocuments.size(); i++) {
|
||||
String fileName = filename + "_" + (i + 1) + ".pdf";
|
||||
PDDocument splitDocument = splitDocuments.get(i);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
splitDocument.save(baos);
|
||||
byte[] pdf = baos.toByteArray();
|
||||
|
||||
ZipEntry pdfEntry = new ZipEntry(fileName);
|
||||
zipOut.putNextEntry(pdfEntry);
|
||||
zipOut.write(pdf);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
// If duplexMode is true and current page is a divider, then skip next page
|
||||
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
||||
page++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove split documents that have no pages
|
||||
splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0);
|
||||
|
||||
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 =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
byte[] data;
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
|
||||
String fileName = filename + "_" + (i + 1) + ".pdf";
|
||||
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
|
||||
byte[] pdf = baos.toByteArray();
|
||||
|
||||
ZipEntry pdfEntry = new ZipEntry(fileName);
|
||||
zipOut.putNextEntry(pdfEntry);
|
||||
zipOut.write(pdf);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("exception", e);
|
||||
} finally {
|
||||
data = Files.readAllBytes(zipFile);
|
||||
Files.deleteIfExists(zipFile);
|
||||
}
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
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) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -30,6 +31,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -40,6 +42,13 @@ public class BlankPageController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Remove blank pages from a PDF file",
|
||||
|
@ -124,7 +133,7 @@ public class BlankPageController {
|
|||
|
||||
public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName)
|
||||
throws IOException {
|
||||
try (PDDocument document = new PDDocument()) {
|
||||
try (PDDocument document = pdfDocumentFactory.createNewDocument()) {
|
||||
|
||||
for (PDPage page : pages) {
|
||||
document.addPage(page);
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
|||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -32,6 +33,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.ProcessExecutor;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
|
@ -44,6 +46,13 @@ public class CompressController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Optimize PDF file",
|
||||
|
@ -258,7 +267,7 @@ public class CompressController {
|
|||
}
|
||||
// Read the optimized PDF file
|
||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
|
||||
Path finalFile = tempOutputFile;
|
||||
// Check if optimized file is larger than the original
|
||||
if (pdfBytes.length > inputFileSize) {
|
||||
// Log the occurrence
|
||||
|
@ -266,14 +275,15 @@ public class CompressController {
|
|||
"Optimized file is larger than the original. Returning the original file instead.");
|
||||
|
||||
// Read the original file again
|
||||
pdfBytes = Files.readAllBytes(tempInputFile);
|
||||
finalFile = tempInputFile;
|
||||
}
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_Optimized.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
pdfDocumentFactory.load(finalFile.toFile()), outputFilename);
|
||||
|
||||
} finally {
|
||||
// Clean up the temporary files
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.apache.pdfbox.rendering.ImageType;
|
|||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -25,9 +26,8 @@ import io.github.pixee.security.Filenames;
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
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.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -37,6 +37,13 @@ public class FlattenController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Flatten PDF form fields or full page",
|
||||
|
@ -46,7 +53,6 @@ public class FlattenController {
|
|||
MultipartFile file = request.getFileInput();
|
||||
|
||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||
PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
|
||||
Boolean flattenOnlyForms = request.getFlattenOnlyForms();
|
||||
|
||||
if (Boolean.TRUE.equals(flattenOnlyForms)) {
|
||||
|
@ -60,7 +66,8 @@ public class FlattenController {
|
|||
// flatten whole page aka convert each page to image and readd it (making text
|
||||
// unselectable)
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||
PDDocument newDocument = new PDDocument();
|
||||
PDDocument newDocument =
|
||||
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document);
|
||||
int numPages = document.getNumberOfPages();
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
try {
|
||||
|
@ -80,7 +87,6 @@ public class FlattenController {
|
|||
logger.error("exception", e);
|
||||
}
|
||||
}
|
||||
PdfMetadataService.setMetadataToPdf(newDocument, metadata);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
newDocument, Filenames.toSimpleFileName(file.getOriginalFilename()));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -28,6 +29,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
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.ProcessExecutorResult;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
@ -52,6 +54,13 @@ public class OCRController {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public OCRController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
||||
@Operation(
|
||||
summary = "Process a PDF file with OCR",
|
||||
|
@ -175,7 +184,7 @@ public class OCRController {
|
|||
tempOutputFile = tempPdfWithoutImages;
|
||||
}
|
||||
// Read the OCR processed PDF file
|
||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
byte[] pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile());
|
||||
|
||||
// Return the OCR processed PDF as a response
|
||||
String outputFilename =
|
||||
|
@ -196,7 +205,13 @@ public class OCRController {
|
|||
// Add PDF file to the zip
|
||||
ZipEntry pdfEntry = new ZipEntry(outputFilename);
|
||||
zipOut.putNextEntry(pdfEntry);
|
||||
Files.copy(tempOutputFile, zipOut);
|
||||
try (ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = pdfInputStream.read(buffer)) != -1) {
|
||||
zipOut.write(buffer, 0, length);
|
||||
}
|
||||
}
|
||||
zipOut.closeEntry();
|
||||
|
||||
// Add text file to the zip
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -17,6 +18,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -27,6 +29,13 @@ public class OverlayImageController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Overlay image onto a PDF file",
|
||||
|
@ -41,7 +50,9 @@ public class OverlayImageController {
|
|||
try {
|
||||
byte[] pdfBytes = pdfFile.getBytes();
|
||||
byte[] imageBytes = imageFile.getBytes();
|
||||
byte[] result = PdfUtils.overlayImage(pdfBytes, imageBytes, x, y, everyPage);
|
||||
byte[] result =
|
||||
PdfUtils.overlayImage(
|
||||
pdfDocumentFactory, pdfBytes, imageBytes, x, y, everyPage);
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
result,
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -13,6 +12,7 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
|||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -36,6 +37,13 @@ public class PageNumbersController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Add page numbers to a PDF document",
|
||||
|
@ -52,7 +60,7 @@ public class PageNumbersController {
|
|||
String customText = request.getCustomText();
|
||||
int pageNumber = startingNumber;
|
||||
byte[] fileBytes = file.getBytes();
|
||||
PDDocument document = Loader.loadPDF(fileBytes);
|
||||
PDDocument document = pdfDocumentFactory.load(fileBytes);
|
||||
float font_size = request.getFontSize();
|
||||
String font_type = request.getFontType();
|
||||
float marginFactor;
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.List;
|
|||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -20,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.ProcessExecutorResult;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
@ -31,6 +33,13 @@ public class RepairController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Repair a PDF file",
|
||||
|
@ -58,7 +67,7 @@ public class RepairController {
|
|||
.runCommandWithOutputHandling(command);
|
||||
|
||||
// Read the optimized PDF file
|
||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile());
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.List;
|
|||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -25,6 +24,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
|||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -38,6 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.AddStampRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -45,6 +46,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
public class StampController {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public StampController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
||||
@Operation(
|
||||
summary = "Add stamp to a PDF file",
|
||||
|
@ -86,7 +94,7 @@ public class StampController {
|
|||
}
|
||||
|
||||
// Load the input PDF
|
||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||
|
||||
List<Integer> pageNumbers = request.getPageNumbersList(document, true);
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.security.cert.CertificateException;
|
|||
import java.security.cert.CertificateFactory;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
|
||||
|
@ -35,6 +34,7 @@ import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
|||
import org.bouncycastle.pkcs.PKCSException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -47,6 +47,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -71,6 +72,13 @@ public class CertSignController {
|
|||
}
|
||||
}
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public CertSignController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
||||
@Operation(
|
||||
summary = "Sign PDF with a Digital Certificate",
|
||||
|
@ -122,7 +130,7 @@ public class CertSignController {
|
|||
|
||||
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
sign(pdf.getBytes(), baos, createSignature, name, location, reason);
|
||||
sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, name, location, reason);
|
||||
return WebResponseUtils.boasToWebResponse(
|
||||
baos,
|
||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
|
@ -130,13 +138,14 @@ public class CertSignController {
|
|||
}
|
||||
|
||||
private static void sign(
|
||||
CustomPDDocumentFactory pdfDocumentFactory,
|
||||
byte[] input,
|
||||
OutputStream output,
|
||||
CreateSignature instance,
|
||||
String name,
|
||||
String location,
|
||||
String reason) {
|
||||
try (PDDocument doc = Loader.loadPDF(input)) {
|
||||
try (PDDocument doc = pdfDocumentFactory.load(input)) {
|
||||
PDSignature signature = new PDSignature();
|
||||
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
|
||||
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
|
||||
|
|
|
@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api.security;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
||||
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
|
||||
import stirling.software.SPDF.model.api.security.AddPasswordRequest;
|
||||
import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -30,6 +31,13 @@ public class PasswordController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Remove password from a PDF file",
|
||||
|
@ -39,8 +47,7 @@ public class PasswordController {
|
|||
throws IOException {
|
||||
MultipartFile fileInput = request.getFileInput();
|
||||
String password = request.getPassword();
|
||||
|
||||
PDDocument document = Loader.loadPDF(fileInput.getBytes(), password);
|
||||
PDDocument document = pdfDocumentFactory.load(fileInput, password);
|
||||
document.setAllSecurityToBeRemoved(true);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
|
@ -69,7 +76,7 @@ public class PasswordController {
|
|||
boolean canPrint = request.isCanPrint();
|
||||
boolean canPrintFaithful = request.isCanPrintFaithful();
|
||||
|
||||
PDDocument document = Loader.loadPDF(fileInput.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(fileInput);
|
||||
AccessPermission ap = new AccessPermission();
|
||||
ap.setCanAssembleDocument(!canAssembleDocument);
|
||||
ap.setCanExtractContent(!canExtractContent);
|
||||
|
|
|
@ -5,12 +5,12 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
import stirling.software.SPDF.model.PDFText;
|
||||
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
||||
import stirling.software.SPDF.pdf.TextFinder;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.PdfUtils;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
|
@ -35,6 +36,13 @@ public class RedactController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Redacts listOfText in a PDF document",
|
||||
|
@ -52,8 +60,7 @@ public class RedactController {
|
|||
|
||||
System.out.println(listOfTextString);
|
||||
String[] listOfText = listOfTextString.split("\n");
|
||||
byte[] bytes = file.getBytes();
|
||||
PDDocument document = Loader.loadPDF(bytes);
|
||||
PDDocument document = pdfDocumentFactory.load(file);
|
||||
|
||||
Color redactColor;
|
||||
try {
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
|
@ -12,6 +10,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -24,6 +23,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -33,6 +33,13 @@ public class RemoveCertSignController {
|
|||
|
||||
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")
|
||||
@Operation(
|
||||
summary = "Remove digital signature from PDF",
|
||||
|
@ -42,14 +49,8 @@ public class RemoveCertSignController {
|
|||
throws Exception {
|
||||
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
|
||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
||||
PDDocument document = pdfDocumentFactory.load(pdf);
|
||||
|
||||
// Get the document catalog
|
||||
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||
|
@ -67,14 +68,9 @@ public class RemoveCertSignController {
|
|||
acroForm.flatten(fieldsToRemove, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the modified document to the ByteArrayOutputStream
|
||||
document.save(baos);
|
||||
document.close();
|
||||
|
||||
// Return the modified PDF as a response
|
||||
return WebResponseUtils.boasToWebResponse(
|
||||
baos,
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_unsigned.pdf");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package stirling.software.SPDF.controller.api.security;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.cos.COSDictionary;
|
||||
import org.apache.pdfbox.cos.COSName;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
|
@ -21,6 +20,7 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
|
|||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -33,6 +33,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.security.SanitizePdfRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
|
@ -40,6 +41,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@Tag(name = "Security", description = "Security APIs")
|
||||
public class SanitizeController {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public SanitizeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf")
|
||||
@Operation(
|
||||
summary = "Sanitize a PDF file",
|
||||
|
@ -54,7 +62,7 @@ public class SanitizeController {
|
|||
boolean removeLinks = request.isRemoveLinks();
|
||||
boolean removeFonts = request.isRemoveFonts();
|
||||
|
||||
PDDocument document = Loader.loadPDF(inputFile.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(inputFile);
|
||||
if (removeJavaScript) {
|
||||
sanitizeJavaScript(document);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.nio.file.Files;
|
|||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -23,6 +22,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
|||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
@ -36,6 +36,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
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.WebResponseUtils;
|
||||
|
||||
|
@ -44,6 +45,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||
@Tag(name = "Security", description = "Security APIs")
|
||||
public class WatermarkController {
|
||||
|
||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public WatermarkController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
|
||||
@Operation(
|
||||
summary = "Add watermark to a PDF file",
|
||||
|
@ -64,7 +72,7 @@ public class WatermarkController {
|
|||
boolean convertPdfToImage = request.isConvertPDFToImage();
|
||||
|
||||
// Load the input PDF
|
||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
||||
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||
|
||||
// Create a page in the document
|
||||
for (PDPage page : document.getPages()) {
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
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
|
||||
}
|
|
@ -36,6 +36,8 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
|
||||
import io.github.pixee.security.Filenames;
|
||||
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
|
||||
public class PdfUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
|
||||
|
@ -380,9 +382,13 @@ public class PdfUtils {
|
|||
}
|
||||
|
||||
public static byte[] imageToPdf(
|
||||
MultipartFile[] files, String fitOption, boolean autoRotate, String colorType)
|
||||
MultipartFile[] files,
|
||||
String fitOption,
|
||||
boolean autoRotate,
|
||||
String colorType,
|
||||
CustomPDDocumentFactory pdfDocumentFactory)
|
||||
throws IOException {
|
||||
try (PDDocument doc = new PDDocument()) {
|
||||
try (PDDocument doc = pdfDocumentFactory.createNewDocument()) {
|
||||
for (MultipartFile file : files) {
|
||||
String contentType = file.getContentType();
|
||||
String originalFilename = Filenames.toSimpleFileName(file.getOriginalFilename());
|
||||
|
@ -470,10 +476,15 @@ public class PdfUtils {
|
|||
}
|
||||
|
||||
public static byte[] overlayImage(
|
||||
byte[] pdfBytes, byte[] imageBytes, float x, float y, boolean everyPage)
|
||||
CustomPDDocumentFactory pdfDocumentFactory,
|
||||
byte[] pdfBytes,
|
||||
byte[] imageBytes,
|
||||
float x,
|
||||
float y,
|
||||
boolean everyPage)
|
||||
throws IOException {
|
||||
|
||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
||||
PDDocument document = pdfDocumentFactory.load(pdfBytes);
|
||||
|
||||
// Get the first page of the PDF
|
||||
int pages = document.getNumberOfPages();
|
||||
|
|
|
@ -77,10 +77,10 @@ color=Colore
|
|||
sponsor=Sponsor
|
||||
info=Info
|
||||
|
||||
legal.privacy=Privacy Policy
|
||||
legal.terms=Terms and Conditions
|
||||
legal.accessibility=Accessibility
|
||||
legal.cookie=Cookie Policy
|
||||
legal.privacy=Informativa sulla privacy
|
||||
legal.terms=Termini e Condizioni
|
||||
legal.accessibility=Accessibilità
|
||||
legal.cookie=Informativa sui cookie
|
||||
legal.impressum=Impressum
|
||||
|
||||
###############
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
<script th:src="@{'/js/cacheFormInputs.js'}" th:if="${currentPage != 'home'}"></script>
|
||||
<script th:src="@{'/js/tab-container.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:fragment="game">
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
<footer th:fragment="footer" id="footer" class="text-center pt-5">
|
||||
<div class="footer-center pb-4">
|
||||
<!-- Links section -->
|
||||
<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 -->
|
||||
<footer th:fragment="footer" id="footer" class="text-center py-5">
|
||||
<div class="footer-center">
|
||||
<div class="footer-powered-by">
|
||||
<span th:text="#{poweredBy}"></span>
|
||||
<a href="https://stirlingpdf.com" class="stirling-link">Stirling PDF</a>
|
||||
</div>
|
||||
<span>Application proposée par la <b><a href="https://dgnum.eu">DGNum</a></b>.</span>
|
||||
</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>
|
||||
</footer>
|
||||
</footer>
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12 bg-card">
|
||||
<form>
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-md-3">
|
||||
<div id="sliders-container" style="display:none;">
|
||||
<h4><span th:text="#{adjustContrast.contrast}"></span> <span id="contrast-val">100</span>%</h4>
|
||||
|
@ -44,9 +46,13 @@
|
|||
</div>
|
||||
<br>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
var canvas = document.getElementById('contrast-pdf-canvas');
|
||||
|
@ -217,7 +223,7 @@
|
|||
function adjustBrightnessForPixel(pixel, brightness) {
|
||||
return Math.max(0, Math.min(255, pixel * brightness));
|
||||
}
|
||||
|
||||
let inputFileName = '';
|
||||
async function downloadPDF() {
|
||||
for (var i = 0; i < allPages.length; i++) {
|
||||
await renderPageAndAdjustImageProperties(allPages[i]);
|
||||
|
@ -246,7 +252,10 @@
|
|||
// Create download link
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = URL.createObjectURL(blob);
|
||||
downloadLink.download = "download.pdf";
|
||||
let newFileName = inputFileName ? inputFileName.replace('.pdf', '') : 'download';
|
||||
newFileName += '_adjusted_color.pdf';
|
||||
|
||||
downloadLink.download = newFileName;
|
||||
downloadLink.click();
|
||||
|
||||
// After download, reset the viewer and clear stored data
|
||||
|
@ -262,6 +271,7 @@
|
|||
// Event listeners
|
||||
document.getElementById('fileInput-input').addEventListener('change', function(e) {
|
||||
if (e.target.files.length > 0) {
|
||||
inputFileName = e.target.files[0].name;
|
||||
renderPDFAndSaveOriginalImageData(e.target.files[0]);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -172,16 +172,23 @@
|
|||
});
|
||||
|
||||
function toggleFileOption() {
|
||||
const stampImage = document.getElementById('stampImage');
|
||||
const stampType = document.getElementById('stampType').value;
|
||||
const stampTextGroup = document.getElementById('stampTextGroup');
|
||||
const stampImageGroup = document.getElementById('stampImageGroup');
|
||||
const alphabetGroup = document.getElementById('alphabetGroup');
|
||||
|
||||
if (stampType === 'text') {
|
||||
if (stampImage.hasAttribute('required')) {
|
||||
stampImage.removeAttribute('required');
|
||||
}
|
||||
stampTextGroup.style.display = 'block';
|
||||
stampImageGroup.style.display = 'none';
|
||||
alphabetGroup.style.display = 'block';
|
||||
} else if (stampType === 'image') {
|
||||
if (!stampImage.hasAttribute('required')) {
|
||||
stampImage.setAttribute('required', '');
|
||||
}
|
||||
stampTextGroup.style.display = 'none';
|
||||
stampImageGroup.style.display = 'block';
|
||||
alphabetGroup.style.display = 'none';
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=true)}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="element-margin">
|
||||
<div class="element-margin text-start">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
id="submitConfigBtn"
|
||||
|
@ -164,7 +164,7 @@
|
|||
class="btn btn-danger"
|
||||
th:text="#{delete}"
|
||||
></button>
|
||||
|
||||
|
||||
<button
|
||||
id="saveBrowserPipelineBtn"
|
||||
class="btn btn-success"
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
<input type="checkbox" id="convertPDFToImage" name="convertPDFToImage">
|
||||
<label for="convertPDFToImage" th:text="#{watermark.selectText.10}"></label>
|
||||
</div>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<input type="submit" id="submitBtn" th:value="#{watermark.submit}" class="btn btn-primary">
|
||||
</div>
|
||||
</form>
|
||||
|
@ -123,12 +123,18 @@
|
|||
const watermarkImage = document.getElementById('watermarkImage');
|
||||
|
||||
if (watermarkType === 'text') {
|
||||
if (watermarkImage.hasAttribute('required')) {
|
||||
watermarkImage.removeAttribute('required');
|
||||
}
|
||||
watermarkTextGroup.style.display = 'block';
|
||||
watermarkText.required = true;
|
||||
watermarkImageGroup.style.display = 'none';
|
||||
watermarkImage.required = false;
|
||||
alphabetGroup.style.display = 'block';
|
||||
} else if (watermarkType === 'image') {
|
||||
if (watermarkImage.hasAttribute('required')) {
|
||||
watermarkImage.removeAttribute('required');
|
||||
}
|
||||
watermarkTextGroup.style.display = 'none';
|
||||
watermarkText.required = false;
|
||||
watermarkImageGroup.style.display = 'block';
|
||||
|
@ -144,4 +150,4 @@
|
|||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{certSign.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{permissions.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<label th:text="#{removeCertSign.selectPDF}"></label>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||
</div>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeCertSign.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<input type="password" class="form-control" id="password" name="password">
|
||||
</div>
|
||||
<br>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<label for="removeFonts" th:text="#{sanitizePDF.selectText.5}"></label>
|
||||
</div>
|
||||
<br>
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-3 text-left">
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{sanitizePDF.submit}"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -8,15 +8,33 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
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 {
|
||||
|
||||
@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.
|
||||
*/
|
||||
@Test
|
||||
void oddEvenMerge_noPages() {
|
||||
RearrangePagesPDFController sut = new RearrangePagesPDFController();
|
||||
int totalNumberOfPages = 0;
|
||||
|
||||
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
|
||||
|
@ -30,7 +48,6 @@ class RearrangePagesPDFControllerTest {
|
|||
*/
|
||||
@Test
|
||||
void oddEvenMerge_oddTotalPageNumber() {
|
||||
RearrangePagesPDFController sut = new RearrangePagesPDFController();
|
||||
int totalNumberOfPages = 5;
|
||||
|
||||
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
|
||||
|
@ -44,7 +61,6 @@ class RearrangePagesPDFControllerTest {
|
|||
*/
|
||||
@Test
|
||||
void oddEvenMerge_evenTotalPageNumber() {
|
||||
RearrangePagesPDFController sut = new RearrangePagesPDFController();
|
||||
int totalNumberOfPages = 6;
|
||||
|
||||
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
|
||||
|
@ -72,8 +88,6 @@ class RearrangePagesPDFControllerTest {
|
|||
"22,47,23,48,24,49'"
|
||||
})
|
||||
void oddEvenMerge_multi_test(int totalNumberOfPages, String expectedPageOrder) {
|
||||
RearrangePagesPDFController sut = new RearrangePagesPDFController();
|
||||
|
||||
List<Integer> newPageOrder = sut.oddEvenMerge(totalNumberOfPages);
|
||||
|
||||
assertNotNull(newPageOrder, "Returning null instead of page order list");
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import stirling.software.SPDF.controller.api.RearrangePagesPDFController;
|
||||
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ConvertWebsiteToPdfTest {
|
||||
|
||||
|
||||
@Mock
|
||||
private CustomPDDocumentFactory mockPdfDocumentFactory;
|
||||
|
||||
private ConvertWebsiteToPDF convertWebsiteToPDF;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
convertWebsiteToPDF = new ConvertWebsiteToPDF(mockPdfDocumentFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_exemption_is_thrown_when_invalid_url_format_provided() {
|
||||
|
||||
String invalid_format_Url = "invalid-url";
|
||||
// Arrange
|
||||
ConvertWebsiteToPDF convertWebsiteToPDF = new ConvertWebsiteToPDF();
|
||||
|
||||
UrlToPdfRequest request = new UrlToPdfRequest();
|
||||
request.setUrlInput(invalid_format_Url);
|
||||
// Act
|
||||
|
@ -28,7 +46,6 @@ public class ConvertWebsiteToPdfTest {
|
|||
|
||||
String unreachable_Url = "https://www.googleeeexyz.com";
|
||||
// Arrange
|
||||
ConvertWebsiteToPDF convertWebsiteToPDF = new ConvertWebsiteToPDF();
|
||||
UrlToPdfRequest request = new UrlToPdfRequest();
|
||||
request.setUrlInput(unreachable_Url);
|
||||
// Act
|
||||
|
|
Loading…
Reference in a new issue