Compare commits

...

23 Commits

Author SHA1 Message Date
Anthony Stirling
31ac877612 Update build.gradle 2023-12-16 19:56:56 +00:00
Anthony Stirling
79dcf99cce Clean imports and lang updates 2023-12-16 19:30:47 +00:00
Anthony Stirling
c28a40ffe8 Split by sections #506 2023-12-16 19:29:43 +00:00
Anthony Stirling
12dccab460 auth log #522 2023-12-16 18:18:00 +00:00
Anthony Stirling
0a26e2e6d6 new deps 2023-12-16 10:42:27 +00:00
Anthony Stirling
74f6cd63f4 other JS changes 2023-12-16 10:35:45 +00:00
Anthony Stirling
e8de5739fa Resolve has Update button to stay hidden if error 2023-12-16 10:26:35 +00:00
Anthony Stirling
1b2734d99c login enable and security stuff 2023-12-16 10:22:33 +00:00
Anthony Stirling
206cf40cb5 Update Dockerfile-ultra-lite
login
2023-12-16 10:11:34 +00:00
Anthony Stirling
78473e96fd Update Dockerfile-lite
fix for #526 Support for login in lite
2023-12-16 10:08:09 +00:00
Anthony Stirling
b7d6ac2cc3 extra fonts, ocr display full names, overlay fixes 2023-12-12 23:25:56 +00:00
Anthony Stirling
4068d9530f svg 2023-12-11 23:24:13 +00:00
Anthony Stirling
8a331956c2 Merge branch 'main' of git@github.com:Frooodle/Stirling-PDF.git into main 2023-12-11 23:20:43 +00:00
Anthony Stirling
1d3e018a56 init overlay and auto split 2023-12-11 23:20:31 +00:00
Anthony Stirling
3602034938 Merge pull request #520 from NicolasFR/patch-1
Update messages_fr_FR.properties
2023-12-11 18:39:05 +00:00
NicolasFR
eb4e2d5fca Update messages_fr_FR.properties 2023-12-11 17:56:38 +01:00
Anthony Stirling
b6671939e5 Merge pull request #517 from NeilJared/es_ES
Update messages_es_ES.properties
2023-12-11 12:12:17 +00:00
Anthony Stirling
41d09e40a1 Merge branch 'main' into es_ES 2023-12-11 12:11:10 +00:00
Anthony Stirling
9b0dba7f65 Update account.html
#515 fix
2023-12-11 12:10:10 +00:00
NeilJared
ac0dc8b5c7 Update messages_es_ES.properties
Updated es_ES translation
2023-12-11 13:06:59 +01:00
Anthony Stirling
723216c693 Merge pull request #516 from Frooodle/Frooodle-patch-1
Update build.gradle
2023-12-11 11:02:45 +00:00
Anthony Stirling
46f9a5057f Update build.gradle 2023-12-11 11:01:48 +00:00
Anthony Stirling
8a2633ca93 Update build.gradle 2023-12-11 10:59:05 +00:00
55 changed files with 2006 additions and 136 deletions

View File

@@ -1,5 +1,5 @@
# Use the base image
FROM frooodle/stirling-pdf-base:version7
FROM frooodle/stirling-pdf-base:version8
ARG VERSION_TAG

View File

