rearrange support n numbers, downloader.js fixes
This commit is contained in:
parent
e2a787e519
commit
4594765cbd
4 changed files with 235 additions and 245 deletions
|
@ -6,6 +6,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
|
@ -24,228 +29,241 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@RestController
|
@RestController
|
||||||
public class RearrangePagesPDFController {
|
public class RearrangePagesPDFController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
|
||||||
|
|
||||||
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
||||||
|
@Operation(summary = "Remove pages from a PDF file", description = "This endpoint removes specified pages from a given PDF file. Users can provide a comma-separated list of page numbers or ranges to delete.")
|
||||||
|
public ResponseEntity<byte[]> deletePages(
|
||||||
|
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file from which pages will be removed") MultipartFile pdfFile,
|
||||||
|
@RequestParam("pagesToDelete") @Parameter(description = "Comma-separated list of pages or page ranges to delete, e.g., '1,3,5-8'") String pagesToDelete)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
PDDocument document = PDDocument.load(pdfFile.getBytes());
|
||||||
@Operation(summary = "Remove pages from a PDF file",
|
|
||||||
description = "This endpoint removes specified pages from a given PDF file. Users can provide a comma-separated list of page numbers or ranges to delete.")
|
|
||||||
public ResponseEntity<byte[]> deletePages(
|
|
||||||
@RequestPart(required = true, value = "fileInput")
|
|
||||||
@Parameter(description = "The input PDF file from which pages will be removed")
|
|
||||||
MultipartFile pdfFile,
|
|
||||||
@RequestParam("pagesToDelete")
|
|
||||||
@Parameter(description = "Comma-separated list of pages or page ranges to delete, e.g., '1,3,5-8'")
|
|
||||||
String pagesToDelete) throws IOException {
|
|
||||||
|
|
||||||
PDDocument document = PDDocument.load(pdfFile.getBytes());
|
// Split the page order string into an array of page numbers or range of numbers
|
||||||
|
String[] pageOrderArr = pagesToDelete.split(",");
|
||||||
|
|
||||||
// Split the page order string into an array of page numbers or range of numbers
|
List<Integer> pagesToRemove = pageOrderToString(pageOrderArr, document.getNumberOfPages());
|
||||||
String[] pageOrderArr = pagesToDelete.split(",");
|
|
||||||
|
|
||||||
List<Integer> pagesToRemove = pageOrderToString(pageOrderArr, document.getNumberOfPages());
|
for (int i = pagesToRemove.size() - 1; i >= 0; i--) {
|
||||||
|
int pageIndex = pagesToRemove.get(i);
|
||||||
|
document.removePage(pageIndex);
|
||||||
|
}
|
||||||
|
return WebResponseUtils.pdfDocToWebResponse(document,
|
||||||
|
pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_removed_pages.pdf");
|
||||||
|
|
||||||
for (int i = pagesToRemove.size() - 1; i >= 0; i--) {
|
}
|
||||||
int pageIndex = pagesToRemove.get(i);
|
|
||||||
document.removePage(pageIndex);
|
|
||||||
}
|
|
||||||
return WebResponseUtils.pdfDocToWebResponse(document, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_removed_pages.pdf");
|
|
||||||
|
|
||||||
}
|
private enum CustomMode {
|
||||||
|
REVERSE_ORDER, DUPLEX_SORT, BOOKLET_SORT, ODD_EVEN_SPLIT, REMOVE_FIRST, REMOVE_LAST, REMOVE_FIRST_AND_LAST,
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> pageOrderToString(String[] pageOrderArr, int totalPages) {
|
private List<Integer> removeFirst(int totalPages) {
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
if (totalPages <= 1)
|
||||||
// loop through the page order array
|
return new ArrayList<>();
|
||||||
for (String element : pageOrderArr) {
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
// check if the element contains a range of pages
|
for (int i = 2; i <= totalPages; i++) {
|
||||||
if (element.contains("-")) {
|
newPageOrder.add(i - 1);
|
||||||
// split the range into start and end page
|
}
|
||||||
String[] range = element.split("-");
|
return newPageOrder;
|
||||||
int start = Integer.parseInt(range[0]);
|
}
|
||||||
int end = Integer.parseInt(range[1]);
|
|
||||||
// check if the end page is greater than total pages
|
|
||||||
if (end > totalPages) {
|
|
||||||
end = totalPages;
|
|
||||||
}
|
|
||||||
// loop through the range of pages
|
|
||||||
for (int j = start; j <= end; j++) {
|
|
||||||
// print the current index
|
|
||||||
newPageOrder.add(j - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if the element is a single page
|
|
||||||
newPageOrder.add(Integer.parseInt(element) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newPageOrder;
|
private List<Integer> removeLast(int totalPages) {
|
||||||
}
|
if (totalPages <= 1)
|
||||||
|
return new ArrayList<>();
|
||||||
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
|
for (int i = 1; i < totalPages; i++) {
|
||||||
|
newPageOrder.add(i - 1);
|
||||||
|
}
|
||||||
|
return newPageOrder;
|
||||||
|
}
|
||||||
|
|
||||||
private enum CustomMode {
|
private List<Integer> removeFirstAndLast(int totalPages) {
|
||||||
REVERSE_ORDER,
|
if (totalPages <= 2)
|
||||||
DUPLEX_SORT,
|
return new ArrayList<>();
|
||||||
BOOKLET_SORT,
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
ODD_EVEN_SPLIT,
|
for (int i = 2; i < totalPages; i++) {
|
||||||
REMOVE_FIRST,
|
newPageOrder.add(i - 1);
|
||||||
REMOVE_LAST,
|
}
|
||||||
REMOVE_FIRST_AND_LAST,
|
return newPageOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Integer> removeFirst(int totalPages) {
|
private List<Integer> reverseOrder(int totalPages) {
|
||||||
if (totalPages <= 1) return new ArrayList<>();
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
for (int i = totalPages; i >= 1; i--) {
|
||||||
for (int i = 2; i <= totalPages; i++) {
|
newPageOrder.add(i - 1);
|
||||||
newPageOrder.add(i - 1);
|
}
|
||||||
}
|
return newPageOrder;
|
||||||
return newPageOrder;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private List<Integer> removeLast(int totalPages) {
|
private List<Integer> duplexSort(int totalPages) {
|
||||||
if (totalPages <= 1) return new ArrayList<>();
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
int half = (totalPages + 1) / 2; // This ensures proper behavior with odd numbers of pages
|
||||||
for (int i = 1; i < totalPages; i++) {
|
for (int i = 1; i <= half; i++) {
|
||||||
newPageOrder.add(i - 1);
|
newPageOrder.add(i - 1);
|
||||||
}
|
if (i <= totalPages - half) { // Avoid going out of bounds
|
||||||
return newPageOrder;
|
newPageOrder.add(totalPages - i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return newPageOrder;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> removeFirstAndLast(int totalPages) {
|
private List<Integer> bookletSort(int totalPages) {
|
||||||
if (totalPages <= 2) return new ArrayList<>();
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
for (int i = 0; i < totalPages / 2; i++) {
|
||||||
for (int i = 2; i < totalPages; i++) {
|
newPageOrder.add(i);
|
||||||
newPageOrder.add(i - 1);
|
newPageOrder.add(totalPages - i - 1);
|
||||||
}
|
}
|
||||||
return newPageOrder;
|
return newPageOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Integer> oddEvenSplit(int totalPages) {
|
||||||
private List<Integer> reverseOrder(int totalPages) {
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
for (int i = 1; i <= totalPages; i += 2) {
|
||||||
for (int i = totalPages; i >= 1; i--) {
|
newPageOrder.add(i - 1);
|
||||||
newPageOrder.add(i - 1);
|
}
|
||||||
}
|
for (int i = 2; i <= totalPages; i += 2) {
|
||||||
return newPageOrder;
|
newPageOrder.add(i - 1);
|
||||||
}
|
}
|
||||||
|
return newPageOrder;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> duplexSort(int totalPages) {
|
private List<Integer> processCustomMode(String customMode, int totalPages) {
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
try {
|
||||||
int half = (totalPages + 1) / 2; // This ensures proper behavior with odd numbers of pages
|
CustomMode mode = CustomMode.valueOf(customMode.toUpperCase());
|
||||||
for (int i = 1; i <= half; i++) {
|
switch (mode) {
|
||||||
newPageOrder.add(i - 1);
|
case REVERSE_ORDER:
|
||||||
if (i <= totalPages - half) { // Avoid going out of bounds
|
return reverseOrder(totalPages);
|
||||||
newPageOrder.add(totalPages - i);
|
case DUPLEX_SORT:
|
||||||
}
|
return duplexSort(totalPages);
|
||||||
}
|
case BOOKLET_SORT:
|
||||||
return newPageOrder;
|
return bookletSort(totalPages);
|
||||||
}
|
case ODD_EVEN_SPLIT:
|
||||||
|
return oddEvenSplit(totalPages);
|
||||||
|
case REMOVE_FIRST:
|
||||||
|
return removeFirst(totalPages);
|
||||||
|
case REMOVE_LAST:
|
||||||
|
return removeLast(totalPages);
|
||||||
|
case REMOVE_FIRST_AND_LAST:
|
||||||
|
return removeFirstAndLast(totalPages);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported custom mode");
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.error("Unsupported custom mode", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(consumes = "multipart/form-data", value = "/rearrange-pages")
|
||||||
|
@Operation(summary = "Rearrange pages in a PDF file", description = "This endpoint rearranges pages in a given PDF file based on the specified page order or custom mode. Users can provide a page order as a comma-separated list of page numbers or page ranges, or a custom mode.")
|
||||||
|
public ResponseEntity<byte[]> rearrangePages(
|
||||||
|
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to rearrange pages") MultipartFile pdfFile,
|
||||||
|
@RequestParam(required = false, value = "pageOrder") @Parameter(description = "The new page order as a comma-separated list of page numbers, page ranges (e.g., '1,3,5-7'), or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')") String pageOrder,
|
||||||
|
@RequestParam(required = false, value = "customMode") @Parameter(schema = @Schema(implementation = CustomMode.class, description = "The custom mode for page rearrangement. "
|
||||||
|
+ "Valid values are:\n" + "REVERSE_ORDER: Reverses the order of all pages.\n"
|
||||||
|
+ "DUPLEX_SORT: Sorts pages as if all fronts were scanned then all backs in reverse (1, n, 2, n-1, ...). "
|
||||||
|
+ "BOOKLET_SORT: Arranges pages for booklet printing (last, first, second, second last, ...).\n"
|
||||||
|
+ "ODD_EVEN_SPLIT: Splits and arranges pages into odd and even numbered pages.\n"
|
||||||
|
+ "REMOVE_FIRST: Removes the first page.\n" + "REMOVE_LAST: Removes the last page.\n"
|
||||||
|
+ "REMOVE_FIRST_AND_LAST: Removes both the first and the last pages.\n")) String customMode) {
|
||||||
|
try {
|
||||||
|
// Load the input PDF
|
||||||
|
PDDocument document = PDDocument.load(pdfFile.getInputStream());
|
||||||
|
|
||||||
private List<Integer> bookletSort(int totalPages) {
|
// Split the page order string into an array of page numbers or range of numbers
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
String[] pageOrderArr = pageOrder != null ? pageOrder.split(",") : new String[0];
|
||||||
for (int i = 0; i < totalPages / 2; i++) {
|
int totalPages = document.getNumberOfPages();
|
||||||
newPageOrder.add(i);
|
System.out.println("pageOrder=" + pageOrder);
|
||||||
newPageOrder.add(totalPages - i - 1);
|
System.out.println("customMode length =" + customMode.length());
|
||||||
}
|
List<Integer> newPageOrder;
|
||||||
return newPageOrder;
|
if (customMode != null && customMode.length() > 0) {
|
||||||
}
|
newPageOrder = processCustomMode(customMode, totalPages);
|
||||||
|
} else {
|
||||||
|
newPageOrder = pageOrderToString(pageOrderArr, totalPages);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> oddEvenSplit(int totalPages) {
|
// Create a new list to hold the pages in the new order
|
||||||
List<Integer> newPageOrder = new ArrayList<>();
|
List<PDPage> newPages = new ArrayList<>();
|
||||||
for (int i = 1; i <= totalPages; i += 2) {
|
for (int i = 0; i < newPageOrder.size(); i++) {
|
||||||
newPageOrder.add(i - 1);
|
newPages.add(document.getPage(newPageOrder.get(i)));
|
||||||
}
|
}
|
||||||
for (int i = 2; i <= totalPages; i += 2) {
|
|
||||||
newPageOrder.add(i - 1);
|
|
||||||
}
|
|
||||||
return newPageOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Integer> processCustomMode(String customMode, int totalPages) {
|
// Remove all the pages from the original document
|
||||||
try {
|
for (int i = document.getNumberOfPages() - 1; i >= 0; i--) {
|
||||||
CustomMode mode = CustomMode.valueOf(customMode.toUpperCase());
|
document.removePage(i);
|
||||||
switch (mode) {
|
}
|
||||||
case REVERSE_ORDER:
|
|
||||||
return reverseOrder(totalPages);
|
|
||||||
case DUPLEX_SORT:
|
|
||||||
return duplexSort(totalPages);
|
|
||||||
case BOOKLET_SORT:
|
|
||||||
return bookletSort(totalPages);
|
|
||||||
case ODD_EVEN_SPLIT:
|
|
||||||
return oddEvenSplit(totalPages);
|
|
||||||
case REMOVE_FIRST:
|
|
||||||
return removeFirst(totalPages);
|
|
||||||
case REMOVE_LAST:
|
|
||||||
return removeLast(totalPages);
|
|
||||||
case REMOVE_FIRST_AND_LAST:
|
|
||||||
return removeFirstAndLast(totalPages);
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported custom mode");
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
logger.error("Unsupported custom mode", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/rearrange-pages")
|
// Add the pages in the new order
|
||||||
@Operation(summary = "Rearrange pages in a PDF file",
|
for (PDPage page : newPages) {
|
||||||
description = "This endpoint rearranges pages in a given PDF file based on the specified page order or custom mode. Users can provide a page order as a comma-separated list of page numbers or page ranges, or a custom mode.")
|
document.addPage(page);
|
||||||
public ResponseEntity<byte[]> rearrangePages(
|
}
|
||||||
@RequestPart(required = true, value = "fileInput")
|
|
||||||
@Parameter(description = "The input PDF file to rearrange pages")
|
|
||||||
MultipartFile pdfFile,
|
|
||||||
@RequestParam(required = false, value = "pageOrder")
|
|
||||||
@Parameter(description = "The new page order as a comma-separated list of page numbers or page ranges (e.g., '1,3,5-7')")
|
|
||||||
String pageOrder,
|
|
||||||
@RequestParam(required = false, value = "customMode")
|
|
||||||
@Parameter(schema = @Schema(implementation = CustomMode.class, description = "The custom mode for page rearrangement. " +
|
|
||||||
"Valid values are:\n" +
|
|
||||||
"REVERSE_ORDER: Reverses the order of all pages.\n" +
|
|
||||||
"DUPLEX_SORT: Sorts pages as if all fronts were scanned then all backs in reverse (1, n, 2, n-1, ...). " +
|
|
||||||
"BOOKLET_SORT: Arranges pages for booklet printing (last, first, second, second last, ...).\n" +
|
|
||||||
"ODD_EVEN_SPLIT: Splits and arranges pages into odd and even numbered pages.\n" +
|
|
||||||
"REMOVE_FIRST: Removes the first page.\n" +
|
|
||||||
"REMOVE_LAST: Removes the last page.\n" +
|
|
||||||
"REMOVE_FIRST_AND_LAST: Removes both the first and the last pages.\n"))
|
|
||||||
String customMode) {
|
|
||||||
try {
|
|
||||||
// Load the input PDF
|
|
||||||
PDDocument document = PDDocument.load(pdfFile.getInputStream());
|
|
||||||
|
|
||||||
// Split the page order string into an array of page numbers or range of numbers
|
return WebResponseUtils.pdfDocToWebResponse(document,
|
||||||
String[] pageOrderArr = pageOrder != null ? pageOrder.split(",") : new String[0];
|
pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_rearranged.pdf");
|
||||||
int totalPages = document.getNumberOfPages();
|
} catch (IOException e) {
|
||||||
System.out.println("pageOrder=" + pageOrder);
|
logger.error("Failed rearranging documents", e);
|
||||||
System.out.println("customMode length =" + customMode.length());
|
return null;
|
||||||
List<Integer> newPageOrder;
|
}
|
||||||
if(customMode != null && customMode.length() > 0) {
|
}
|
||||||
newPageOrder = processCustomMode(customMode, totalPages);
|
|
||||||
} else {
|
|
||||||
newPageOrder = pageOrderToString(pageOrderArr, totalPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new list to hold the pages in the new order
|
private List<Integer> pageOrderToString(String[] pageOrderArr, int totalPages) {
|
||||||
List<PDPage> newPages = new ArrayList<>();
|
List<Integer> newPageOrder = new ArrayList<>();
|
||||||
for (int i = 0; i < newPageOrder.size(); i++) {
|
|
||||||
newPages.add(document.getPage(newPageOrder.get(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all the pages from the original document
|
// loop through the page order array
|
||||||
for (int i = document.getNumberOfPages() - 1; i >= 0; i--) {
|
for (String element : pageOrderArr) {
|
||||||
document.removePage(i);
|
// check if the element contains a range of pages
|
||||||
}
|
if (element.matches("\\d*n\\+?-?\\d*|\\d*\\+?n")) {
|
||||||
|
// Handle page order as a function
|
||||||
|
int coefficient = 0;
|
||||||
|
int constant = 0;
|
||||||
|
boolean coefficientExists = false;
|
||||||
|
boolean constantExists = false;
|
||||||
|
|
||||||
// Add the pages in the new order
|
if (element.contains("n")) {
|
||||||
for (PDPage page : newPages) {
|
String[] parts = element.split("n");
|
||||||
document.addPage(page);
|
if (!parts[0].equals("") && parts[0] != null) {
|
||||||
}
|
coefficient = Integer.parseInt(parts[0]);
|
||||||
|
coefficientExists = true;
|
||||||
|
}
|
||||||
|
if (parts.length > 1 && !parts[1].equals("") && parts[1] != null) {
|
||||||
|
constant = Integer.parseInt(parts[1]);
|
||||||
|
constantExists = true;
|
||||||
|
}
|
||||||
|
} else if (element.contains("+")) {
|
||||||
|
constant = Integer.parseInt(element.replace("+", ""));
|
||||||
|
constantExists = true;
|
||||||
|
}
|
||||||
|
|
||||||
return WebResponseUtils.pdfDocToWebResponse(document, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_rearranged.pdf");
|
for (int i = 1; i <= totalPages; i++) {
|
||||||
} catch (IOException e) {
|
int pageNum = coefficientExists ? coefficient * i : i;
|
||||||
logger.error("Failed rearranging documents", e);
|
pageNum += constantExists ? constant : 0;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (pageNum <= totalPages && pageNum > 0) {
|
||||||
|
newPageOrder.add(pageNum - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (element.contains("-")) {
|
||||||
|
// split the range into start and end page
|
||||||
|
String[] range = element.split("-");
|
||||||
|
int start = Integer.parseInt(range[0]);
|
||||||
|
int end = Integer.parseInt(range[1]);
|
||||||
|
// check if the end page is greater than total pages
|
||||||
|
if (end > totalPages) {
|
||||||
|
end = totalPages;
|
||||||
|
}
|
||||||
|
// loop through the range of pages
|
||||||
|
for (int j = start; j <= end; j++) {
|
||||||
|
// print the current index
|
||||||
|
newPageOrder.add(j - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the element is a single page
|
||||||
|
newPageOrder.add(Integer.parseInt(element) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPageOrder;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ multiPdfDropPrompt=Select (or drag & drop) all PDFs you require
|
||||||
imgPrompt=Select Image(s)
|
imgPrompt=Select Image(s)
|
||||||
genericSubmit=Submit
|
genericSubmit=Submit
|
||||||
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
||||||
pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers) :
|
pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :
|
||||||
goToPage=Go
|
goToPage=Go
|
||||||
true=True
|
true=True
|
||||||
false=False
|
false=False
|
||||||
|
|
|
@ -19,25 +19,9 @@ $(document).ready(function() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (override === 'multi' || files.length > 1 && override !== 'single') {
|
if (override === 'multi' || files.length > 1 && override !== 'single') {
|
||||||
// Show the progress bar
|
|
||||||
$('#progressBarContainer').show();
|
|
||||||
// Initialize the progress bar
|
|
||||||
//let progressBar = $('#progressBar');
|
|
||||||
//progressBar.css('width', '0%');
|
|
||||||
//progressBar.attr('aria-valuenow', 0);
|
|
||||||
//progressBar.attr('aria-valuemax', files.length);
|
|
||||||
|
|
||||||
await submitMultiPdfForm(url, files);
|
await submitMultiPdfForm(url, files);
|
||||||
} else {
|
} else {
|
||||||
const downloadDetails = await handleSingleDownload(url, formData);
|
await handleSingleDownload(url, formData);
|
||||||
const downloadOption = localStorage.getItem('downloadOption');
|
|
||||||
|
|
||||||
// Handle the download action according to the selected option
|
|
||||||
//handleDownloadAction(downloadOption, downloadDetails.blob, downloadDetails.filename);
|
|
||||||
|
|
||||||
// Update the progress bar
|
|
||||||
//updateProgressBar(progressBar, 1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#submitBtn').text('Submit');
|
$('#submitBtn').text('Submit');
|
||||||
|
@ -49,29 +33,9 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleDownloadAction(downloadOption, blob, filename) {
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
|
|
||||||
switch (downloadOption) {
|
|
||||||
case 'sameWindow':
|
|
||||||
// Open the file in the same window
|
|
||||||
window.location.href = url;
|
|
||||||
break;
|
|
||||||
case 'newWindow':
|
|
||||||
// Open the file in a new window
|
|
||||||
window.open(url, '_blank');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Download the file
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = url;
|
|
||||||
link.download = filename;
|
|
||||||
link.click();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleSingleDownload(url, formData) {
|
async function handleSingleDownload(url, formData, isMulti = false) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url, { method: 'POST', body: formData });
|
const response = await fetch(url, { method: 'POST', body: formData });
|
||||||
const contentType = response.headers.get('content-type');
|
const contentType = response.headers.get('content-type');
|
||||||
|
@ -90,7 +54,7 @@ async function handleSingleDownload(url, formData) {
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
|
|
||||||
if (contentType.includes('application/pdf') || contentType.includes('image/')) {
|
if (contentType.includes('application/pdf') || contentType.includes('image/')) {
|
||||||
return handleResponse(blob, filename, true);
|
return handleResponse(blob, filename, !isMulti);
|
||||||
} else {
|
} else {
|
||||||
return handleResponse(blob, filename);
|
return handleResponse(blob, filename);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +82,7 @@ function getFilenameFromContentDisposition(contentDisposition) {
|
||||||
async function handleJsonResponse(response) {
|
async function handleJsonResponse(response) {
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
const errorMessage = JSON.stringify(json, null, 2);
|
const errorMessage = JSON.stringify(json, null, 2);
|
||||||
if (errorMessage.toLowerCase().includes('the password is incorrect') || errorMessage.toLowerCase().includes('Password is not provided')) {
|
if (errorMessage.toLowerCase().includes('the password is incorrect') || errorMessage.toLowerCase().includes('Password is not provided') || errorMessage.toLowerCase().includes('PDF contains an encryption dictionary')) {
|
||||||
alert('[[#{error.pdfPassword}]]');
|
alert('[[#{error.pdfPassword}]]');
|
||||||
} else {
|
} else {
|
||||||
showErrorBanner(json.error + ':' + json.message, json.trace);
|
showErrorBanner(json.error + ':' + json.message, json.trace);
|
||||||
|
@ -173,10 +137,15 @@ async function submitMultiPdfForm(url, files) {
|
||||||
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||||
const zipFiles = files.length > zipThreshold;
|
const zipFiles = files.length > zipThreshold;
|
||||||
let jszip = null;
|
let jszip = null;
|
||||||
//let progressBar = $('#progressBar');
|
// Show the progress bar
|
||||||
//progressBar.css('width', '0%');
|
$('#progressBarContainer').show();
|
||||||
//progressBar.attr('aria-valuenow', 0);
|
// Initialize the progress bar
|
||||||
//progressBar.attr('aria-valuemax', Array.from(files).length);
|
|
||||||
|
let progressBar = $('#progressBar');
|
||||||
|
progressBar.css('width', '0%');
|
||||||
|
progressBar.attr('aria-valuenow', 0);
|
||||||
|
progressBar.attr('aria-valuemax', files.length);
|
||||||
|
|
||||||
if (zipFiles) {
|
if (zipFiles) {
|
||||||
jszip = new JSZip();
|
jszip = new JSZip();
|
||||||
}
|
}
|
||||||
|
@ -202,20 +171,21 @@ async function submitMultiPdfForm(url, files) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const downloadDetails = await handleSingleDownload(url, fileFormData);
|
const downloadDetails = await handleSingleDownload(url, fileFormData, true);
|
||||||
console.log(downloadDetails);
|
console.log(downloadDetails);
|
||||||
if (zipFiles) {
|
if (zipFiles) {
|
||||||
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
||||||
} else {
|
} else {
|
||||||
downloadFile(downloadDetails.blob, downloadDetails.filename);
|
downloadFile(downloadDetails.blob, downloadDetails.filename);
|
||||||
}
|
}
|
||||||
//updateProgressBar(progressBar, Array.from(files).length);
|
updateProgressBar(progressBar, Array.from(files).length);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleDownloadError(error);
|
handleDownloadError(error);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zipFiles) {
|
if (zipFiles) {
|
||||||
|
@ -226,6 +196,8 @@ async function submitMultiPdfForm(url, files) {
|
||||||
console.error('Error generating ZIP file: ' + error);
|
console.error('Error generating ZIP file: ' + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
progressBar.css('width', '100%');
|
||||||
|
progressBar.attr('aria-valuenow', Array.from(files).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label>
|
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label>
|
||||||
<input type="text" class="form-control" id="pageOrder" name="pageOrder" placeholder="(e.g. 1,3,2 or 4-8,2,10-12)" required>
|
<input type="text" class="form-control" id="pageOrder" name="pageOrder" placeholder="(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
||||||
|
|
Loading…
Reference in a new issue