@@ -2,11 +2,11 @@
FROM bellsoft/liberica-openjdk-debian:17
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libreoffice-core-nogui \
libreoffice-core \
libreoffice-common \
libreoffice-writer-nogui \
libreoffice-calc-nogui \
libreoffice-impress-nogui \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
unoconv && \
rm -rf /var/lib/apt/lists/*
@@ -50,5 +50,5 @@ ENV DOCKER_ENABLE_SECURITY=false
# Run the application
#USER stirlingpdfuser
ENTRYPOINT ["/scripts/init.sh"]
CMD ["java", "-jar", "/app.jar"]

View File

@@ -2,33 +2,36 @@
FROM bellsoft/liberica-openjdk-alpine:17
# Set Environment Variables
ENV PUID=1000 \
PGID=1000 \
UMASK=022 \
DOCKER_ENABLE_SECURITY=false \
ENV DOCKER_ENABLE_SECURITY=false \
HOME=/home/stirlingpdfuser \
VERSION_TAG=$VERSION_TAG
VERSION_TAG=$VERSION_TAG
# PUID=1000 \
# PGID=1000 \
# UMASK=022 \
# Create user and group using Alpine's addgroup and adduser
RUN addgroup -g $PGID stirlingpdfgroup && \
adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \
mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
#RUN addgroup -g $PGID stirlingpdfgroup && \
# adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \
# mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
# Set up necessary directories and permissions
RUN mkdir -p /scripts /configs /customFiles && \
chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles
#RUN mkdir -p /scripts /configs /customFiles && \
# chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles
COPY build/libs/*.jar app.jar
# Set font cache and permissions
RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar
#RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar
# Expose the application port
EXPOSE 8080
# Set environment variables
ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI
ENV DOCKER_ENABLE_SECURITY=false
ENTRYPOINT ["/scripts/init.sh"]
# Run the application
CMD ["java", "-jar", "/app.jar"]

View File

@@ -11,11 +11,11 @@ RUN apt-get update && \
# Doc conversion
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libreoffice-core-nogui \
libreoffice-core \
libreoffice-common \
libreoffice-writer-nogui \
libreoffice-calc-nogui \
libreoffice-impress-nogui \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
python3-uno \
curl \
unoconv

View File

@@ -115,6 +115,7 @@ docker run -d \
-p 8080:8080 \
-v /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata \
-v /location/of/extraConfigs:/configs \
-v /location/of/logs:/logs \
-e DOCKER_ENABLE_SECURITY=false \
--name stirling-pdf \
frooodle/s-pdf:latest
@@ -136,6 +137,7 @@ services:
- /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata #Required for extra OCR languages
- /location/of/extraConfigs:/configs
# - /location/of/customFiles:/customFiles/
# - /location/of/logs:/logs/
environment:
- DOCKER_ENABLE_SECURITY=false
```

View File

@@ -8,7 +8,7 @@ plugins {
}
group = 'stirling.software'
version = '0.16.1'
version = '0.17.0'
sourceCompatibility = '17'
repositories {
@@ -63,18 +63,23 @@ launch4j {
}
dependencies {
//security updates
implementation 'ch.qos.logback:logback-classic:1.4.14'
implementation 'ch.qos.logback:logback-core:1.4.14'
implementation 'org.springframework:spring-webmvc:6.0.15'
implementation 'org.yaml:snakeyaml:2.1'
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.1.2'
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.6'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.1.6'
if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') {
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.2'
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.6'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
implementation "com.h2database:h2"
}
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.4'
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.6'
@@ -91,8 +96,8 @@ dependencies {
implementation group: 'com.opencsv', name: 'opencsv', version: '5.7.1'
implementation 'org.apache.pdfbox:pdfbox:2.0.29'
implementation 'org.apache.pdfbox:xmpbox:2.0.29'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-core'
implementation group: 'com.google.zxing', name: 'core', version: '3.5.2'

View File

@@ -1,6 +1,5 @@
package stirling.software.SPDF.config;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -16,6 +16,8 @@ public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationF
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
String ip = request.getRemoteAddr();
logger.error("Failed login attempt from IP: " + ip);
if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) {
setDefaultFailureUrl("/login?error=badcredentials");
} else if (exception.getClass().isAssignableFrom(LockedException.class)) {

View File

@@ -0,0 +1,121 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.pdfbox.multipdf.Overlay;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.MediaType;
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.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.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
public class PdfOverlayController {
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
@Operation(summary = "Overlay PDF files in various modes", description = "Overlay PDF files onto a base PDF with different modes: Sequential, Interleaved, or Fixed Repeat. Input:PDF Output:PDF Type:MIMO")
public ResponseEntity<byte[]> overlayPdfs(@ModelAttribute OverlayPdfsRequest request) throws IOException {
MultipartFile baseFile = request.getFileInput();
int overlayPos = request.getOverlayPosition();
MultipartFile[] overlayFiles = request.getOverlayFiles();
File[] overlayPdfFiles = new File[overlayFiles.length];
try{
for (int i = 0; i < overlayFiles.length; i++) {
overlayPdfFiles[i] = GeneralUtils.multipartToFile(overlayFiles[i]);
}
String mode = request.getOverlayMode(); // "SequentialOverlay", "InterleavedOverlay", "FixedRepeatOverlay"
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
try (PDDocument basePdf = PDDocument.load(baseFile.getInputStream());
Overlay overlay = new Overlay()) {
Map<Integer, String> overlayGuide = prepareOverlayGuide(basePdf.getNumberOfPages(), overlayPdfFiles, mode, counts);
overlay.setInputPDF(basePdf);
if(overlayPos == 0) {
overlay.setOverlayPosition(Overlay.Position.FOREGROUND);
} else {
overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
overlay.overlay(overlayGuide).save(outputStream);
byte[] data = outputStream.toByteArray();
return WebResponseUtils.bytesToWebResponse(data, "overlaid.pdf", MediaType.APPLICATION_PDF);
}
} finally {
for (File overlayPdfFile : overlayPdfFiles) {
if (overlayPdfFile != null) overlayPdfFile.delete();
}
}
}
private Map<Integer, String> prepareOverlayGuide(int basePageCount, File[] overlayFiles, String mode, int[] counts) throws IOException {
Map<Integer, String> overlayGuide = new HashMap<>();
switch (mode) {
case "SequentialOverlay":
sequentialOverlay(overlayGuide, overlayFiles, basePageCount);
break;
case "InterleavedOverlay":
interleavedOverlay(overlayGuide, overlayFiles, basePageCount);
break;
case "FixedRepeatOverlay":
fixedRepeatOverlay(overlayGuide, overlayFiles, counts, basePageCount);
break;
default:
throw new IllegalArgumentException("Invalid overlay mode");
}
return overlayGuide;
}
private void sequentialOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException {
int currentPage = 1;
for (File overlayFile : overlayFiles) {
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) {
for (int i = 0; i < overlayPdf.getNumberOfPages(); i++) {
if (currentPage > basePageCount) break;
overlayGuide.put(currentPage++, overlayFile.getAbsolutePath());
}
}
}
}
private void interleavedOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException {
for (int i = 0; i < basePageCount; i++) {
File overlayFile = overlayFiles[i % overlayFiles.length];
overlayGuide.put(i + 1, overlayFile.getAbsolutePath());
}
}
private void fixedRepeatOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int[] counts, int basePageCount) throws IOException {
if (overlayFiles.length != counts.length) {
throw new IllegalArgumentException("Counts array length must match the number of overlay files");
}
int currentPage = 1;
for (int i = 0; i < overlayFiles.length; i++) {
File overlayFile = overlayFiles[i];
int repeatCount = counts[i];
for (int j = 0; j < repeatCount; j++) {
if (currentPage > basePageCount) break;
overlayGuide.put(currentPage++, overlayFile.getAbsolutePath());
}
}
}
}
// Additional classes like OverlayPdfsRequest, WebResponseUtils, etc. are assumed to be defined elsewhere.

View File

@@ -12,13 +12,10 @@ 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.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.SortTypes;
import stirling.software.SPDF.model.api.PDFWithPageNums;

View File

@@ -0,0 +1,134 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.multipdf.LayerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix;
import org.springframework.http.MediaType;
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.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "Misc", description = "Miscellaneous APIs")
public class SplitPdfBySectionsController {
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
@Operation(summary = "Split PDF pages into smaller sections", description = "Split each page of a PDF into smaller sections based on the user's choice (halves, thirds, quarters, etc.), both vertically and horizontally. Input: PDF, Split Parameters. Output: ZIP containing split documents.")
public ResponseEntity<byte[]> splitPdf(@ModelAttribute SplitPdfBySectionsRequest request) throws Exception {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
MultipartFile file = request.getFileInput();
PDDocument sourceDocument = PDDocument.load(file.getInputStream());
// Process the PDF based on split parameters
int horiz = request.getHorizontalDivisions();
int verti = request.getVerticalDivisions();
List<PDDocument> splitDocuments = splitPdfPages(sourceDocument, horiz, verti);
for (PDDocument doc : splitDocuments) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
doc.close();
splitDocumentsBoas.add(baos);
}
sourceDocument.close();
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = file.getOriginalFilename().replaceFirst("[.][^.]+$", "");
byte[] data;
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
int pageNum = 1;
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
int sectionNum = (i % (horiz * verti)) + 1;
String fileName = filename + "_" + pageNum + "_" + sectionNum + ".pdf";
byte[] pdf = baos.toByteArray();
ZipEntry pdfEntry = new ZipEntry(fileName);
zipOut.putNextEntry(pdfEntry);
zipOut.write(pdf);
zipOut.closeEntry();
if (sectionNum == horiz * verti) pageNum++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
data = Files.readAllBytes(zipFile);
Files.delete(zipFile);
}
return WebResponseUtils.bytesToWebResponse(data, filename + "_split.zip", MediaType.APPLICATION_OCTET_STREAM);
}
public List<PDDocument> splitPdfPages(PDDocument document, int horizontalDivisions, int verticalDivisions) throws IOException {
List<PDDocument> splitDocuments = new ArrayList<>();
for (PDPage originalPage : document.getPages()) {
PDRectangle originalMediaBox = originalPage.getMediaBox();
float width = originalMediaBox.getWidth();
float height = originalMediaBox.getHeight();
float subPageWidth = width / horizontalDivisions;
float subPageHeight = height / verticalDivisions;
LayerUtility layerUtility = new LayerUtility(document);
for (int i = 0; i < horizontalDivisions; i++) {
for (int j = 0; j < verticalDivisions; j++) {
PDDocument subDoc = new PDDocument();
PDPage subPage = new PDPage(new PDRectangle(subPageWidth, subPageHeight));
subDoc.addPage(subPage);
PDFormXObject form = layerUtility.importPageAsForm(document, document.getPages().indexOf(originalPage));
try (PDPageContentStream contentStream = new PDPageContentStream(subDoc, subPage)) {
// Set clipping area and position
float translateX = -subPageWidth * i;
float translateY = height - subPageHeight * (j + 1) - subPageHeight;
contentStream.saveGraphicsState();
contentStream.addRect(0, 0, subPageWidth, subPageHeight);
contentStream.clip();
contentStream.transform(new Matrix(1, 0, 0, 1, translateX, translateY));
// Draw the form
contentStream.drawForm(form);
contentStream.restoreGraphicsState();
}
splitDocuments.add(subDoc);
}
}
}
return splitDocuments;
}
}

View File

@@ -0,0 +1,153 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.springframework.http.MediaType;
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.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.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "Misc", description = "Miscellaneous APIs")
public class SplitPdfBySizeController {
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
@Operation(summary = "Auto split PDF pages into separate documents based on size or count", description = "split PDF into multiple paged documents based on size/count, ie if 20 pages and split into 5, it does 5 documents each 4 pages\r\n"
+ " if 10MB and each page is 1MB and you enter 2MB then 5 docs each 2MB (rounded so that it accepts 1.9MB but not 2.1MB) Input:PDF Output:ZIP Type:SIMO")
public ResponseEntity<byte[]> autoSplitPdf(@ModelAttribute SplitPdfBySizeOrCountRequest request) throws Exception {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<ByteArrayOutputStream>();
MultipartFile file = request.getFileInput();
PDDocument sourceDocument = PDDocument.load(file.getInputStream());
//0 = size, 1 = page count, 2 = doc count
int type = request.getSplitType();
String value = request.getSplitValue();
if (type == 0) { // Split by size
long maxBytes = GeneralUtils.convertSizeToBytes(value);
long currentSize = 0;
PDDocument currentDoc = new PDDocument();
for (PDPage page : sourceDocument.getPages()) {
ByteArrayOutputStream pageOutputStream = new ByteArrayOutputStream();
PDDocument tempDoc = new PDDocument();
tempDoc.addPage(page);
tempDoc.save(pageOutputStream);
tempDoc.close();
long pageSize = pageOutputStream.size();
if (currentSize + pageSize > maxBytes) {
// Save and reset current document
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
currentDoc = new PDDocument();
currentSize = 0;
}
currentDoc.addPage(page);
currentSize += pageSize;
}
// Add the last document if it contains any pages
if (currentDoc.getPages().getCount() != 0) {
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else if (type == 1) { // Split by page count
int pageCount = Integer.parseInt(value);
int currentPageCount = 0;
PDDocument currentDoc = new PDDocument();
for (PDPage page : sourceDocument.getPages()) {
currentDoc.addPage(page);
currentPageCount++;
if (currentPageCount == pageCount) {
// Save and reset current document
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
currentDoc = new PDDocument();
currentPageCount = 0;
}
}
// Add the last document if it contains any pages
if (currentDoc.getPages().getCount() != 0) {
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else if (type == 2) { // Split by doc count
int documentCount = Integer.parseInt(value);
int totalPageCount = sourceDocument.getNumberOfPages();
int pagesPerDocument = totalPageCount / documentCount;
int extraPages = totalPageCount % documentCount;
int currentPageIndex = 0;
for (int i = 0; i < documentCount; i++) {
PDDocument currentDoc = new PDDocument();
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
for (int j = 0; j < pagesToAdd; j++) {
currentDoc.addPage(sourceDocument.getPage(currentPageIndex++));
}
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else {
throw new IllegalArgumentException("Invalid argument for split type");
}
sourceDocument.close();
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = 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) {
e.printStackTrace();
} finally {
data = Files.readAllBytes(zipFile);
Files.delete(zipFile);
}
return WebResponseUtils.bytesToWebResponse(data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
}
private ByteArrayOutputStream currentDocToByteArray(PDDocument document) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
document.close();
return baos;
}
}

View File

@@ -1,8 +1,10 @@
package stirling.software.SPDF.controller.api.converters;
import com.opencsv.CSVWriter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger;
@@ -11,18 +13,19 @@ import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
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 com.opencsv.CSVWriter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.controller.api.CropController;
import stirling.software.SPDF.controller.api.strippers.PDFTableStripper;
import stirling.software.SPDF.model.api.extract.PDFFilePage;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api/v1/convert")
@Tag(name = "General", description = "General APIs")

View File

@@ -1,14 +1,12 @@
package stirling.software.SPDF.controller.api.misc;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

View File

@@ -1,5 +1,19 @@
package stirling.software.SPDF.controller.api.strippers;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
@@ -9,16 +23,6 @@ import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.apache.pdfbox.text.TextPosition;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import java.util.*;
/**
*
* Class to extract tabular data from a PDF.

View File

@@ -1,9 +1,19 @@
package stirling.software.SPDF.controller.web;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -12,14 +22,11 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
@Controller
@Tag(name = "General", description = "General APIs")
@@ -74,6 +81,13 @@ public class GeneralWebController {
model.addAttribute("currentPage", "merge-pdfs");
return "merge-pdfs";
}
@GetMapping("/split-pdf-by-sections")
@Hidden
public String splitPdfBySections(Model model) {
model.addAttribute("currentPage", "split-pdf-by-sections");
return "split-pdf-by-sections";
}
@GetMapping("/view-pdf")
@Hidden
@@ -155,6 +169,20 @@ public class GeneralWebController {
return "scale-pages";
}
@GetMapping("/split-by-size-or-count")
@Hidden
public String splitBySizeOrCount(Model model) {
model.addAttribute("currentPage", "split-by-size-or-count");
return "split-by-size-or-count";
}
@GetMapping("/overlay-pdf")
@Hidden
public String overlayPdf(Model model) {
model.addAttribute("currentPage", "overlay-pdf");
return "overlay-pdf";
}
@Autowired

View File

@@ -98,7 +98,7 @@ public class OtherWebController {
return modelAndView;
}
@GetMapping("/add-image")
@Hidden
public String overlayImage(Model model) {

View File

@@ -0,0 +1,16 @@
package stirling.software.SPDF.model.api;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper=true)
public class SplitPdfBySectionsRequest extends PDFFile {
@Schema(description = "Number of horizontal divisions for each PDF page", example = "2")
private int horizontalDivisions;
@Schema(description = "Number of vertical divisions for each PDF page", example = "2")
private int verticalDivisions;
}

View File

@@ -0,0 +1,24 @@
package stirling.software.SPDF.model.api.general;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper = true)
public class OverlayPdfsRequest extends PDFFile {
@Schema(description = "An array of PDF files to be used as overlays on the base PDF. The order in these files is applied based on the selected mode.")
private MultipartFile[] overlayFiles;
@Schema(description = "The mode of overlaying: 'SequentialOverlay' for sequential application, 'InterleavedOverlay' for round-robin application, 'FixedRepeatOverlay' for fixed repetition based on provided counts", required = true)
private String overlayMode;
@Schema(description = "An array of integers specifying the number of times each corresponding overlay file should be applied in the 'FixedRepeatOverlay' mode. This should match the length of the overlayFiles array.", required = false)
private int[] counts;
@Schema(description = "Overlay position 0 is Foregound, 1 is Background")
private int overlayPosition;
}

View File

@@ -3,7 +3,6 @@ package stirling.software.SPDF.model.api.general;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.model.api.PDFWithPageSize;
@Data

View File

@@ -0,0 +1,18 @@
package stirling.software.SPDF.model.api.general;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper=true)
public class SplitPdfBySizeOrCountRequest extends PDFFile {
@Schema(description = "Determines the type of split: 0 for size, 1 for page count, 2 for document count", required = false, defaultValue = "0")
private int splitType;
@Schema(description = "Value for split: size in MB (e.g., '10MB') or number of pages (e.g., '5')", required = false, defaultValue = "10MB")
private String splitValue;
}

View File

@@ -1,6 +1,9 @@
package stirling.software.SPDF.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitResult;
@@ -12,6 +15,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class GeneralUtils {
public static void deleteDirectory(Path path) throws IOException {
@@ -48,6 +52,18 @@ public class GeneralUtils {
}
}
public static File multipartToFile(MultipartFile multipart) throws IOException {
Path tempFile = Files.createTempFile("overlay-", ".pdf");
try (InputStream in = multipart.getInputStream();
FileOutputStream out = new FileOutputStream(tempFile.toFile())) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile.toFile();
}
public static Long convertSizeToBytes(String sizeStr) {
if (sizeStr == null) {

View File

@@ -1,8 +0,0 @@
log4j.rootLogger=ERROR,stdout
log4j.logger.com.endeca=INFO
# Logger for crawl metrics
log4j.logger.com.endeca.itl.web.metrics=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n

View File

@@ -0,0 +1,51 @@
<configuration>
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Rolling File Appender -->
<appender name="AUTHLOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/invalid-auths.log</file>
<encoder>
<pattern>%d %p %c{1} [%thread] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover and keep 7 days' worth of history -->
<fileNamePattern>auth-%d{MM-dd-yyyy}.log</fileNamePattern>
<maxHistory>1</maxHistory>
</rollingPolicy>
</appender>
<!-- Rolling File Appender -->
<appender name="GENERAL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/info.log</file>
<encoder>
<pattern>%d %p %c{1} [%thread] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover and keep 7 days' worth of history -->
<fileNamePattern>info-%d{MM-dd-yyyy}.log</fileNamePattern>
<maxHistory>1</maxHistory>
</rollingPolicy>
</appender>
<!-- Root Logger -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="GENERAL"/>
</root>
<!-- Specific Logger -->
<logger name="stirling.software.SPDF.config.security.CustomAuthenticationFailureHandler" level="ERROR" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="AUTHLOG"/>
</logger>
</configuration>

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=??????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=????????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extracte
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=Tabelle extrahieren
home.tableExtraxt.desc=Tabelle aus PDF in CSV extrahieren
tableExtraxt.tags=CSV
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF zu CSV
PDFToCSV.header=PDF zu CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extrakt
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF ?? CSV
PDFToCSV.header=PDF ?? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=?????????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -832,4 +846,40 @@ PDFToXML.submit=Convert
PDFToCSV.title=PDF to CSV
PDFToCSV.header=PDF to CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF to CSV
PDFToCSV.header=PDF to CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -26,7 +26,7 @@ text=Texto
font=Fuente
selectFillter=-- Seleccionar --
pageNum=Número de página
sizes.small=Paqueño
sizes.small=Pequeño
sizes.medium=Mediano
sizes.large=Grande
sizes.x-large=Extra grande
@@ -44,7 +44,7 @@ blue=Azul
custom=Personalizado...
changedCredsMessage=Se cambiaron las credenciales!
notAuthenticatedMessage=Usuario njo autentificado.
notAuthenticatedMessage=Usuario no autentificado.
userNotFoundMessage=Usuario no encontrado.
incorrectPasswordMessage=La contraseña actual no es correcta.
usernameExistsMessage=El nuevo nombre de usuario está en uso.
@@ -70,8 +70,8 @@ settings.appVersion=Versión de la aplicación:
settings.downloadOption.title=Elegir la opción de descarga (para descargas de un solo archivo sin ZIP):
settings.downloadOption.1=Abrir en la misma ventana
settings.downloadOption.2=Abrir en una nueva ventana
settings.downloadOption.3=Descargar el fichero
settings.zipThreshold=Ficheros ZIP cuando excede el número de ficheros descargados
settings.downloadOption.3=Descargar el archivo
settings.zipThreshold=Archivos ZIP cuando excede el número de archivos descargados
settings.signOut=Desconectar
settings.accountSettings=Configuración de la cuenta
@@ -125,7 +125,7 @@ adminUserSettings.submit=Guardar Usuario
#############
# HOME-PAGE #
#############
home.desc=Su ventanilla única autohospedada para todas tus necesidades PDF
home.desc=Su ventanilla única autohospedada para todas sus necesidades PDF
home.searchBar=Buscar características...
@@ -164,12 +164,12 @@ pdfOrganiser.tags=doble cara,pares,impares,ordenar,mover
home.addImage.title=Agregar imagen al PDF
home.addImage.desc=Agregar una imagen en una ubicación establecida en el PDF (en desarrollo)
home.addImage.desc=Agregar una imagen en el PDF en una ubicación establecida (en desarrollo)
addImage.tags=img,jpg,imagen,fotografía
home.watermark.title=Añadir marca de agua
home.watermark.desc=Añadir una marca de agua predefinida al documento PDF
watermark.tags=Texto,repetir,etiquetar,propietario,copyight,marca comercial,img,jpg,imagen,fotografía
watermark.tags=Texto,repetir,etiquetar,propietario,copyright,marca comercial,img,jpg,imagen,fotografía
home.permissions.title=Cambiar permisos
home.permissions.desc=Cambiar los permisos del documento PDF
@@ -189,7 +189,7 @@ home.removePassword.desc=Eliminar la contraseña del documento PDF
removePassword.tags=seguro,Desencriptar,seguridad,quitar contraseña,eliminar contraseña
home.compressPdfs.title=Comprimir
home.compressPdfs.desc=Comprimir PDFs para reducir el tamaño del fichero
home.compressPdfs.desc=Comprimir PDFs para reducir el tamaño del archivo
compressPdfs.tags=aplastar,pequeño,diminuto
@@ -197,7 +197,7 @@ home.changeMetadata.title=Cambiar metadatos
home.changeMetadata.desc=Cambiar/Eliminar/Añadir metadatos al documento PDF
changeMetadata.tags==Título,autor,fecha,creación,hora,editorial,productor,estadísticas
home.fileToPDF.title=Convertir fichero a PDF
home.fileToPDF.title=Convertir archivo a PDF
home.fileToPDF.desc=Convertir casi cualquier archivo a PDF (DOCX, PNG, XLS, PPT, TXT y más)
fileToPDF.tags=transformación,formato,documento,imagen,diapositiva,texto,conversión,office,docs,word,excel,powerpoint
@@ -301,7 +301,7 @@ sanitizePdf.tags=limpiar,asegurar,seguro,quitar amenazas
home.URLToPDF.title=URL/Página web a PDF
home.URLToPDF.desc=Convierte cualquier dirección http(s) a PDF
URLToPDF.tags=captura web,guardar página,web-a-documento,archivo
URLToPDF.tags=captura web,guardar página,web a documento,archivo
home.HTMLToPDF.title=HTML a PDF
home.HTMLToPDF.desc=Convierte cualquier archivo HTML o ZIP a PDF
@@ -336,9 +336,23 @@ home.autoRedact.title=Auto Redactar
home.autoRedact.desc=Redactar automáticamente (ocultar) texto en un PDF según el texto introducido
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.tableExtraxt.title=PDF a CSV
home.tableExtraxt.desc=Extraer Tablas de un PDF convirtiéndolas a CSV
tableExtraxt.tags=CSV,Extraer tabla,extraer,convertir
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
@@ -363,7 +377,7 @@ autoRedact.textsToRedactPlaceholder=por ej. \nConfidencial \nAlto-Secreto
autoRedact.useRegexLabel=Usar Regex
autoRedact.wholeWordSearchLabel=Búsqueda por palabra completa
autoRedact.customPaddingLabel=Extra Padding personalizado
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen-PDF (Utilizado para quitar el texto detrás del cajetín)
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen PDF (Utilizado para quitar el texto detrás del cajetín)
autoRedact.submitButton=Enviar
@@ -412,7 +426,7 @@ URLToPDF.credit=Utiliza WeasyPrint
#html-to-pdf
HTMLToPDF.title=HTML a PDF
HTMLToPDF.header=HTML a PDF
HTMLToPDF.help=Acepta archivos HTML y ZIPs conteniendo los html/css/imágenes etc requeridas
HTMLToPDF.help=Acepta archivos HTML y ZIPs conteniendo los html/css/imágenes, etc, requeridas
HTMLToPDF.submit=Convertir
HTMLToPDF.credit=Utiliza WeasyPrint
@@ -438,7 +452,7 @@ addPageNumbers.selectText.4=Número de inicio
addPageNumbers.selectText.5=Páginas a numerar
addPageNumbers.selectText.6=Texto personalizado
addPageNumbers.customTextDesc=Texto personalizado
addPageNumbers.numberPagesDesc=Qué páginas numerar, por defecto 'all', también acepta 1-5 o 2,5,9 etc
addPageNumbers.numberPagesDesc=Qué páginas numerar, por defecto 'todas', también acepta 1-5 o 2,5,9 etc
addPageNumbers.customNumberDesc=Por defecto a {n}, también acepta 'Página {n} de {total}', 'Texto-{n}', '{filename}-{n}
addPageNumbers.submit=Añadir Números de Página
@@ -474,8 +488,8 @@ autoSplitPDF.selectText.3=Cargue un único archivo PDF escaneado de gran tamaño
autoSplitPDF.selectText.4=Las páginas divisorias son automáticamente detectadas y eliminadas, garantizando un buen documento final.
autoSplitPDF.formPrompt=Entregar PDF conteniendo divisores de página de Stirling-PDF:
autoSplitPDF.duplexMode=Modo Dúplex (Escaneado de ambas caras)
autoSplitPDF.dividerDownload1=Descargar 'Auto Splitter Divider (mínima).pdf'
autoSplitPDF.dividerDownload2=Descargar 'Auto Splitter Divider (con instrucciones).pdf'
autoSplitPDF.dividerDownload1=Descargar 'Divisor automático (mínima).pdf'
autoSplitPDF.dividerDownload2=Descargar 'Divisor automático (con instrucciones).pdf'
autoSplitPDF.submit=Entregar
@@ -500,7 +514,7 @@ scalePages.submit=Entregar
#certSign
certSign.title=Firma de certificado
certSign.title=Firma con certificado
certSign.header=Firmar un PDF con su certificado (en desarrollo)
certSign.selectPDF=Seleccione un archivo PDF para firmar:
certSign.selectKey=Seleccione su archivo de clave privada (formato PKCS#8, podría ser .pem o .der):
@@ -562,7 +576,7 @@ ScannerImageSplit.selectText.3=Tolerancia:
ScannerImageSplit.selectText.4=Determinar el rango de variación de color alrededor del color de fondo estimado (predeterminado: 30).
ScannerImageSplit.selectText.5=Área mínima:
ScannerImageSplit.selectText.6=Establecer el umbral mínimo de área para una foto (predeterminado: 10000).
ScannerImageSplit.selectText.7=Área de contorno mínima:
ScannerImageSplit.selectText.7=Área mínima de contorno:
ScannerImageSplit.selectText.8=Establecer el umbral mínimo del área de contorno para una foto
ScannerImageSplit.selectText.9=Tamaño del borde:
ScannerImageSplit.selectText.10=Establece el tamaño del borde agregado y eliminado para evitar bordes blancos en la salida (predeterminado: 1).
@@ -598,8 +612,8 @@ extractImages.submit=Extraer
#File to PDF
fileToPDF.title=Archivo a PDF
fileToPDF.header=Convertir cualquier archivo a PDF
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de ficheros
fileToPDF.supportedFileTypes=Los tipos de ficheros soportados deben incluir los de abajo; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de archivos
fileToPDF.supportedFileTypes=Los tipos de archivo soportados deben incluir los indicados a continuación; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
fileToPDF.submit=Convertir a PDF
@@ -719,8 +733,8 @@ addPassword.selectText.11=Impedir modificación de anotaciones
addPassword.selectText.12=Impedir imprimir
addPassword.selectText.13=Impedir imprimir diferentes formatos
addPassword.selectText.14=Contraseña
addPassword.selectText.15=Restringe qué se puede hacer con el documento una vez abierto (no soportado por todos los lectores)
addPassword.selectText.16=Restringe la apertura del propio documento
addPassword.selectText.15=Restringir qué se puede hacer con el documento una vez abierto (no soportado por todos los lectores)
addPassword.selectText.16=Restringir la apertura del propio documento
addPassword.submit=Encriptar
@@ -831,5 +845,41 @@ PDFToXML.submit=Convertir
#PDFToCSV
PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extracto
PDFToCSV.prompt=Elija una página para extraer la tabla
PDFToCSV.submit=Extraer
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extracto
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -129,9 +129,9 @@ home.desc=Votre application Web hébergée localement pour répondre à tous vos
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.viewPdf.title=Visionner le PDF
home.viewPdf.desc=Visionner, annoter, ajouter du texte ou des images
viewPdf.tags=visualiser,lire,annoter,texte,image
home.multiTool.title=Outil multifonction PDF
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF en CSV
PDFToCSV.header=PDF en CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extrait
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=Da PDF a CSV
PDFToCSV.header=Da PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Estratto
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF??CSV?
PDFToCSV.header=PDF??CSV?
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF? CSV?
PDFToCSV.header=PDF? CSV?
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=??
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF naar CSV
PDFToCSV.header=PDF naar CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF na CSV
PDFToCSV.header=PDF na CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Wyci?g
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF ? CSV
PDFToCSV.header=PDF ? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=???????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF till CSV
PDFToCSV.header=PDF till CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Navvit
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF to CSV
PDFToCSV.header=PDF to CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -340,6 +340,20 @@ home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -833,3 +847,39 @@ PDFToCSV.title=PDF ? CSV
PDFToCSV.header=PDF ? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=??
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-layers" viewBox="0 0 16 16">
<path d="M8.235 1.559a.5.5 0 0 0-.47 0l-7.5 4a.5.5 0 0 0 0 .882L3.188 8 .264 9.559a.5.5 0 0 0 0 .882l7.5 4a.5.5 0 0 0 .47 0l7.5-4a.5.5 0 0 0 0-.882L12.813 8l2.922-1.559a.5.5 0 0 0 0-.882l-7.5-4zm3.515 7.008L14.438 10 8 13.433 1.562 10 4.25 8.567l3.515 1.874a.5.5 0 0 0 .47 0l3.515-1.874zM8 9.433 1.562 6 8 2.567 14.438 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 458 B

View File

@@ -140,8 +140,11 @@ document.addEventListener("DOMContentLoaded", function () {
setMode("off")
}
document.getElementById("dark-mode-toggle").addEventListener("click", function (event) {
event.preventDefault()
toggleDarkMode()
})
var darkModeToggle = document.getElementById("dark-mode-toggle");
if (darkModeToggle !== null) {
darkModeToggle.addEventListener("click", function (event) {
event.preventDefault();
toggleDarkMode();
});
}
})

View File

@@ -16,26 +16,40 @@ function compareVersions(version1, version2) {
return 0;
}
async function getLatestReleaseVersion() {
const url = "https://api.github.com/repos/Frooodle/Stirling-PDF/releases/latest";
const response = await fetch(url);
const data = await response.json();
return data.tag_name.substring(1);
}
async function getLatestReleaseVersion() {
const url = "https://api.github.com/repos/Frooodle/Stirling-PDF/releases/latest";
try {
const response = await fetch(url);
const data = await response.json();
return data.tag_name ? data.tag_name.substring(1) : "";
} catch (error) {
console.error("Failed to fetch latest version:", error);
return ""; // Return an empty string if the fetch fails
}
}
async function checkForUpdate() {
const latestVersion = await getLatestReleaseVersion();
console.log("latestVersion=" + latestVersion)
console.log("currentVersion=" + currentVersion)
console.log("compareVersions(latestVersion, currentVersion) > 0)=" + compareVersions(latestVersion, currentVersion))
if (latestVersion != null && latestVersion != "" && compareVersions(latestVersion, currentVersion) > 0) {
document.getElementById("update-btn").style.display = "block";
console.log("visible")
} else {
document.getElementById("update-btn").style.display = "none";
console.log("hidden")
// Initialize the update button as hidden
var updateBtn = document.getElementById("update-btn");
if (updateBtn !== null) {
updateBtn.style.display = "none";
}
const latestVersion = await getLatestReleaseVersion();
console.log("latestVersion=" + latestVersion)
console.log("currentVersion=" + currentVersion)
console.log("compareVersions(latestVersion, currentVersion) > 0)=" + compareVersions(latestVersion, currentVersion))
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
document.getElementById("update-btn").style.display = "block";
console.log("visible")
} else {
console.log("hidden")
}
}
checkForUpdate();
document.addEventListener('DOMContentLoaded', (event) => {
checkForUpdate();
});

View File

@@ -275,7 +275,7 @@
document.getElementById('syncToAccount').addEventListener('click', function() {
let form = document.createElement("form");
form.method = "POST";
form.action = "/updateUserSettings"; // Your endpoint URL
form.action = "api/v1/user/updateUserSettings"; // Your endpoint URL
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);

View File

@@ -59,8 +59,9 @@
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('crop', 'images/crop.svg', 'home.crop.title', 'home.crop.desc', 'crop.tags')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('extract-page', 'images/extract.svg', 'home.extractPage.title', 'home.extractPage.desc', 'extractPage.tags')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-single-page', 'images/single-page.svg', 'home.PdfToSinglePage.title', 'home.PdfToSinglePage.desc', 'PdfToSinglePage.tags')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'split-by-size-or-count', 'images/layout-split.svg', 'home.autoSizeSplitPDF.title', 'home.autoSizeSplitPDF.desc', 'autoSizeSplitPDF.tags')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'overlay-pdf', 'images/overlay.svg', 'home.overlay-pdfs.title', 'home.overlay-pdfs.desc', 'overlay-pdfs.tags')}"></div>
<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'split-pdf-by-sections', 'images/layout-split.svg', 'home.split-by-sections.title', 'home.split-by-sections.desc', 'split-by-sections.tags')}"></div>
</div>
</li>
<li class="nav-item nav-item-separator"></li>

View File

@@ -94,8 +94,11 @@
<div th:replace="~{fragments/card :: card(id='auto-redact', cardTitle=#{home.autoRedact.title}, cardText=#{home.autoRedact.desc}, cardLink='auto-redact', svgPath='images/eraser-fill.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='pdf-to-csv', cardTitle=#{home.tableExtraxt.title}, cardText=#{home.tableExtraxt.desc}, cardLink='pdf-to-csv', svgPath='images/pdf-csv.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='split-by-size-or-count', cardTitle=#{home.autoSizeSplitPDF.title}, cardText=#{home.autoSizeSplitPDF.desc}, cardLink='split-by-size-or-count', svgPath='images/layout-split.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='overlay-pdf', cardTitle=#{home.overlay-pdfs.title}, cardText=#{home.overlay-pdfs.desc}, cardLink='overlay-pdf', svgPath='images/overlay.svg')}"></div>
<div th:replace="~{fragments/card :: card(id='split-pdf-by-sections', cardTitle=#{home.split-by-sections.title}, cardText=#{home.split-by-sections.desc}, cardLink='split-pdf-by-sections', svgPath='images/layout-split.svg')}"></div>
</div>
</div> </div>

View File

@@ -46,7 +46,7 @@
<div id="languages">
<div th:each="language, iterStat : ${languages}">
<input type="checkbox" th:name="languages" th:value="${language}" required th:id="${'language-' + language}" onchange="handleLangSelection()" />
<label class="form-check-label" th:for="${'language-' + language}" th:text="${(language == 'eng') ? 'English' : language}"></label>
<label class="form-check-label" th:for="${'language-' + language}" th:text="${language}"></label>
</div>
</div>
<hr>
@@ -93,6 +93,154 @@
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{ocr.submit}"></button>
</form>
<script>
const languageMap = {
'afr': 'Afrikaans',
'amh': 'Amharic',
'ara': 'Arabic',
'asm': 'Assamese',
'aze': 'Azerbaijani',
'aze_cyrl': 'Azerbaijani (Cyrillic)',
'bel': 'Belarusian',
'ben': 'Bengali',
'bod': 'Tibetan',
'bos': 'Bosnian',
'bre': 'Breton',
'bul': 'Bulgarian',
'cat': 'Catalan',
'ceb': 'Cebuano',
'ces': 'Czech',
'chi_sim': 'Chinese (Simplified)',
'chi_sim_vert': 'Chinese (Simplified, Vertical)',
'chi_tra': 'Chinese (Traditional)',
'chi_tra_vert': 'Chinese (Traditional, Vertical)',
'chr': 'Cherokee',
'cos': 'Corsican',
'cym': 'Welsh',
'dan': 'Danish',
'dan_frak': 'Danish (Fraktur)',
'deu': 'German',
'deu_frak': 'German (Fraktur)',
'div': 'Divehi',
'dzo': 'Dzongkha',
'ell': 'Greek',
'eng': 'English',
'enm': 'English, Middle (1100-1500)',
'epo': 'Esperanto',
'equ': 'Math / equation detection module',
'est': 'Estonian',
'eus': 'Basque',
'fao': 'Faroese',
'fas': 'Persian',
'fil': 'Filipino',
'fin': 'Finnish',
'fra': 'French',
'frk': 'Frankish',
'frm': 'French, Middle (ca.1400-1600)',
'fry': 'Western Frisian',
'gla': 'Scottish Gaelic',
'gle': 'Irish',
'glg': 'Galician',
'grc': 'Ancient Greek',
'guj': 'Gujarati',
'hat': 'Haitian, Haitian Creole',
'heb': 'Hebrew',
'hin': 'Hindi',
'hrv': 'Croatian',
'hun': 'Hungarian',
'hye': 'Armenian',
'iku': 'Inuktitut',
'ind': 'Indonesian',
'isl': 'Icelandic',
'ita': 'Italian',
'ita_old': 'Italian (Old)',
'jav': 'Javanese',
'jpn': 'Japanese',
'jpn_vert': 'Japanese (Vertical)',
'kan': 'Kannada',
'kat': 'Georgian',
'kat_old': 'Georgian (Old)',
'kaz': 'Kazakh',
'khm': 'Central Khmer',
'kir': 'Kirghiz, Kyrgyz',
'kmr': 'Northern Kurdish',
'kor': 'Korean',
'kor_vert': 'Korean (Vertical)',
'lao': 'Lao',
'lat': 'Latin',
'lav': 'Latvian',
'lit': 'Lithuanian',
'ltz': 'Luxembourgish',
'mal': 'Malayalam',
'mar': 'Marathi',
'mkd': 'Macedonian',
'mlt': 'Maltese',
'mon': 'Mongolian',
'mri': 'Maori',
'msa': 'Malay',
'mya': 'Burmese',
'nep': 'Nepali',
'nld': 'Dutch; Flemish',
'nor': 'Norwegian',
'oci': 'Occitan (post 1500)',
'ori': 'Oriya',
'osd': 'Orientation and script detection module',
'pan': 'Panjabi, Punjabi',
'pol': 'Polish',
'por': 'Portuguese',
'pus': 'Pushto, Pashto',
'que': 'Quechua',
'ron': 'Romanian, Moldavian, Moldovan',
'rus': 'Russian',
'san': 'Sanskrit',
'sin': 'Sinhala, Sinhalese',
'slk': 'Slovak',
'slk_frak': 'Slovak (Fraktur)',
'slv': 'Slovenian',
'snd': 'Sindhi',
'spa': 'Spanish',
'spa_old': 'Spanish (Old)',
'sqi': 'Albanian',
'srp': 'Serbian',
'srp_latn': 'Serbian (Latin)',
'sun': 'Sundanese',
'swa': 'Swahili',
'swe': 'Swedish',
'syr': 'Syriac',
'tam': 'Tamil',
'tat': 'Tatar',
'tel': 'Telugu',
'tgk': 'Tajik',
'tgl': 'Tagalog',
'tha': 'Thai',
'tir': 'Tigrinya',
'ton': 'Tonga (Tonga Islands)',
'tur': 'Turkish',
'uig': 'Uighur, Uyghur',
'ukr': 'Ukrainian',
'urd': 'Urdu',
'uzb': 'Uzbek',
'uzb_cyrl': 'Uzbek (Cyrillic)',
'vie': 'Vietnamese',
'yid': 'Yiddish',
'yor': 'Yoruba'
};
// Step 2: Function to get the full language name
function getFullLanguageName(shortCode) {
return languageMap[shortCode] || shortCode;
}
// Step 3: Apply the function to your labels
document.addEventListener('DOMContentLoaded', () => {
const labels = document.querySelectorAll('#languages .form-check-label');
labels.forEach(label => {
const languageCode = label.getAttribute('for').split('-')[1];
label.textContent = getFullLanguageName(languageCode);
});
});
</script>
<p th:text="#{ocr.credit}"></p>
<p th:text="#{ocr.help}"></p>
<a href="https://github.com/Frooodle/Stirling-PDF/blob/main/HowToUseOCR.md">https://github.com/Frooodle/Stirling-PDF/blob/main/HowToUseOCR.md</a>

View File

@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{split-by-size-or-count.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{overlay-pdfs.header}"></h2>
<form id="overlayForm" method="post" enctype="multipart/form-data" th:action="@{/api/v1/general/overlay-pdfs}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div th:replace="~{fragments/common :: fileSelector(name='overlayFiles', multiple=true, accept='application/pdf')}"></div>
<label for="overlayMode" th:text="#{overlay-pdfs.mode.label}">Overlay Mode</label>
<select id="overlayMode" name="overlayMode" class="form-control">
<option value="SequentialOverlay" th:text="#{overlay-pdfs.mode.sequential}">Sequential Overlay</option>
<option value="InterleavedOverlay" th:text="#{overlay-pdfs.mode.interleaved}">Interleaved Overlay</option>
<option value="FixedRepeatOverlay" th:text="#{overlay-pdfs.mode.fixedRepeat}">Fixed Repeat Overlay</option>
</select>
<br>
<label for="overlayPosition" th:text="#{overlay-pdfs.position.label}">Overlay Position</label>
<select id="overlayPosition" name="overlayPosition" class="form-control">
<option value="0" th:text="#{overlay-pdfs.position.foreground}">Foreground</option>
<option value="1" th:text="#{overlay-pdfs.position.background}">Background</option>
</select>
<br>
<div id="countsContainer" style="display: none;">
<label th:text="#{overlay-pdfs.counts.label}">Overlay Counts</label>
<!-- Inputs for counts will be dynamically added here -->
</div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{overlay-pdfs.submit}">Submit</button>
</form>
<script>
function updateCountsInputs() {
const mode = document.getElementById('overlayMode').value;
console.log("mode",mode);
const countsContainer = document.getElementById('countsContainer');
console.log("countsContainer",countsContainer);
countsContainer.innerHTML = ''; // Clear previous inputs
if (mode === 'FixedRepeatOverlay') {
const fileInput = document.getElementById('overlayFiles-input');
console.log("fileInput",fileInput);
if(fileInput){
const files = fileInput.files
console.log("files",files);
if(files) {
const fileCount = files.length;
for (let i = 0; i < fileCount; i++) {
const input = document.createElement('input');
input.type = 'text';
input.name = 'counts';
input.classList.add('form-control');
input.placeholder = 'Count for file ' + (i + 1);
countsContainer.appendChild(input);
}
countsContainer.style.display = 'block';
}
}
} else {
countsContainer.style.display = 'none';
}
}
document.addEventListener('DOMContentLoaded', (event) => {
var fileInput = document.getElementById('overlayFiles-input');
console.log("fileInput2",fileInput);
if (fileInput) {
fileInput.addEventListener('change', updateCountsInputs);
}
});
document.addEventListener('DOMContentLoaded', (event) => {
var overlay = document.getElementById('overlayMode');
console.log("overlay2",overlay);
if (overlay) {
overlay.addEventListener('change', updateCountsInputs);
}
});
</script>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{split-by-size-or-count.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{split-by-size-or-count.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{/api/v1/general/split-by-size-or-count}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<label for="splitType" th:text="#{split-by-size-or-count.type.label}">Split Type</label>
<select id="splitType" name="splitType" class="form-control">
<option value="0" th:text="#{split-by-size-or-count.type.size}">Size</option>
<option value="1" th:text="#{split-by-size-or-count.type.pageCount}">Page Count</option>
<option value="2" th:text="#{split-by-size-or-count.type.docCount}">Document Count</option>
</select>
<br>
<label for="splitValue" th:text="#{split-by-size-or-count.value.label}">Split Value</label>
<input type="text" id="splitValue" name="splitValue" class="form-control" required th:placeholder="#{split-by-size-or-count.value.placeholder}">
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{split-by-size-or-count.submit}">Submit</button>
</form>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{split-by-sections.title})}"></th:block>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
<br> <br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 th:text="#{split-by-sections.header}"></h2>
<form method="post" enctype="multipart/form-data" th:action="@{/api/v1/general/split-pdf-by-sections}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<label for="horizontalDivisions" th:text="#{split-by-sections.horizontal.label}">Horizontal Divisions</label>
<input type="number" id="horizontalDivisions" name="horizontalDivisions" class="form-control" min="1" required th:placeholder="#{split-by-sections.horizontal.placeholder}">
<br>
<label for="verticalDivisions" th:text="#{split-by-sections.vertical.label}">Vertical Divisions</label>
<input type="number" id="verticalDivisions" name="verticalDivisions" class="form-control" min="1" required th:placeholder="#{split-by-sections.vertical.placeholder}">
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{split-by-sections.submit}">Submit</button>
</form>
</div>
</div>
</div>
</div>
<div th:insert="~{fragments/footer.html :: footer}"></div>
</div>
</body>
</html>