Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c311f9a4ed | ||
|
|
0a7517ecdd | ||
|
|
03febd9484 | ||
|
|
655b97bfd5 | ||
|
|
fdbc7f4621 | ||
|
|
f9fe303671 | ||
|
|
d4459eb6d6 | ||
|
|
9087a3ebbd | ||
|
|
56669f4247 | ||
|
|
22be1a1104 | ||
|
|
a80c585086 | ||
|
|
6d5dbd9729 | ||
|
|
0b4e3de455 | ||
|
|
8faef235a6 | ||
|
|
559bc7c731 | ||
|
|
3d7fdd0f35 | ||
|
|
726fcf861c | ||
|
|
839105f41d | ||
|
|
a2a27e2216 | ||
|
|
f866c8a61f | ||
|
|
472082cb03 | ||
|
|
b5a59ddb6a | ||
|
|
82da3c0027 | ||
|
|
908e75de39 |
49
Dockerfile
49
Dockerfile
@@ -1,46 +1,5 @@
|
|||||||
# Build jbig2enc in a separate stage
|
# Build jbig2enc in a separate stage
|
||||||
FROM debian:bullseye-slim as jbig2enc_builder
|
FROM frooodle/stirling-pdf-base:latest
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
git \
|
|
||||||
automake \
|
|
||||||
autoconf \
|
|
||||||
libtool \
|
|
||||||
libleptonica-dev \
|
|
||||||
pkg-config \
|
|
||||||
ca-certificates \
|
|
||||||
zlib1g-dev \
|
|
||||||
make \
|
|
||||||
g++
|
|
||||||
|
|
||||||
RUN git clone https://github.com/agl/jbig2enc && \
|
|
||||||
cd jbig2enc && \
|
|
||||||
./autogen.sh && \
|
|
||||||
./configure && \
|
|
||||||
make && \
|
|
||||||
make install
|
|
||||||
|
|
||||||
# Main stage
|
|
||||||
FROM openjdk:17-jdk-slim
|
|
||||||
|
|
||||||
# Install necessary dependencies
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
libreoffice-core \
|
|
||||||
libreoffice-common \
|
|
||||||
libreoffice-writer \
|
|
||||||
libreoffice-calc \
|
|
||||||
libreoffice-impress \
|
|
||||||
python3-uno \
|
|
||||||
python3-pip \
|
|
||||||
unoconv \
|
|
||||||
pngquant \
|
|
||||||
ocrmypdf && \
|
|
||||||
pip install --user --upgrade ocrmypdf
|
|
||||||
|
|
||||||
# Copy the jbig2enc binary from the builder stage
|
|
||||||
COPY --from=jbig2enc_builder /usr/local/bin/jbig2 /usr/local/bin/jbig2
|
|
||||||
|
|
||||||
# Copy the application JAR file
|
# Copy the application JAR file
|
||||||
COPY build/libs/*.jar app.jar
|
COPY build/libs/*.jar app.jar
|
||||||
@@ -49,10 +8,12 @@ COPY build/libs/*.jar app.jar
|
|||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV LOG_LEVEL=INFO
|
ENV APP_HOME_NAME="Stirling PDF"
|
||||||
|
#ENV APP_HOME_DESCRIPTION="Personal PDF Website!"
|
||||||
|
#ENV APP_NAVBAR_NAME="Stirling PDF"
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
ENTRYPOINT ["java","-jar","/app.jar","-Dlogging.level=${LOG_LEVEL}"]
|
ENTRYPOINT java -jar /app.jar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
44
DockerfileBase
Normal file
44
DockerfileBase
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Build jbig2enc in a separate stage
|
||||||
|
FROM debian:bullseye-slim as jbig2enc_builder
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git \
|
||||||
|
automake \
|
||||||
|
autoconf \
|
||||||
|
libtool \
|
||||||
|
libleptonica-dev \
|
||||||
|
pkg-config \
|
||||||
|
ca-certificates \
|
||||||
|
zlib1g-dev \
|
||||||
|
make \
|
||||||
|
g++
|
||||||
|
|
||||||
|
RUN git clone https://github.com/agl/jbig2enc && \
|
||||||
|
cd jbig2enc && \
|
||||||
|
./autogen.sh && \
|
||||||
|
./configure && \
|
||||||
|
make && \
|
||||||
|
make install
|
||||||
|
|
||||||
|
# Main stage
|
||||||
|
FROM openjdk:17-jdk-slim
|
||||||
|
|
||||||
|
# Install necessary dependencies
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
libreoffice-core \
|
||||||
|
libreoffice-common \
|
||||||
|
libreoffice-writer \
|
||||||
|
libreoffice-calc \
|
||||||
|
libreoffice-impress \
|
||||||
|
python3-uno \
|
||||||
|
python3-pip \
|
||||||
|
unoconv \
|
||||||
|
pngquant \
|
||||||
|
unpaper \
|
||||||
|
ocrmypdf && \
|
||||||
|
pip install --user --upgrade ocrmypdf
|
||||||
|
|
||||||
|
# Copy the jbig2enc binary from the builder stage
|
||||||
|
COPY --from=jbig2enc_builder /usr/local/bin/jbig2 /usr/local/bin/jbig2
|
||||||
39
README.md
39
README.md
@@ -7,16 +7,13 @@
|
|||||||
[](https://github.com/Frooodle/stirling-pdf)
|
[](https://github.com/Frooodle/stirling-pdf)
|
||||||
[](https://www.paypal.com/paypalme/froodleplex)
|
[](https://www.paypal.com/paypalme/froodleplex)
|
||||||
|
|
||||||
This is a locally hosted web application that allows you to perform various operations on PDF files, such as splitting and adding images.
|
This is a powerful locally hosted web based PDF manipulation tool using docker that allows you to perform various operations on PDF files, such as splitting merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application started as a 100% ChatGPT-made application and has evolved to include a wide range of features to handle all your PDF needs.
|
||||||
|
|
||||||
Started off as a 100% ChatGPT made application, slowly moving away from that as more features are added
|
Feel free to request any features of bug fixes either in github issues or our [Discord](https://discord.gg/Cn8pWhQRxZ)
|
||||||
|
|
||||||
I will support and fix/add things to this if there is a demand [Discord](https://discord.gg/Cn8pWhQRxZ)
|
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
|
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
|
||||||
@@ -25,17 +22,24 @@ I will support and fix/add things to this if there is a demand [Discord](https:/
|
|||||||
- Reorganize PDF pages into different orders.
|
- Reorganize PDF pages into different orders.
|
||||||
- Add images to PDFs at specified locations. (WIP)
|
- Add images to PDFs at specified locations. (WIP)
|
||||||
- Rotating PDFs in 90 degree increments.
|
- Rotating PDFs in 90 degree increments.
|
||||||
- Compressing PDFs to decrease their filesize.
|
- Compressing PDFs to decrease their filesize. (Using OCRMyPDF)
|
||||||
- Add and remove passwords
|
- Add and remove passwords
|
||||||
- Set PDF Permissions
|
- Set PDF Permissions
|
||||||
- Add watermark(s)
|
- Add watermark(s)
|
||||||
|
- Convert Any common file to PDF (using LibreOffice)
|
||||||
|
- Convert PDF to Word/Powerpoint/Others (using LibreOffice)
|
||||||
|
- Extract images from PDF
|
||||||
|
- OCR on PDF (Using OCRMyPDF)
|
||||||
- Edit metadata
|
- Edit metadata
|
||||||
- Dark mode support.
|
- Dark mode support.
|
||||||
|
- Custom download options (see [here](https://github.com/Frooodle/Stirling-PDF/blob/main/images/settings.png) for example)
|
||||||
|
- Parallel file processing and downloads
|
||||||
|
|
||||||
## Technologies used
|
## Technologies used
|
||||||
- Spring Boot + Thymeleaf
|
- Spring Boot + Thymeleaf
|
||||||
- PDFBox
|
- PDFBox
|
||||||
- e-iceblue spire.pdf.free (for PDF compression untill i find a nicer way)
|
- [LibreOffice](https://www.libreoffice.org/discover/libreoffice/) for advanced conversions
|
||||||
|
- [OcrMyPdf](https://github.com/ocrmypdf/OCRmyPDF)
|
||||||
- HTML, CSS, JavaScript
|
- HTML, CSS, JavaScript
|
||||||
- Docker
|
- Docker
|
||||||
|
|
||||||
@@ -69,9 +73,26 @@ services:
|
|||||||
image: frooodle/s-pdf
|
image: frooodle/s-pdf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Enable OCR/Compression feature
|
||||||
|
Please view https://github.com/Frooodle/Stirling-PDF/blob/main/HowToUseOCR.md
|
||||||
|
|
||||||
|
## Want to add your own language?
|
||||||
|
If you want to add your own language to Stirling-PDF please refer
|
||||||
|
https://github.com/Frooodle/Stirling-PDF/blob/main/HowToAddNewLanguage.md
|
||||||
|
|
||||||
|
And please create a PR to merge it back in so others can use it!
|
||||||
|
|
||||||
|
Also please note as i add new features i will google translate existing languages so that they dont lose support. This could mean that new features need grammer corrections as added.
|
||||||
|
|
||||||
## How to View
|
## How to View
|
||||||
1. Open a web browser and navigate to `http://localhost:8080/`
|
1. Open a web browser and navigate to `http://localhost:8080/`
|
||||||
2. Use the application by following the instructions on the website.
|
2. Use the application by following the instructions on the website.
|
||||||
|
|
||||||
## Note
|
|
||||||
The application is currently not thread-safe
|
## Customize App
|
||||||
|
Stirling PDF allows easy customization of the visible application name.
|
||||||
|
Simply use environment variables APP_HOME_NAME, APP_HOME_DESCRIPTION and APP_NAVBAR_NAME with Docker or Java.
|
||||||
|
If running Java directly, you can also pass these as properties using -D arguments.
|
||||||
|
|
||||||
|
Using the same method you can also change the default language by providing APP_LOCALE with values like de-DE fr-FR or ar-AR to select your default language (Will always default to English on invalid locale)
|
||||||
18
build.gradle
18
build.gradle
@@ -1,11 +1,11 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.0.3'
|
id 'org.springframework.boot' version '3.0.5'
|
||||||
id 'io.spring.dependency-management' version '1.1.0'
|
id 'io.spring.dependency-management' version '1.1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'stirling.software'
|
group = 'stirling.software'
|
||||||
version = '0.4.0'
|
version = '0.5.0'
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -13,16 +13,18 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web:3.0.5'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.0.5'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.5'
|
||||||
|
// https://mvnrepository.com/artifact/org.apache.pdfbox/jbig2-imageio
|
||||||
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
implementation group: 'org.apache.pdfbox', name: 'jbig2-imageio', version: '3.0.4'
|
||||||
|
implementation 'commons-io:commons-io:2.11.0'
|
||||||
|
|
||||||
//general PDF
|
//general PDF
|
||||||
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
|
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
|
||||||
implementation 'com.itextpdf:itextpdf:5.5.13.3'
|
|
||||||
|
|
||||||
|
implementation 'com.itextpdf:itextpdf:5.5.13.3'
|
||||||
|
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
images/settings.png
Normal file
BIN
images/settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 80 KiB |
@@ -5,9 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SPdfApplication {
|
public class SPdfApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SPdfApplication.class, args);
|
SpringApplication.run(SPdfApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,4 +11,33 @@ public class AppConfig {
|
|||||||
String version = getClass().getPackage().getImplementationVersion();
|
String version = getClass().getPackage().getImplementationVersion();
|
||||||
return (version != null) ? version : "0.3.3";
|
return (version != null) ? version : "0.3.3";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "appName")
|
||||||
|
public String appName() {
|
||||||
|
String appName = System.getProperty("APP_HOME_NAME");
|
||||||
|
if(appName == null)
|
||||||
|
appName = System.getenv("APP_HOME_NAME");
|
||||||
|
return (appName != null) ? appName : "Stirling PDF";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "navBarText")
|
||||||
|
public String navBarText() {
|
||||||
|
String navBarText = System.getProperty("APP_NAVBAR_NAME");
|
||||||
|
if(navBarText == null)
|
||||||
|
navBarText = System.getenv("APP_NAVBAR_NAME");
|
||||||
|
if(navBarText == null)
|
||||||
|
navBarText = System.getProperty("APP_HOME_NAME");
|
||||||
|
if(navBarText == null)
|
||||||
|
navBarText = System.getenv("APP_HOME_NAME");
|
||||||
|
|
||||||
|
return (navBarText != null) ? navBarText : "Stirling PDF";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "homeText")
|
||||||
|
public String homeText() {
|
||||||
|
String homeText = System.getProperty("APP_HOME_DESCRIPTION");
|
||||||
|
if(homeText == null)
|
||||||
|
homeText = System.getenv("APP_HOME_DESCRIPTION");
|
||||||
|
return (homeText != null) ? homeText : "null";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,24 @@ public class Beans implements WebMvcConfigurer {
|
|||||||
@Bean
|
@Bean
|
||||||
public LocaleResolver localeResolver() {
|
public LocaleResolver localeResolver() {
|
||||||
SessionLocaleResolver slr = new SessionLocaleResolver();
|
SessionLocaleResolver slr = new SessionLocaleResolver();
|
||||||
slr.setDefaultLocale(Locale.US);
|
|
||||||
|
String appLocaleEnv = System.getProperty("APP_LOCALE");
|
||||||
|
if(appLocaleEnv == null)
|
||||||
|
appLocaleEnv = System.getenv("APP_LOCALE");
|
||||||
|
Locale defaultLocale = Locale.UK; // Fallback to UK locale if environment variable is not set
|
||||||
|
|
||||||
|
if (appLocaleEnv != null && !appLocaleEnv.isEmpty()) {
|
||||||
|
Locale tempLocale = Locale.forLanguageTag(appLocaleEnv);
|
||||||
|
String tempLanguageTag = tempLocale.toLanguageTag();
|
||||||
|
|
||||||
|
if (appLocaleEnv.equalsIgnoreCase(tempLanguageTag)) {
|
||||||
|
defaultLocale = tempLocale;
|
||||||
|
} else {
|
||||||
|
System.err.println("Invalid APP_LOCALE environment variable value. Falling back to default Locale.UK.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slr.setDefaultLocale(defaultLocale);
|
||||||
return slr;
|
return slr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,15 @@
|
|||||||
package stirling.software.SPDF.controller;
|
package stirling.software.SPDF.controller;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import org.apache.pdfbox.cos.COSName;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDResources;
|
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@@ -26,30 +18,8 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.itextpdf.text.DocumentException;
|
|
||||||
import com.itextpdf.text.pdf.PdfReader;
|
|
||||||
import com.itextpdf.text.pdf.PdfStamper;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class CompressController {
|
public class CompressController {
|
||||||
@@ -80,8 +50,13 @@ public class CompressController {
|
|||||||
// Prepare the OCRmyPDF command
|
// Prepare the OCRmyPDF command
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("ocrmypdf");
|
command.add("ocrmypdf");
|
||||||
|
command.add("--skip-text");
|
||||||
|
command.add("--tesseract-timeout=0");
|
||||||
command.add("--optimize");
|
command.add("--optimize");
|
||||||
command.add(String.valueOf(optimizeLevel));
|
command.add(String.valueOf(optimizeLevel));
|
||||||
|
command.add("--output-type");
|
||||||
|
command.add("pdf");
|
||||||
|
|
||||||
|
|
||||||
if (fastWebView != null && fastWebView) {
|
if (fastWebView != null && fastWebView) {
|
||||||
long fileSize = inputFile.getSize();
|
long fileSize = inputFile.getSize();
|
||||||
@@ -97,7 +72,7 @@ public class CompressController {
|
|||||||
command.add(tempInputFile.toString());
|
command.add(tempInputFile.toString());
|
||||||
command.add(tempOutputFile.toString());
|
command.add(tempOutputFile.toString());
|
||||||
|
|
||||||
int returnCode = ProcessExecutor.runCommandWithOutputHandling(command);
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF).runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the optimized PDF file
|
// Read the optimized PDF file
|
||||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package stirling.software.SPDF.controller;
|
package stirling.software.SPDF.controller;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -11,8 +9,6 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@@ -21,6 +17,8 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class MergeController {
|
public class MergeController {
|
||||||
|
|
||||||
@@ -33,7 +31,7 @@ public class MergeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/merge-pdfs")
|
@PostMapping("/merge-pdfs")
|
||||||
public ResponseEntity<InputStreamResource> mergePdfs(@RequestParam("fileInput") MultipartFile[] files) throws IOException {
|
public ResponseEntity<byte[]> mergePdfs(@RequestParam("fileInput") MultipartFile[] files) throws IOException {
|
||||||
// Read the input PDF files into PDDocument objects
|
// Read the input PDF files into PDDocument objects
|
||||||
List<PDDocument> documents = new ArrayList<>();
|
List<PDDocument> documents = new ArrayList<>();
|
||||||
|
|
||||||
@@ -43,15 +41,9 @@ public class MergeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PDDocument mergedDoc = mergeDocuments(documents);
|
PDDocument mergedDoc = mergeDocuments(documents);
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
||||||
mergedDoc.save(byteArrayOutputStream);
|
|
||||||
mergedDoc.close();
|
|
||||||
|
|
||||||
// Create an InputStreamResource from the merged PDF
|
|
||||||
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
|
|
||||||
|
|
||||||
// Return the merged PDF as a response
|
// Return the merged PDF as a response
|
||||||
return ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF).body(resource);
|
return PdfUtils.pdfDocToWebResponse(mergedDoc, files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "")+ "_merged.pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
package stirling.software.SPDF.controller;
|
package stirling.software.SPDF.controller;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@@ -28,14 +28,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
//import com.spire.pdf.*;
|
|
||||||
@Controller
|
@Controller
|
||||||
public class OCRController {
|
public class OCRController {
|
||||||
|
|
||||||
@@ -52,34 +44,79 @@ public class OCRController {
|
|||||||
@PostMapping("/ocr-pdf")
|
@PostMapping("/ocr-pdf")
|
||||||
public ResponseEntity<byte[]> processPdfWithOCR(@RequestParam("fileInput") MultipartFile inputFile,
|
public ResponseEntity<byte[]> processPdfWithOCR(@RequestParam("fileInput") MultipartFile inputFile,
|
||||||
@RequestParam("languages") List<String> selectedLanguages,
|
@RequestParam("languages") List<String> selectedLanguages,
|
||||||
@RequestParam(name = "sidecar", required = false) Boolean sidecar) throws IOException, InterruptedException {
|
@RequestParam(name = "sidecar", required = false) Boolean sidecar,
|
||||||
|
@RequestParam(name = "deskew", required = false) Boolean deskew,
|
||||||
|
@RequestParam(name = "clean", required = false) Boolean clean,
|
||||||
|
@RequestParam(name = "clean-final", required = false) Boolean cleanFinal,
|
||||||
|
@RequestParam(name = "ocrType", required = false) String ocrType) throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
|
||||||
//--output-type pdfa
|
//--output-type pdfa
|
||||||
if (selectedLanguages == null || selectedLanguages.size() < 1) {
|
if (selectedLanguages == null || selectedLanguages.size() < 1) {
|
||||||
throw new IOException("Please select at least one language.");
|
throw new IOException("Please select at least one language.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate and sanitize selected languages using regex
|
||||||
|
String languagePattern = "^[a-zA-Z]{3}$"; // Regex pattern for three-letter language codes
|
||||||
|
selectedLanguages = selectedLanguages.stream()
|
||||||
|
.filter(lang -> Pattern.matches(languagePattern, lang))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
|
if (selectedLanguages.isEmpty()) {
|
||||||
|
throw new IOException("None of the selected languages are valid.");
|
||||||
|
}
|
||||||
// Save the uploaded file to a temporary location
|
// Save the uploaded file to a temporary location
|
||||||
Path tempInputFile = Files.createTempFile("input_", ".pdf");
|
Path tempInputFile = Files.createTempFile("input_", ".pdf");
|
||||||
inputFile.transferTo(tempInputFile.toFile());
|
Files.copy(inputFile.getInputStream(), tempInputFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
// Prepare the output file path
|
// Prepare the output file path
|
||||||
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
|
|
||||||
|
// Prepare the output file path
|
||||||
|
Path sidecarTextPath = null;
|
||||||
|
|
||||||
// Run OCR Command
|
// Run OCR Command
|
||||||
String languageOption = String.join("+", selectedLanguages);
|
String languageOption = String.join("+", selectedLanguages);
|
||||||
List<String> command = new ArrayList<>(Arrays.asList("ocrmypdf","--verbose", "2", "--language", languageOption,
|
|
||||||
tempInputFile.toString(), tempOutputFile.toString()));
|
List<String> command = new ArrayList<>(Arrays.asList("ocrmypdf","--verbose", "2", "--output-type", "pdf"));
|
||||||
String sidecarFile = tempOutputFile.toString().replace(".pdf", ".txt");
|
|
||||||
|
|
||||||
if (sidecar != null && sidecar) {
|
if (sidecar != null && sidecar) {
|
||||||
|
sidecarTextPath = Files.createTempFile("sidecar", ".txt");
|
||||||
command.add("--sidecar");
|
command.add("--sidecar");
|
||||||
command.add(sidecarFile);
|
command.add(sidecarTextPath.toString());
|
||||||
}
|
}
|
||||||
int returnCode = ProcessExecutor.runCommandWithOutputHandling(command);
|
|
||||||
|
if (deskew != null && deskew) {
|
||||||
|
command.add("--deskew");
|
||||||
|
}
|
||||||
|
if (clean != null && clean) {
|
||||||
|
command.add("--clean");
|
||||||
|
}
|
||||||
|
if (cleanFinal != null && cleanFinal) {
|
||||||
|
command.add("--clean-final");
|
||||||
|
}
|
||||||
|
if (ocrType != null && !ocrType.equals("")) {
|
||||||
|
if("skip-text".equals(ocrType)) {
|
||||||
|
command.add("--skip-text");
|
||||||
|
} else if("force-ocr".equals(ocrType)) {
|
||||||
|
command.add("--force-ocr");
|
||||||
|
} else if("Normal".equals(ocrType)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command.addAll(Arrays.asList("--language", languageOption,
|
||||||
|
tempInputFile.toString(), tempOutputFile.toString()));
|
||||||
|
|
||||||
|
//Run CLI command
|
||||||
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF).runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the OCR processed PDF file
|
// Read the OCR processed PDF file
|
||||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||||
|
|
||||||
|
|
||||||
// Clean up the temporary files
|
// Clean up the temporary files
|
||||||
Files.delete(tempInputFile);
|
Files.delete(tempInputFile);
|
||||||
// Return the OCR processed PDF as a response
|
// Return the OCR processed PDF as a response
|
||||||
@@ -100,9 +137,9 @@ public class OCRController {
|
|||||||
zipOut.closeEntry();
|
zipOut.closeEntry();
|
||||||
|
|
||||||
// Add text file to the zip
|
// Add text file to the zip
|
||||||
ZipEntry txtEntry = new ZipEntry(sidecarFile);
|
ZipEntry txtEntry = new ZipEntry(outputFilename.replace(".pdf", ".txt"));
|
||||||
zipOut.putNextEntry(txtEntry);
|
zipOut.putNextEntry(txtEntry);
|
||||||
Files.copy(Paths.get(sidecarFile), zipOut);
|
Files.copy(sidecarTextPath, zipOut);
|
||||||
zipOut.closeEntry();
|
zipOut.closeEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +148,7 @@ public class OCRController {
|
|||||||
// Clean up the temporary zip file
|
// Clean up the temporary zip file
|
||||||
Files.delete(tempZipFile);
|
Files.delete(tempZipFile);
|
||||||
Files.delete(tempOutputFile);
|
Files.delete(tempOutputFile);
|
||||||
Files.delete(Paths.get(sidecarFile));
|
Files.delete(sidecarTextPath);
|
||||||
|
|
||||||
// Return the zip file containing both the PDF and the text file
|
// Return the zip file containing both the PDF and the text file
|
||||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ public class OverlayImageController {
|
|||||||
|
|
||||||
@PostMapping("/add-image")
|
@PostMapping("/add-image")
|
||||||
public ResponseEntity<byte[]> overlayImage(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("fileInput2") MultipartFile imageFile, @RequestParam("x") float x,
|
public ResponseEntity<byte[]> overlayImage(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("fileInput2") MultipartFile imageFile, @RequestParam("x") float x,
|
||||||
@RequestParam("y") float y) {
|
@RequestParam("y") float y, @RequestParam("everyPage") boolean everyPage) {
|
||||||
try {
|
try {
|
||||||
byte[] pdfBytes = pdfFile.getBytes();
|
byte[] pdfBytes = pdfFile.getBytes();
|
||||||
byte[] imageBytes = imageFile.getBytes();
|
byte[] imageBytes = imageFile.getBytes();
|
||||||
byte[] result = PdfUtils.overlayImage(pdfBytes, imageBytes, x, y);
|
byte[] result = PdfUtils.overlayImage(pdfBytes, imageBytes, x, y, everyPage);
|
||||||
|
|
||||||
return PdfUtils.bytesToWebResponse(result, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_overlayed.pdf");
|
return PdfUtils.bytesToWebResponse(result, pdfFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_overlayed.pdf");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
package stirling.software.SPDF.controller;
|
package stirling.software.SPDF.controller;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.file.FileSystem;
|
|
||||||
import java.nio.file.FileSystems;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
@@ -33,7 +27,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class SplitPDFController {
|
public class SplitPDFController {
|
||||||
|
|
||||||
@@ -107,32 +100,33 @@ public class SplitPDFController {
|
|||||||
// closing the original document
|
// closing the original document
|
||||||
document.close();
|
document.close();
|
||||||
|
|
||||||
// create the zip file
|
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
||||||
Path zipFile = Paths.get("split_documents.zip");
|
|
||||||
URI uri = URI.create("jar:file:" + zipFile.toUri().getPath());
|
|
||||||
Map<String, String> env = new HashMap<>();
|
|
||||||
env.put("create", "true");
|
|
||||||
FileSystem zipfs = FileSystems.newFileSystem(uri, env);
|
|
||||||
|
|
||||||
|
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||||
// loop through the split documents and write them to the zip file
|
// loop through the split documents and write them to the zip file
|
||||||
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
|
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
|
||||||
String fileName = "split_document_" + (i + 1) + ".pdf";
|
String fileName = "split_document_" + (i + 1) + ".pdf";
|
||||||
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
|
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
|
||||||
byte[] pdf = baos.toByteArray();
|
byte[] pdf = baos.toByteArray();
|
||||||
Path pathInZipfile = zipfs.getPath(fileName);
|
|
||||||
try (OutputStream os = Files.newOutputStream(pathInZipfile)) {
|
// Add PDF file to the zip
|
||||||
os.write(pdf);
|
ZipEntry pdfEntry = new ZipEntry(fileName);
|
||||||
|
zipOut.putNextEntry(pdfEntry);
|
||||||
|
zipOut.write(pdf);
|
||||||
|
zipOut.closeEntry();
|
||||||
|
|
||||||
logger.info("Wrote split document {} to zip file", fileName);
|
logger.info("Wrote split document {} to zip file", fileName);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed writing to zip", e);
|
logger.error("Failed writing to zip", e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
zipfs.close();
|
|
||||||
logger.info("Successfully created zip file with split documents: {}", zipFile.toString());
|
logger.info("Successfully created zip file with split documents: {}", zipFile.toString());
|
||||||
byte[] data = Files.readAllBytes(zipFile);
|
byte[] data = Files.readAllBytes(zipFile);
|
||||||
ByteArrayResource resource = new ByteArrayResource(data);
|
ByteArrayResource resource = new ByteArrayResource(data);
|
||||||
new File("split_documents.zip").delete();
|
Files.delete(zipFile);
|
||||||
|
|
||||||
// return the Resource in the response
|
// return the Resource in the response
|
||||||
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_split.zip").contentType(MediaType.APPLICATION_OCTET_STREAM)
|
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_split.zip").contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
.contentLength(resource.contentLength()).body(resource);
|
.contentLength(resource.contentLength()).body(resource);
|
||||||
|
|||||||
@@ -38,12 +38,13 @@ public class ConvertImgPDFController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/img-to-pdf")
|
@PostMapping("/img-to-pdf")
|
||||||
public ResponseEntity<byte[]> convertToPdf(@RequestParam("fileInput") MultipartFile file) throws IOException {
|
public ResponseEntity<byte[]> convertToPdf(@RequestParam("fileInput") MultipartFile[] file,
|
||||||
|
@RequestParam(defaultValue = "false", name = "stretchToFit") boolean stretchToFit,
|
||||||
|
@RequestParam(defaultValue = "true", name = "autoRotate") boolean autoRotate) throws IOException {
|
||||||
// Convert the file to PDF and get the resulting bytes
|
// Convert the file to PDF and get the resulting bytes
|
||||||
byte[] bytes = PdfUtils.convertToPdf(file.getInputStream());
|
System.out.println(stretchToFit);
|
||||||
logger.info("File {} successfully converted to pdf", file.getOriginalFilename());
|
byte[] bytes = PdfUtils.imageToPdf(file, stretchToFit, autoRotate);
|
||||||
|
return PdfUtils.bytesToWebResponse(bytes, file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "")+ "_coverted.pdf");
|
||||||
return PdfUtils.bytesToWebResponse(bytes, file.getOriginalFilename().replaceFirst("[.][^.]+$", "")+ "_coverted.pdf");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/pdf-to-img")
|
@PostMapping("/pdf-to-img")
|
||||||
@@ -72,7 +73,6 @@ public class ConvertImgPDFController {
|
|||||||
if (singleImage) {
|
if (singleImage) {
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentType(MediaType.parseMediaType(getMediaType(imageFormat)));
|
headers.setContentType(MediaType.parseMediaType(getMediaType(imageFormat)));
|
||||||
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
|
|
||||||
ResponseEntity<Resource> response = new ResponseEntity<>(new ByteArrayResource(result), headers, HttpStatus.OK);
|
ResponseEntity<Resource> response = new ResponseEntity<>(new ByteArrayResource(result), headers, HttpStatus.OK);
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package stirling.software.SPDF.controller.converters;
|
package stirling.software.SPDF.controller.converters;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@@ -17,9 +16,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.LibreOfficeListener;
|
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
@Controller
|
@Controller
|
||||||
@@ -44,9 +41,15 @@ public class ConvertOfficeController {
|
|||||||
|
|
||||||
|
|
||||||
public byte[] convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
public byte[] convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
|
// Check for valid file extension
|
||||||
|
String originalFilename = inputFile.getOriginalFilename();
|
||||||
|
if (originalFilename == null || !isValidFileExtension(FilenameUtils.getExtension(originalFilename))) {
|
||||||
|
throw new IllegalArgumentException("Invalid file extension");
|
||||||
|
}
|
||||||
|
|
||||||
// Save the uploaded file to a temporary location
|
// Save the uploaded file to a temporary location
|
||||||
Path tempInputFile = Files.createTempFile("input_", "." + getFileExtension(inputFile.getOriginalFilename()));
|
Path tempInputFile = Files.createTempFile("input_", "." + FilenameUtils.getExtension(originalFilename));
|
||||||
inputFile.transferTo(tempInputFile.toFile());
|
Files.copy(inputFile.getInputStream(), tempInputFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
// Prepare the output file path
|
// Prepare the output file path
|
||||||
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
@@ -58,7 +61,7 @@ public byte[] convertToPdf(MultipartFile inputFile) throws IOException, Interrup
|
|||||||
"-o",
|
"-o",
|
||||||
tempOutputFile.toString(),
|
tempOutputFile.toString(),
|
||||||
tempInputFile.toString()));
|
tempInputFile.toString()));
|
||||||
int returnCode = ProcessExecutor.runCommandWithOutputHandling(command);
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE).runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the converted PDF file
|
// Read the converted PDF file
|
||||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||||
@@ -69,14 +72,9 @@ public byte[] convertToPdf(MultipartFile inputFile) throws IOException, Interrup
|
|||||||
|
|
||||||
return pdfBytes;
|
return pdfBytes;
|
||||||
}
|
}
|
||||||
|
private boolean isValidFileExtension(String fileExtension) {
|
||||||
|
String extensionPattern = "^(?i)[a-z0-9]{2,4}$";
|
||||||
|
return fileExtension.matches(extensionPattern);
|
||||||
private String getFileExtension(String fileName) {
|
|
||||||
int dotIndex = fileName.lastIndexOf('.');
|
|
||||||
if (dotIndex == -1) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return fileName.substring(dotIndex + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package stirling.software.SPDF.controller.converters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.PDFToFile;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class ConvertPDFToOffice {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-word")
|
||||||
|
public ModelAndView pdfToWord() {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-word");
|
||||||
|
modelAndView.addObject("currentPage", "pdf-to-word");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-presentation")
|
||||||
|
public ModelAndView pdfToPresentation() {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-presentation");
|
||||||
|
modelAndView.addObject("currentPage", "pdf-to-presentation");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-text")
|
||||||
|
public ModelAndView pdfToText() {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-text");
|
||||||
|
modelAndView.addObject("currentPage", "pdf-to-text");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-html")
|
||||||
|
public ModelAndView pdfToHTML() {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-html");
|
||||||
|
modelAndView.addObject("currentPage", "pdf-to-html");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-xml")
|
||||||
|
public ModelAndView pdfToXML() {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-xml");
|
||||||
|
modelAndView.addObject("currentPage", "pdf-to-xml");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-word")
|
||||||
|
public ResponseEntity<byte[]> processPdfToWord(@RequestParam("fileInput") MultipartFile inputFile,
|
||||||
|
@RequestParam("outputFormat") String outputFormat) throws IOException, InterruptedException {
|
||||||
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "writer_pdf_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-presentation")
|
||||||
|
public ResponseEntity<byte[]> processPdfToPresentation(@RequestParam("fileInput") MultipartFile inputFile,
|
||||||
|
@RequestParam("outputFormat") String outputFormat) throws IOException, InterruptedException {
|
||||||
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "impress_pdf_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-text")
|
||||||
|
public ResponseEntity<byte[]> processPdfToRTForTXT(@RequestParam("fileInput") MultipartFile inputFile,
|
||||||
|
@RequestParam("outputFormat") String outputFormat) throws IOException, InterruptedException {
|
||||||
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "writer_pdf_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-html")
|
||||||
|
public ResponseEntity<byte[]> processPdfToHTML(@RequestParam("fileInput") MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
return pdfToFile.processPdfToOfficeFormat(inputFile, "html", "writer_pdf_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-xml")
|
||||||
|
public ResponseEntity<byte[]> processPdfToXML(@RequestParam("fileInput") MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
return pdfToFile.processPdfToOfficeFormat(inputFile, "xml", "writer_pdf_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package stirling.software.SPDF.controller.converters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
|
@Controller
|
||||||
|
public class ConvertPDFToPDFA {
|
||||||
|
|
||||||
|
@GetMapping("/pdf-to-pdfa")
|
||||||
|
public String pdfToPdfAForm(Model model) {
|
||||||
|
model.addAttribute("currentPage", "pdf-to-pdfa");
|
||||||
|
return "convert/pdf-to-pdfa";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/pdf-to-pdfa")
|
||||||
|
public ResponseEntity<byte[]> pdfToPdfA(
|
||||||
|
@RequestParam("fileInput") MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
|
||||||
|
// Save the uploaded file to a temporary location
|
||||||
|
Path tempInputFile = Files.createTempFile("input_", ".pdf");
|
||||||
|
inputFile.transferTo(tempInputFile.toFile());
|
||||||
|
|
||||||
|
// Prepare the output file path
|
||||||
|
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
|
|
||||||
|
// Prepare the OCRmyPDF command
|
||||||
|
List<String> command = new ArrayList<>();
|
||||||
|
command.add("ocrmypdf");
|
||||||
|
command.add("--skip-text");
|
||||||
|
command.add("--tesseract-timeout=0");
|
||||||
|
command.add("--output-type");
|
||||||
|
command.add("pdfa");
|
||||||
|
command.add(tempInputFile.toString());
|
||||||
|
command.add(tempOutputFile.toString());
|
||||||
|
|
||||||
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF).runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
|
// Read the optimized PDF file
|
||||||
|
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||||
|
|
||||||
|
// Clean up the temporary files
|
||||||
|
Files.delete(tempInputFile);
|
||||||
|
Files.delete(tempOutputFile);
|
||||||
|
|
||||||
|
// Return the optimized PDF as a response
|
||||||
|
String outputFilename = inputFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_PDFA.pdf";
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_PDF);
|
||||||
|
headers.setContentDispositionFormData("attachment", outputFilename);
|
||||||
|
return ResponseEntity.ok().headers(headers).body(pdfBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||||
|
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
@@ -45,6 +46,7 @@ public class WatermarkController {
|
|||||||
@PostMapping("/add-watermark")
|
@PostMapping("/add-watermark")
|
||||||
public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("watermarkText") String watermarkText,
|
public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("watermarkText") String watermarkText,
|
||||||
@RequestParam(defaultValue = "30", name = "fontSize") float fontSize, @RequestParam(defaultValue = "0", name = "rotation") float rotation,
|
@RequestParam(defaultValue = "30", name = "fontSize") float fontSize, @RequestParam(defaultValue = "0", name = "rotation") float rotation,
|
||||||
|
@RequestParam(defaultValue = "0.5", name = "opacity") float opacity,
|
||||||
@RequestParam(defaultValue = "50", name = "widthSpacer") int widthSpacer, @RequestParam(defaultValue = "50", name = "heightSpacer") int heightSpacer)
|
@RequestParam(defaultValue = "50", name = "widthSpacer") int widthSpacer, @RequestParam(defaultValue = "50", name = "heightSpacer") int heightSpacer)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
@@ -53,9 +55,18 @@ public class WatermarkController {
|
|||||||
|
|
||||||
// Create a page in the document
|
// Create a page in the document
|
||||||
for (PDPage page : document.getPages()) {
|
for (PDPage page : document.getPages()) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get the page's content stream
|
// Get the page's content stream
|
||||||
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
|
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
|
||||||
|
|
||||||
|
// Set transparency
|
||||||
|
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
|
||||||
|
graphicsState.setNonStrokingAlphaConstant(opacity);
|
||||||
|
contentStream.setGraphicsStateParameters(graphicsState);
|
||||||
|
|
||||||
// Set font of watermark
|
// Set font of watermark
|
||||||
PDFont font = PDType1Font.HELVETICA_BOLD;
|
PDFont font = PDType1Font.HELVETICA_BOLD;
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
|
|||||||
101
src/main/java/stirling/software/SPDF/utils/PDFToFile.java
Normal file
101
src/main/java/stirling/software/SPDF/utils/PDFToFile.java
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package stirling.software.SPDF.utils;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
public class PDFToFile {
|
||||||
|
public ResponseEntity<byte[]> processPdfToOfficeFormat(MultipartFile inputFile, String outputFormat, String libreOfficeFilter)
|
||||||
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
if (!"application/pdf".equals(inputFile.getContentType())) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the original PDF file name without the extension
|
||||||
|
String originalPdfFileName = inputFile.getOriginalFilename();
|
||||||
|
String pdfBaseName = originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'));
|
||||||
|
|
||||||
|
// Validate output format
|
||||||
|
List<String> allowedFormats = Arrays.asList("doc", "docx", "odt", "ppt", "pptx", "odp", "rtf", "html","xml","txt:Text");
|
||||||
|
if (!allowedFormats.contains(outputFormat)) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path tempInputFile = null;
|
||||||
|
Path tempOutputDir = null;
|
||||||
|
byte[] fileBytes;
|
||||||
|
// Prepare response
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Save the uploaded file to a temporary location
|
||||||
|
tempInputFile = Files.createTempFile("input_", ".pdf");
|
||||||
|
Files.copy(inputFile.getInputStream(), tempInputFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
// Prepare the output directory
|
||||||
|
tempOutputDir = Files.createTempDirectory("output_");
|
||||||
|
|
||||||
|
// Run the LibreOffice command
|
||||||
|
List<String> command = new ArrayList<>(Arrays.asList(
|
||||||
|
"soffice", "--infilter=" + libreOfficeFilter, "--convert-to", outputFormat, "--outdir", tempOutputDir.toString(), tempInputFile.toString()
|
||||||
|
));
|
||||||
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE).runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
|
// Get output files
|
||||||
|
List<File> outputFiles = Arrays.asList(tempOutputDir.toFile().listFiles());
|
||||||
|
|
||||||
|
if (outputFiles.size() == 1) {
|
||||||
|
// Return single output file
|
||||||
|
File outputFile = outputFiles.get(0);
|
||||||
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
if(outputFormat.equals("txt:Text")) {
|
||||||
|
outputFormat="txt";
|
||||||
|
}
|
||||||
|
headers.setContentDispositionFormData("attachment", pdfBaseName + "." + outputFormat);
|
||||||
|
fileBytes = FileUtils.readFileToByteArray(outputFile);
|
||||||
|
} else {
|
||||||
|
// Return output files in a ZIP archive
|
||||||
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
headers.setContentDispositionFormData("attachment", pdfBaseName + "To" + outputFormat + ".zip");
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
|
||||||
|
|
||||||
|
for (File outputFile : outputFiles) {
|
||||||
|
ZipEntry entry = new ZipEntry(outputFile.getName());
|
||||||
|
zipOutputStream.putNextEntry(entry);
|
||||||
|
FileInputStream fis = new FileInputStream(outputFile);
|
||||||
|
IOUtils.copy(fis, zipOutputStream);
|
||||||
|
fis.close();
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
zipOutputStream.close();
|
||||||
|
fileBytes = byteArrayOutputStream.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
// Clean up the temporary files
|
||||||
|
if (tempInputFile != null)
|
||||||
|
Files.delete(tempInputFile);
|
||||||
|
if (tempOutputDir != null)
|
||||||
|
FileUtils.deleteDirectory(tempOutputDir.toFile());
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,6 +29,7 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.itextpdf.text.Document;
|
import com.itextpdf.text.Document;
|
||||||
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.DocumentException;
|
||||||
@@ -37,12 +39,13 @@ public class PdfUtils {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
|
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
|
||||||
|
|
||||||
public static byte[] convertToPdf(InputStream imageStream) throws IOException {
|
public static byte[] imageToPdf(MultipartFile[] files, boolean stretchToFit, boolean autoRotate) throws IOException {
|
||||||
|
try (PDDocument doc = new PDDocument()) {
|
||||||
|
for (MultipartFile file : files) {
|
||||||
|
// Create a temporary file for the image
|
||||||
|
File imageFile = Files.createTempFile("image", ".jpg").toFile();
|
||||||
|
|
||||||
// Create a File object for the image
|
try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = file.getInputStream()) {
|
||||||
File imageFile = new File("image.jpg");
|
|
||||||
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = imageStream) {
|
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int len;
|
int len;
|
||||||
// Read from the input stream and write to the file
|
// Read from the input stream and write to the file
|
||||||
@@ -55,7 +58,6 @@ public class PdfUtils {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (PDDocument doc = new PDDocument()) {
|
|
||||||
// Create a new PDF page
|
// Create a new PDF page
|
||||||
PDPage page = new PDPage();
|
PDPage page = new PDPage();
|
||||||
doc.addPage(page);
|
doc.addPage(page);
|
||||||
@@ -63,23 +65,74 @@ public class PdfUtils {
|
|||||||
// Create an image object from the image file
|
// Create an image object from the image file
|
||||||
PDImageXObject image = PDImageXObject.createFromFileByContent(imageFile, doc);
|
PDImageXObject image = PDImageXObject.createFromFileByContent(imageFile, doc);
|
||||||
|
|
||||||
|
float pageWidth = page.getMediaBox().getWidth();
|
||||||
|
float pageHeight = page.getMediaBox().getHeight();
|
||||||
|
|
||||||
|
if (autoRotate && ((image.getWidth() > image.getHeight() && pageHeight > pageWidth) || (image.getWidth() < image.getHeight() && pageWidth > pageHeight))) {
|
||||||
|
// Rotate the page 90 degrees if the image better fits the page in landscape orientation
|
||||||
|
page.setRotation(90);
|
||||||
|
pageWidth = page.getMediaBox().getHeight();
|
||||||
|
pageHeight = page.getMediaBox().getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
|
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
|
||||||
|
if (stretchToFit) {
|
||||||
|
if (page.getRotation() == 0 || page.getRotation() == 180) {
|
||||||
|
// Stretch the image to fit the whole page
|
||||||
|
contentStream.drawImage(image, 0, 0, pageWidth, pageHeight);
|
||||||
|
} else {
|
||||||
|
// Adjust the width and height of the page when rotated
|
||||||
|
contentStream.drawImage(image, 0, 0, pageHeight, pageWidth);
|
||||||
|
}
|
||||||
|
logger.info("Image successfully added to PDF, stretched to fit page");
|
||||||
|
} else {
|
||||||
|
// Ensure the image fits the page but maintain the image's aspect ratio
|
||||||
|
float imageAspectRatio = (float) image.getWidth() / (float) image.getHeight();
|
||||||
|
float pageAspectRatio = pageWidth / pageHeight;
|
||||||
|
|
||||||
|
// Determine the scale factor to fit the image onto the page
|
||||||
|
float scaleFactor = 1.0f;
|
||||||
|
if (imageAspectRatio > pageAspectRatio) {
|
||||||
|
// Image is wider than the page, scale to fit the width
|
||||||
|
scaleFactor = pageWidth / image.getWidth();
|
||||||
|
} else {
|
||||||
|
// Image is taller than the page, scale to fit the height
|
||||||
|
scaleFactor = pageHeight / image.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the position of the image on the page
|
||||||
|
float xPos = (pageWidth - (image.getWidth() * scaleFactor)) / 2;
|
||||||
|
float yPos = (pageHeight - (image.getHeight() * scaleFactor)) / 2;
|
||||||
|
|
||||||
// Draw the image onto the page
|
// Draw the image onto the page
|
||||||
contentStream.drawImage(image, 0, 0);
|
if (page.getRotation() == 0 || page.getRotation() == 180) {
|
||||||
logger.info("Image successfully added to PDF");
|
contentStream.drawImage(image, xPos, yPos, image.getWidth() * scaleFactor, image.getHeight() * scaleFactor);
|
||||||
|
} else {
|
||||||
|
// Adjust the width and height of the page when rotated
|
||||||
|
contentStream.drawImage(image, yPos, xPos, image.getHeight() * scaleFactor, image.getWidth() * scaleFactor);
|
||||||
|
}
|
||||||
|
logger.info("Image successfully added to PDF, maintaining aspect ratio");
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Error adding image to PDF", e);
|
logger.error("Error adding image to PDF", e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete the temporary file
|
||||||
|
imageFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
// Create a ByteArrayOutputStream to save the PDF to
|
// Create a ByteArrayOutputStream to save the PDF to
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
doc.save(byteArrayOutputStream);
|
doc.save(byteArrayOutputStream);
|
||||||
logger.info("PDF successfully saved to byte array");
|
logger.info("PDF successfully saved to byte array");
|
||||||
|
|
||||||
return byteArrayOutputStream.toByteArray();
|
return byteArrayOutputStream.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI)
|
public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI)
|
||||||
throws IOException, Exception {
|
throws IOException, Exception {
|
||||||
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) {
|
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) {
|
||||||
@@ -135,28 +188,35 @@ public class PdfUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] overlayImage(byte[] pdfBytes, byte[] imageBytes, float x, float y) throws IOException {
|
public static byte[] overlayImage(byte[] pdfBytes, byte[] imageBytes, float x, float y, boolean everyPage) throws IOException {
|
||||||
|
|
||||||
|
PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes));
|
||||||
|
|
||||||
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes))) {
|
|
||||||
// Get the first page of the PDF
|
// Get the first page of the PDF
|
||||||
PDPage page = document.getPage(0);
|
int pages = document.getNumberOfPages();
|
||||||
|
for (int i = 0; i < pages; i++) {
|
||||||
|
PDPage page = document.getPage(i);
|
||||||
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true)) {
|
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true)) {
|
||||||
// Create an image object from the image bytes
|
// Create an image object from the image bytes
|
||||||
PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, "");
|
PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, "");
|
||||||
// Draw the image onto the page at the specified x and y coordinates
|
// Draw the image onto the page at the specified x and y coordinates
|
||||||
contentStream.drawImage(image, x, y);
|
contentStream.drawImage(image, x, y);
|
||||||
logger.info("Image successfully overlayed onto PDF");
|
logger.info("Image successfully overlayed onto PDF");
|
||||||
|
if (everyPage == false && i == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Log an error message if there is an issue overlaying the image onto the PDF
|
||||||
|
logger.error("Error overlaying image onto PDF", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Create a ByteArrayOutputStream to save the PDF to
|
// Create a ByteArrayOutputStream to save the PDF to
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
document.save(baos);
|
document.save(baos);
|
||||||
logger.info("PDF successfully saved to byte array");
|
logger.info("PDF successfully saved to byte array");
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
} catch (IOException e) {
|
|
||||||
// Log an error message if there is an issue overlaying the image onto the PDF
|
|
||||||
logger.error("Error overlaying image onto PDF", e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResponseEntity<byte[]> iTextDocToWebResponse(Document document, String docName) throws IOException, DocumentException {
|
public static ResponseEntity<byte[]> iTextDocToWebResponse(Document document, String docName) throws IOException, DocumentException {
|
||||||
|
|||||||
@@ -1,15 +1,46 @@
|
|||||||
package stirling.software.SPDF.utils;
|
package stirling.software.SPDF.utils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
public class ProcessExecutor {
|
public class ProcessExecutor {
|
||||||
public static int runCommandWithOutputHandling(List<String> command) throws IOException, InterruptedException {
|
|
||||||
|
public enum Processes {
|
||||||
|
LIBRE_OFFICE,
|
||||||
|
OCR_MY_PDF
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<Processes, ProcessExecutor> instances = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
private final Semaphore semaphore;
|
||||||
|
|
||||||
|
private ProcessExecutor(int semaphoreLimit) {
|
||||||
|
this.semaphore = new Semaphore(semaphoreLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProcessExecutor getInstance(Processes processType) {
|
||||||
|
return instances.computeIfAbsent(processType, key -> {
|
||||||
|
int semaphoreLimit = switch (key) {
|
||||||
|
case LIBRE_OFFICE -> 1;
|
||||||
|
case OCR_MY_PDF -> 2;
|
||||||
|
};
|
||||||
|
return new ProcessExecutor(semaphoreLimit);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runCommandWithOutputHandling(List<String> command) throws IOException, InterruptedException {
|
||||||
|
int exitCode = 1;
|
||||||
|
semaphore.acquire();
|
||||||
|
try {
|
||||||
|
|
||||||
|
System.out.print("Running command: " + String.join(" ", command));
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
Process process = processBuilder.start();
|
Process process = processBuilder.start();
|
||||||
|
|
||||||
@@ -43,7 +74,7 @@ public class ProcessExecutor {
|
|||||||
outputReaderThread.start();
|
outputReaderThread.start();
|
||||||
|
|
||||||
// Wait for the conversion process to complete
|
// Wait for the conversion process to complete
|
||||||
int exitCode = process.waitFor();
|
exitCode = process.waitFor();
|
||||||
|
|
||||||
// Wait for the reader threads to finish
|
// Wait for the reader threads to finish
|
||||||
errorReaderThread.join();
|
errorReaderThread.join();
|
||||||
@@ -61,7 +92,9 @@ public class ProcessExecutor {
|
|||||||
throw new IOException("Command process failed with exit code " + exitCode + ". Error message: " + errorMessage);
|
throw new IOException("Command process failed with exit code " + exitCode + ". Error message: " + errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
spring.http.multipart.max-file-size=1GB
|
spring.http.multipart.max-file-size=2GB
|
||||||
spring.http.multipart.max-request-size=1GB
|
spring.http.multipart.max-request-size=2GB
|
||||||
|
|
||||||
multipart.enabled=true
|
multipart.enabled=true
|
||||||
multipart.max-file-size=1000MB
|
multipart.max-file-size=2000MB
|
||||||
multipart.max-request-size=1000MB
|
multipart.max-request-size=2000MB
|
||||||
|
|
||||||
spring.servlet.multipart.max-file-size=1000MB
|
spring.servlet.multipart.max-file-size=2000MB
|
||||||
spring.servlet.multipart.max-request-size=1000MB
|
spring.servlet.multipart.max-request-size=2000MB
|
||||||
|
|
||||||
server.forward-headers-strategy=NATIVE
|
server.forward-headers-strategy=NATIVE
|
||||||
|
|
||||||
@@ -17,3 +17,8 @@ server.error.include-exception=true
|
|||||||
server.error.include-message=always
|
server.error.include-message=always
|
||||||
|
|
||||||
server.servlet.session.tracking-modes=cookie
|
server.servlet.session.tracking-modes=cookie
|
||||||
|
|
||||||
|
spring.devtools.restart.enabled=true
|
||||||
|
spring.devtools.livereload.enabled=true
|
||||||
|
|
||||||
|
spring.thymeleaf.encoding=UTF-8
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
###########
|
###########
|
||||||
# Generic #
|
# Generic #
|
||||||
###########
|
###########
|
||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
# the direction that the language is written (ltr=left to right, rtl=right to left)
|
||||||
language.direction=rtl
|
language.direction=rtl
|
||||||
|
|
||||||
pdfPrompt=اختر PDF
|
pdfPrompt=اختر PDF
|
||||||
@@ -56,8 +56,8 @@ home.addImage.desc=إضافة صورة إلى موقع معين في PDF (الع
|
|||||||
home.watermark.title=إضافة علامة مائية
|
home.watermark.title=إضافة علامة مائية
|
||||||
home.watermark.desc=أضف علامة مائية مخصصة إلى مستند PDF الخاص بك.
|
home.watermark.desc=أضف علامة مائية مخصصة إلى مستند PDF الخاص بك.
|
||||||
|
|
||||||
home.remove-watermark.title = \u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
home.remove-watermark.title=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
||||||
home.remove-watermark.desc = \u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0645\u0627\u0626\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF \u0627\u0644\u062E\u0627\u0635 \u0628\u0643.
|
home.remove-watermark.desc=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0645\u0627\u0626\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF \u0627\u0644\u062E\u0627\u0635 \u0628\u0643.
|
||||||
|
|
||||||
home.permissions.title=تغيير الأذونات
|
home.permissions.title=تغيير الأذونات
|
||||||
home.permissions.desc=قم بتغيير أذونات مستند PDF الخاص بك
|
home.permissions.desc=قم بتغيير أذونات مستند PDF الخاص بك
|
||||||
@@ -74,37 +74,64 @@ home.removePassword.desc=إزالة الحماية بكلمة مرور من مس
|
|||||||
home.compressPdfs.title=ضغط ملفات PDF
|
home.compressPdfs.title=ضغط ملفات PDF
|
||||||
home.compressPdfs.desc=ضغط ملفات PDF لتقليل حجم الملف.
|
home.compressPdfs.desc=ضغط ملفات PDF لتقليل حجم الملف.
|
||||||
|
|
||||||
home.changeMetadata.title = \u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
home.changeMetadata.title=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
||||||
home.changeMetadata.desc = \u062A\u063A\u064A\u064A\u0631 / \u0625\u0632\u0627\u0644\u0629 / \u0625\u0636\u0627\u0641\u0629 \u0628\u064A\u0627\u0646\u0627\u062A \u0623\u0648\u0644\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF
|
home.changeMetadata.desc=\u062A\u063A\u064A\u064A\u0631 / \u0625\u0632\u0627\u0644\u0629 / \u0625\u0636\u0627\u0641\u0629 \u0628\u064A\u0627\u0646\u0627\u062A \u0623\u0648\u0644\u064A\u0629 \u0645\u0646 \u0645\u0633\u062A\u0646\u062F PDF
|
||||||
|
|
||||||
|
|
||||||
home.fileToPDF.title=\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0645\u0644\u0641 \u0625\u0644\u0649 PDF
|
home.fileToPDF.title=\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0645\u0644\u0641 \u0625\u0644\u0649 PDF
|
||||||
home.fileToPDF.desc=\u062A\u062D\u0648\u064A\u0644 \u0623\u064A \u0645\u0644\u0641 \u062A\u0642\u0631\u064A\u0628\u0627 \u0625\u0644\u0649 PDF (DOCX \u0648PNG \u0648XLS \u0648PPT \u0648TXT \u0648\u0627\u0644\u0645\u0632\u064A\u062F)
|
home.fileToPDF.desc=\u062A\u062D\u0648\u064A\u0644 \u0623\u064A \u0645\u0644\u0641 \u062A\u0642\u0631\u064A\u0628\u0627 \u0625\u0644\u0649 PDF (DOCX \u0648PNG \u0648XLS \u0648PPT \u0648TXT \u0648\u0627\u0644\u0645\u0632\u064A\u062F)
|
||||||
|
|
||||||
home.ocr.title=\u062A\u0634\u063A\u064A\u0644 OCR \u0639\u0644\u0649 PDF
|
home.ocr.title=\u062A\u0634\u063A\u064A\u0644 OCR \u0639\u0644\u0649 PDF \u0648 / \u0623\u0648 \u0645\u0633\u062D \u0636\u0648\u0626\u064A
|
||||||
home.ocr.desc=\u0645\u0633\u062D \u0648\u0627\u0643\u062A\u0634\u0627\u0641 \u0627\u0644\u0646\u0635 \u0645\u0646 \u0627\u0644\u0635\u0648\u0631 \u062F\u0627\u062E\u0644 PDF \u0648\u0625\u0639\u0627\u062F\u0629 \u0625\u0636\u0627\u0641\u062A\u0647 \u0643\u0646\u0635.
|
home.ocr.desc=\u064A\u0642\u0648\u0645 \u0628\u0631\u0646\u0627\u0645\u062C \u0627\u0644\u062A\u0646\u0638\u064A\u0641 \u0628\u0645\u0633\u062D \u0648\u0627\u0643\u062A\u0634\u0627\u0641 \u0627\u0644\u0646\u0635 \u0645\u0646 \u0627\u0644\u0635\u0648\u0631 \u062F\u0627\u062E\u0644 \u0645\u0644\u0641 PDF \u0648\u064A\u0639\u064A\u062F \u0625\u0636\u0627\u0641\u062A\u0647 \u0643\u0646\u0635
|
||||||
|
|
||||||
home.extractImages.title=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
|
home.extractImages.title=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
|
||||||
home.extractImages.desc=\u064A\u0633\u062A\u062E\u0631\u062C \u062C\u0645\u064A\u0639 \u0627\u0644\u0635\u0648\u0631 \u0645\u0646 \u0645\u0644\u0641 PDF \u0648\u064A\u062D\u0641\u0638\u0647\u0627 \u0641\u064A \u0627\u0644\u0631\u0645\u0632 \u0627\u0644\u0628\u0631\u064A\u062F\u064A
|
home.extractImages.desc=\u064A\u0633\u062A\u062E\u0631\u062C \u062C\u0645\u064A\u0639 \u0627\u0644\u0635\u0648\u0631 \u0645\u0646 \u0645\u0644\u0641 PDF \u0648\u064A\u062D\u0641\u0638\u0647\u0627 \u0641\u064A \u0627\u0644\u0631\u0645\u0632 \u0627\u0644\u0628\u0631\u064A\u062F\u064A
|
||||||
|
|
||||||
navbar.settings = \u0625\u0639\u062F\u0627\u062F\u0627\u062A
|
home.pdfToPDFA.title = \u062A\u062D\u0648\u064A\u0644 \u0645\u0644\u0641\u0627\u062A PDF \u0625\u0644\u0649 PDF / A
|
||||||
|
home.pdfToPDFA.desc = \u062A\u062D\u0648\u064A\u0644 PDF \u0625\u0644\u0649 PDF / A \u0644\u0644\u062A\u062E\u0632\u064A\u0646 \u0637\u0648\u064A\u0644 \u0627\u0644\u0645\u062F\u0649
|
||||||
|
|
||||||
|
|
||||||
|
home.PDFToWord.title = تحويل PDF إلى Word
|
||||||
|
home.PDFToWord.desc = تحويل PDF إلى تنسيقات Word (DOC و DOCX و ODT)
|
||||||
|
|
||||||
|
home.PDFToPresentation.title = PDF للعرض التقديمي
|
||||||
|
home.PDFToPresentation.desc = تحويل PDF إلى تنسيقات عرض تقديمي (PPT و PPTX و ODP)
|
||||||
|
|
||||||
|
home.PDFToText.title = تحويل PDF إلى نص / RTF
|
||||||
|
home.PDFToText.desc = تحويل PDF إلى تنسيق نص أو RTF
|
||||||
|
|
||||||
|
home.PDFToHTML.title = تحويل PDF إلى HTML
|
||||||
|
home.PDFToHTML.desc = تحويل PDF إلى تنسيق HTML
|
||||||
|
|
||||||
|
home.PDFToXML.title = تحويل PDF إلى XML
|
||||||
|
home.PDFToXML.desc = تحويل PDF إلى تنسيق XML
|
||||||
|
|
||||||
|
navbar.settings=\u0625\u0639\u062F\u0627\u062F\u0627\u062A
|
||||||
settings.title=\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A
|
settings.title=\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A
|
||||||
settings.update = \u0627\u0644\u062A\u062D\u062F\u064A\u062B \u0645\u062A\u0627\u062D
|
settings.update=\u0627\u0644\u062A\u062D\u062F\u064A\u062B \u0645\u062A\u0627\u062D
|
||||||
settings.appVersion = \u0625\u0635\u062F\u0627\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642:
|
settings.appVersion=\u0625\u0635\u062F\u0627\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642:
|
||||||
settings.downloadOption.title=\u062A\u062D\u062F\u064A\u062F \u062E\u064A\u0627\u0631 \u0627\u0644\u062A\u0646\u0632\u064A\u0644 (\u0644\u0644\u062A\u0646\u0632\u064A\u0644\u0627\u062A \u0630\u0627\u062A \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0648\u0627\u062D\u062F \u063A\u064A\u0631 \u0627\u0644\u0645\u0636\u063A\u0648\u0637):
|
settings.downloadOption.title=\u062A\u062D\u062F\u064A\u062F \u062E\u064A\u0627\u0631 \u0627\u0644\u062A\u0646\u0632\u064A\u0644 (\u0644\u0644\u062A\u0646\u0632\u064A\u0644\u0627\u062A \u0630\u0627\u062A \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0648\u0627\u062D\u062F \u063A\u064A\u0631 \u0627\u0644\u0645\u0636\u063A\u0648\u0637):
|
||||||
settings.downloadOption.1=\u0641\u062A\u062D \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0646\u0627\u0641\u0630\u0629
|
settings.downloadOption.1=\u0641\u062A\u062D \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0646\u0627\u0641\u0630\u0629
|
||||||
settings.downloadOption.2=\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629
|
settings.downloadOption.2=\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629
|
||||||
settings.downloadOption.3=\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u0644\u0641
|
settings.downloadOption.3=\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u0644\u0641
|
||||||
settings.zip=\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u062A\u0639\u062F\u062F \u0627\u0644\u0645\u0636\u063A\u0648\u0637\u0629
|
settings.zipThreshold=\u0645\u0644\u0641\u0627\u062A \u0645\u0636\u063A\u0648\u0637\u0629 \u0639\u0646\u062F \u062A\u062C\u0627\u0648\u0632 \u0639\u062F\u062F \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0645 \u062A\u0646\u0632\u064A\u0644\u0647\u0627
|
||||||
|
|
||||||
#OCR
|
#OCR
|
||||||
OCR.title = OCR
|
ocr.title=\u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 / \u062A\u0646\u0638\u064A\u0641 \u0627\u0644\u0645\u0633\u062D \u0627\u0644\u0636\u0648\u0626\u064A
|
||||||
ocr.header=OCR (\u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u0623\u062D\u0631\u0641)
|
ocr.header=\u0645\u0633\u062D \u0627\u0644\u0645\u0633\u062D \u0627\u0644\u0636\u0648\u0626\u064A / \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 (\u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641)
|
||||||
ocr.selectText.1=\u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0644\u063A\u0627\u062A \u0627\u0644\u062A\u064A \u0633\u064A\u062A\u0645 \u0627\u0643\u062A\u0634\u0627\u0641\u0647\u0627 \u062F\u0627\u062E\u0644 PDF (\u0627\u0644\u0644\u063A\u0627\u062A \u0627\u0644\u0645\u062F\u0631\u062C\u0629 \u0647\u064A \u062A\u0644\u0643 \u0627\u0644\u0645\u0643\u062A\u0634\u0641\u0629 \u062D\u0627\u0644\u064A\u0627):
|
ocr.selectText.1=\u062D\u062F\u062F \u0627\u0644\u0644\u063A\u0627\u062A \u0627\u0644\u062A\u064A \u0633\u064A\u062A\u0645 \u0627\u0643\u062A\u0634\u0627\u0641\u0647\u0627 \u062F\u0627\u062E\u0644 \u0645\u0644\u0641 PDF (\u0627\u0644\u0644\u063A\u0627\u062A \u0627\u0644\u0645\u062F\u0631\u062C\u0629 \u0647\u064A \u062A\u0644\u0643 \u0627\u0644\u062A\u064A \u062A\u0645 \u0627\u0643\u062A\u0634\u0627\u0641\u0647\u0627 \u062D\u0627\u0644\u064A\u064B\u0627):
|
||||||
ocr.selectText.2=\u0625\u0646\u062A\u0627\u062C \u0645\u0644\u0641 \u0646\u0635\u064A \u064A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 \u0646\u0635 OCR \u062C\u0646\u0628\u0627 \u0625\u0644\u0649 \u062C\u0646\u0628 \u0645\u0639 \u0645\u0644\u0641 PDF OCR'ed
|
ocr.selectText.2=\u0625\u0646\u062A\u0627\u062C \u0645\u0644\u0641 \u0646\u0635\u064A \u064A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 \u0646\u0635 OCR \u0628\u062C\u0627\u0646\u0628 \u0645\u0644\u0641 PDF \u0627\u0644\u0630\u064A \u062A\u0645 \u0625\u0639\u062F\u0627\u062F\u0647 \u0628\u0648\u0627\u0633\u0637\u0629 OCR
|
||||||
|
ocr.selectText.3=\u062A\u0645 \u0645\u0633\u062D \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u0635\u062D\u064A\u062D\u0629 \u0636\u0648\u0626\u064A\u064B\u0627 \u0628\u0632\u0627\u0648\u064A\u0629 \u0645\u0646\u062D\u0631\u0641\u0629 \u0639\u0646 \u0637\u0631\u064A\u0642 \u062A\u062F\u0648\u064A\u0631\u0647\u0627 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649 \u0641\u064A \u0645\u0643\u0627\u0646\u0647\u0627
|
||||||
|
ocr.selectText.4=\u0635\u0641\u062D\u0629 \u0646\u0638\u064A\u0641\u0629 \u0644\u0630\u0644\u0643 \u0645\u0646 \u063A\u064A\u0631 \u0627\u0644\u0645\u062D\u062A\u0645\u0644 \u0623\u0646 \u064A\u062C\u062F OCR \u0646\u0635\u064B\u0627 \u0641\u064A \u0636\u0648\u0636\u0627\u0621 \u0627\u0644\u062E\u0644\u0641\u064A\u0629. (\u0644\u0627 \u064A\u0648\u062C\u062F \u062A\u063A\u064A\u064A\u0631 \u0641\u064A \u0627\u0644\u0625\u062E\u0631\u0627\u062C)
|
||||||
|
ocr.selectText.5=\u0635\u0641\u062D\u0629 \u0646\u0638\u064A\u0641\u0629 \u060C \u0644\u0630\u0644\u0643 \u0645\u0646 \u063A\u064A\u0631 \u0627\u0644\u0645\u062D\u062A\u0645\u0644 \u0623\u0646 \u064A\u062C\u062F OCR \u0646\u0635\u064B\u0627 \u0641\u064A \u0636\u0648\u0636\u0627\u0621 \u0627\u0644\u062E\u0644\u0641\u064A\u0629 \u060C \u0648\u064A\u062D\u0627\u0641\u0638 \u0639\u0644\u0649 \u0627\u0644\u062A\u0646\u0638\u064A\u0641 \u0641\u064A \u0627\u0644\u0625\u062E\u0631\u0627\u062C.
|
||||||
|
ocr.selectText.6=\u064A\u062A\u062C\u0627\u0647\u0644 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 \u0646\u0635 \u062A\u0641\u0627\u0639\u0644\u064A \u060C \u0641\u0642\u0637 \u0635\u0641\u062D\u0627\u062A OCRs \u0627\u0644\u062A\u064A \u0647\u064A \u0635\u0648\u0631
|
||||||
|
ocr.selectText.7=\u0641\u0631\u0636 \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 \u060C \u0633\u064A\u0624\u062F\u064A \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641 \u0639\u0644\u0649 \u0643\u0644 \u0635\u0641\u062D\u0629 \u0625\u0644\u0649 \u0625\u0632\u0627\u0644\u0629 \u062C\u0645\u064A\u0639 \u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0646\u0635 \u0627\u0644\u0623\u0635\u0644\u064A
|
||||||
|
ocr.selectText.8=\u0639\u0627\u062F\u064A (\u062E\u0637\u0623 \u0625\u0630\u0627 \u0643\u0627\u0646 PDF \u064A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 \u0646\u0635)
|
||||||
|
ocr.selectText.9=\u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0625\u0636\u0627\u0641\u064A\u0629
|
||||||
|
ocr.selectText.10=\u0648\u0636\u0639 \u0627\u0644\u062A\u0639\u0631\u0641 \u0627\u0644\u0636\u0648\u0626\u064A \u0639\u0644\u0649 \u0627\u0644\u062D\u0631\u0648\u0641
|
||||||
ocr.help=\u064A\u0631\u062C\u0649 \u0642\u0631\u0627\u0621\u0629 \u0647\u0630\u0647 \u0627\u0644\u0648\u062B\u0627\u0626\u0642 \u062D\u0648\u0644 \u0643\u064A\u0641\u064A\u0629 \u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0647\u0630\u0627 \u0644\u0644\u063A\u0627\u062A \u0623\u062E\u0631\u0649 \u0648 / \u0623\u0648 \u0627\u0644\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0644\u064A\u0633 \u0641\u064A \u0639\u0627\u0645\u0644 \u0627\u0644\u0625\u0631\u0633\u0627\u0621
|
ocr.help=\u064A\u0631\u062C\u0649 \u0642\u0631\u0627\u0621\u0629 \u0647\u0630\u0647 \u0627\u0644\u0648\u062B\u0627\u0626\u0642 \u062D\u0648\u0644 \u0643\u064A\u0641\u064A\u0629 \u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0647\u0630\u0627 \u0644\u0644\u063A\u0627\u062A \u0623\u062E\u0631\u0649 \u0648 / \u0623\u0648 \u0627\u0644\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0644\u064A\u0633 \u0641\u064A \u0639\u0627\u0645\u0644 \u0627\u0644\u0625\u0631\u0633\u0627\u0621
|
||||||
ocr.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0648 Tesseract \u0644 OCR.
|
ocr.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0648 Tesseract \u0644 OCR.
|
||||||
ocr.submit = \u0645\u0639\u0627\u0644\u062C\u0629 PDF \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 OCR
|
ocr.submit=\u0645\u0639\u0627\u0644\u062C\u0629 PDF \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 OCR
|
||||||
|
|
||||||
|
|
||||||
extractImages.title=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
|
extractImages.title=\u0627\u0633\u062A\u062E\u0631\u0627\u062C \u0627\u0644\u0635\u0648\u0631
|
||||||
@@ -123,12 +150,20 @@ fileToPDF.submit=\u062A\u062D\u0648\u064A\u0644 \u0625\u0644\u0649 PDF
|
|||||||
#Add image
|
#Add image
|
||||||
addImage.title=إضافة صورة
|
addImage.title=إضافة صورة
|
||||||
addImage.header=إضافة صورة إلى PDF (العمل قيد التقدم)
|
addImage.header=إضافة صورة إلى PDF (العمل قيد التقدم)
|
||||||
|
addImage.everyPage=كل صفحة؟
|
||||||
addImage.submit=إضافة صورة
|
addImage.submit=إضافة صورة
|
||||||
|
|
||||||
#compress
|
#compress
|
||||||
compress.title=ضغط
|
compress.title=ضغط
|
||||||
compress.header=ضغط ملف PDF
|
compress.header=\u0636\u063A\u0637 PDF
|
||||||
compress.compressLevel=القيمة بين 1 و 100 (يتم تقليل 1 إلى أقصى حد)
|
compress.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0644\u0636\u063A\u0637 / \u062A\u062D\u0633\u064A\u0646 PDF.
|
||||||
|
compress.selectText.1=\u0645\u0633\u062A\u0648\u0649 \u0627\u0644\u062A\u062D\u0633\u064A\u0646:
|
||||||
|
compress.selectText.2=0 (\u0628\u062F\u0648\u0646 \u062A\u062D\u0633\u064A\u0646)
|
||||||
|
compress.selectText.3=1 (\u0627\u0641\u062A\u0631\u0627\u0636\u064A\u060C \u062A\u062D\u0633\u064A\u0646 \u0628\u062F\u0648\u0646 \u0641\u0642\u062F\u0627\u0646)
|
||||||
|
compress.selectText.4=2 (\u062A\u062D\u0633\u064A\u0646 \u0636\u064A\u0627\u0639)
|
||||||
|
compress.selectText.5=3 (\u062A\u062D\u0633\u064A\u0646 \u0636\u064A\u0627\u0639 \u060C \u0623\u0643\u062B\u0631 \u0639\u062F\u0648\u0627\u0646\u064A\u0629)
|
||||||
|
compress.selectText.6=\u062A\u0645\u0643\u064A\u0646 \u0639\u0631\u0636 \u0627\u0644\u0648\u064A\u0628 \u0627\u0644\u0633\u0631\u064A\u0639 (\u062E\u0637\u064A PDF)
|
||||||
|
compress.selectText.7=\u062A\u0645\u0643\u064A\u0646 \u062A\u0631\u0645\u064A\u0632 JBIG2 \u0627\u0644\u0645\u0641\u0642\u0648\u062F
|
||||||
compress.submit=ضغط
|
compress.submit=ضغط
|
||||||
|
|
||||||
|
|
||||||
@@ -177,18 +212,23 @@ split.submit=Split
|
|||||||
imageToPDF.title=صورة إلى PDF
|
imageToPDF.title=صورة إلى PDF
|
||||||
imageToPDF.header=صورة إلى PDF
|
imageToPDF.header=صورة إلى PDF
|
||||||
imageToPDF.submit=تحول
|
imageToPDF.submit=تحول
|
||||||
|
imageToPDF.selectText.1=\u062A\u0645\u062F\u062F \u0644\u0644\u0645\u0644\u0627\u0621\u0645\u0629
|
||||||
|
imageToPDF.selectText.2=\u062F\u0648\u0631\u0627\u0646 PDF \u062A\u0644\u0642\u0627\u0626\u064A\u064B\u0627
|
||||||
|
imageToPDF.selectText.3=\u0627\u0644\u0645\u0646\u0637\u0642 \u0627\u0644\u0645\u062A\u0639\u062F\u062F \u0644\u0644\u0645\u0644\u0641\u0627\u062A (\u0645\u0641\u0639\u0651\u0644 \u0641\u0642\u0637 \u0625\u0630\u0627 \u0643\u0646\u062A \u062A\u0639\u0645\u0644 \u0645\u0639 \u0635\u0648\u0631 \u0645\u062A\u0639\u062F\u062F\u0629)
|
||||||
|
imageToPDF.selectText.4=\u062F\u0645\u062C \u0641\u064A \u0645\u0644\u0641 PDF \u0648\u0627\u062D\u062F
|
||||||
|
imageToPDF.selectText.5=\u062A\u062D\u0648\u064A\u0644 \u0625\u0644\u0649 \u0645\u0644\u0641\u0627\u062A PDF \u0645\u0646\u0641\u0635\u0644\u0629
|
||||||
|
|
||||||
#pdfToImage
|
#pdfToImage
|
||||||
pdfToImage.title=تحويل PDF إلى صورة
|
pdfToImage.title=تحويل PDF إلى صورة
|
||||||
pdfToImage.header=تحويل PDF إلى صورة
|
pdfToImage.header=تحويل PDF إلى صورة
|
||||||
pdfToImage.selectText=تنسيق الصورة
|
pdfToImage.selectText=تنسيق الصورة
|
||||||
pdfToImage.singleOrMultiple = \u0646\u0648\u0639 \u0646\u062A\u064A\u062C\u0629 \u0627\u0644\u0635\u0648\u0631\u0629
|
pdfToImage.singleOrMultiple=\u0646\u0648\u0639 \u0646\u062A\u064A\u062C\u0629 \u0627\u0644\u0635\u0648\u0631\u0629
|
||||||
pdfToImage.single = \u0635\u0648\u0631\u0629 \u0648\u0627\u062D\u062F\u0629 \u0643\u0628\u064A\u0631\u0629
|
pdfToImage.single=\u0635\u0648\u0631\u0629 \u0648\u0627\u062D\u062F\u0629 \u0643\u0628\u064A\u0631\u0629
|
||||||
pdfToImage.multi = \u0635\u0648\u0631 \u0645\u062A\u0639\u062F\u062F\u0629
|
pdfToImage.multi=\u0635\u0648\u0631 \u0645\u062A\u0639\u062F\u062F\u0629
|
||||||
pdfToImage.colorType = \u0646\u0648\u0639 \u0627\u0644\u0644\u0648\u0646
|
pdfToImage.colorType=\u0646\u0648\u0639 \u0627\u0644\u0644\u0648\u0646
|
||||||
pdfToImage.color = \u0627\u0644\u0644\u0648\u0646
|
pdfToImage.color=\u0627\u0644\u0644\u0648\u0646
|
||||||
pdfToImage.grey = \u062A\u062F\u0631\u062C \u0627\u0644\u0631\u0645\u0627\u062F\u064A
|
pdfToImage.grey=\u062A\u062F\u0631\u062C \u0627\u0644\u0631\u0645\u0627\u062F\u064A
|
||||||
pdfToImage.blackwhite = \u0623\u0628\u064A\u0636 \u0648\u0623\u0633\u0648\u062F (\u0642\u062F \u064A\u0641\u0642\u062F \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A!)
|
pdfToImage.blackwhite=\u0623\u0628\u064A\u0636 \u0648\u0623\u0633\u0648\u062F (\u0642\u062F \u064A\u0641\u0642\u062F \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A!)
|
||||||
pdfToImage.submit=تحول
|
pdfToImage.submit=تحول
|
||||||
|
|
||||||
#addPassword
|
#addPassword
|
||||||
@@ -218,14 +258,15 @@ watermark.selectText.3=حجم الخط:
|
|||||||
watermark.selectText.4=دوران (0-360):
|
watermark.selectText.4=دوران (0-360):
|
||||||
watermark.selectText.5=widthSpacer (مسافة بين كل علامة مائية أفقيًا):
|
watermark.selectText.5=widthSpacer (مسافة بين كل علامة مائية أفقيًا):
|
||||||
watermark.selectText.6=heightSpacer (مسافة بين كل علامة مائية عموديًا):
|
watermark.selectText.6=heightSpacer (مسافة بين كل علامة مائية عموديًا):
|
||||||
|
watermark.selectText.7=\u0627\u0644\u062A\u0639\u062A\u064A\u0645 (0\u066A - 100\u066A):
|
||||||
watermark.submit=إضافة علامة مائية
|
watermark.submit=إضافة علامة مائية
|
||||||
|
|
||||||
#remove-watermark
|
#remove-watermark
|
||||||
remove-watermark.title = \u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
remove-watermark.title=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
||||||
remove-watermark.header = \u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
remove-watermark.header=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
||||||
remove-watermark.selectText.1 = \u062D\u062F\u062F PDF \u0644\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629 \u0645\u0646:
|
remove-watermark.selectText.1=\u062D\u062F\u062F PDF \u0644\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629 \u0645\u0646:
|
||||||
remove-watermark.selectText.2 = \u0646\u0635 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629:
|
remove-watermark.selectText.2=\u0646\u0635 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629:
|
||||||
remove-watermark.submit = \u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
remove-watermark.submit=\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0627\u0626\u064A\u0629
|
||||||
|
|
||||||
#Change permissions
|
#Change permissions
|
||||||
permissions.title=تغيير الأذونات
|
permissions.title=تغيير الأذونات
|
||||||
@@ -250,27 +291,63 @@ removePassword.selectText.1=حدد PDF لفك التشفير
|
|||||||
removePassword.selectText.2=كلمة المرور
|
removePassword.selectText.2=كلمة المرور
|
||||||
removePassword.submit=إزالة
|
removePassword.submit=إزالة
|
||||||
|
|
||||||
changeMetadata.title = \u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
changeMetadata.title=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
||||||
changeMetadata.header = \u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
changeMetadata.header=\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0648\u0635\u0641\u064A\u0629
|
||||||
changeMetadata.selectText.1 = \u064A\u0631\u062C\u0649 \u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0645\u062A\u063A\u064A\u0631\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0631\u063A\u0628 \u0641\u064A \u062A\u063A\u064A\u064A\u0631\u0647\u0627
|
changeMetadata.selectText.1=\u064A\u0631\u062C\u0649 \u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0645\u062A\u063A\u064A\u0631\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0631\u063A\u0628 \u0641\u064A \u062A\u063A\u064A\u064A\u0631\u0647\u0627
|
||||||
changeMetadata.selectText.2 = \u062D\u0630\u0641 \u0643\u0644 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0623\u0648\u0644\u064A\u0629
|
changeMetadata.selectText.2=\u062D\u0630\u0641 \u0643\u0644 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0623\u0648\u0644\u064A\u0629
|
||||||
changeMetadata.selectText.3 = \u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0623\u0648\u0644\u064A\u0629 \u0627\u0644\u0645\u062E\u0635\u0635\u0629:
|
changeMetadata.selectText.3=\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0623\u0648\u0644\u064A\u0629 \u0627\u0644\u0645\u062E\u0635\u0635\u0629:
|
||||||
changeMetadata.author = \u0627\u0644\u0645\u0624\u0644\u0641:
|
changeMetadata.author=\u0627\u0644\u0645\u0624\u0644\u0641:
|
||||||
changeMetadata.creationDate = \u062A\u0627\u0631\u064A\u062E \u0627\u0644\u0625\u0646\u0634\u0627\u0621 (yyyy / MM / dd HH: mm: ss):
|
changeMetadata.creationDate=\u062A\u0627\u0631\u064A\u062E \u0627\u0644\u0625\u0646\u0634\u0627\u0621 (yyyy / MM / dd HH: mm: ss):
|
||||||
changeMetadata.creator = \u0627\u0644\u0645\u0646\u0634\u0626:
|
changeMetadata.creator=\u0627\u0644\u0645\u0646\u0634\u0626:
|
||||||
changeMetadata.keywords = \u0627\u0644\u0643\u0644\u0645\u0627\u062A \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629:
|
changeMetadata.keywords=\u0627\u0644\u0643\u0644\u0645\u0627\u062A \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629:
|
||||||
changeMetadata.modDate = \u062A\u0627\u0631\u064A\u062E \u0627\u0644\u062A\u0639\u062F\u064A\u0644 (yyyy / MM / dd HH: mm: ss):
|
changeMetadata.modDate=\u062A\u0627\u0631\u064A\u062E \u0627\u0644\u062A\u0639\u062F\u064A\u0644 (yyyy / MM / dd HH: mm: ss):
|
||||||
changeMetadata.producer = \u0627\u0644\u0645\u0646\u062A\u062C:
|
changeMetadata.producer=\u0627\u0644\u0645\u0646\u062A\u062C:
|
||||||
changeMetadata.subject = \u0627\u0644\u0645\u0648\u0636\u0648\u0639:
|
changeMetadata.subject=\u0627\u0644\u0645\u0648\u0636\u0648\u0639:
|
||||||
changeMetadata.title = \u0627\u0644\u0639\u0646\u0648\u0627\u0646:
|
changeMetadata.title=\u0627\u0644\u0639\u0646\u0648\u0627\u0646:
|
||||||
changeMetadata.trapped = \u0645\u062D\u0627\u0635\u0631:
|
changeMetadata.trapped=\u0645\u062D\u0627\u0635\u0631:
|
||||||
changeMetadata.selectText.4 = \u0628\u064A\u0627\u0646\u0627\u062A \u0648\u0635\u0641\u064A\u0629 \u0623\u062E\u0631\u0649:
|
changeMetadata.selectText.4=\u0628\u064A\u0627\u0646\u0627\u062A \u0648\u0635\u0641\u064A\u0629 \u0623\u062E\u0631\u0649:
|
||||||
changeMetadata.selectText.5 = \u0625\u0636\u0627\u0641\u0629 \u0625\u062F\u062E\u0627\u0644 \u0628\u064A\u0627\u0646\u0627\u062A \u0623\u0648\u0644\u064A\u0629 \u0645\u062E\u0635\u0635
|
changeMetadata.selectText.5=\u0625\u0636\u0627\u0641\u0629 \u0625\u062F\u062E\u0627\u0644 \u0628\u064A\u0627\u0646\u0627\u062A \u0623\u0648\u0644\u064A\u0629 \u0645\u062E\u0635\u0635
|
||||||
changeMetadata.submit = \u062A\u063A\u064A\u064A\u0631
|
changeMetadata.submit=\u062A\u063A\u064A\u064A\u0631
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xlsToPdf.title = \u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
|
xlsToPdf.title=\u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
|
||||||
xlsToPdf.header = \u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
|
xlsToPdf.header=\u062A\u062D\u0648\u064A\u0644 Excel \u0625\u0644\u0649 PDF
|
||||||
xlsToPdf.selectText.1 = \u062D\u062F\u062F \u0648\u0631\u0642\u0629 \u0625\u0643\u0633\u0644 XLS \u0623\u0648 XLSX \u0644\u0644\u062A\u062D\u0648\u064A\u0644
|
xlsToPdf.selectText.1=\u062D\u062F\u062F \u0648\u0631\u0642\u0629 \u0625\u0643\u0633\u0644 XLS \u0623\u0648 XLSX \u0644\u0644\u062A\u062D\u0648\u064A\u0644
|
||||||
xlsToPdf.convert = \u062A\u062D\u0648\u064A\u0644
|
xlsToPdf.convert=\u062A\u062D\u0648\u064A\u0644
|
||||||
|
|
||||||
|
pdfToPDFA.title=PDF \u0625\u0644\u0649 PDF / A
|
||||||
|
pdfToPDFA.header=PDF \u0625\u0644\u0649 PDF / A
|
||||||
|
pdfToPDFA.credit=\u062A\u0633\u062A\u062E\u062F\u0645 \u0647\u0630\u0647 \u0627\u0644\u062E\u062F\u0645\u0629 OCRmyPDF \u0644\u062A\u062D\u0648\u064A\u0644 PDF / A.
|
||||||
|
pdfToPDFA.submit=\u062A\u062D\u0648\u064A\u0644
|
||||||
|
|
||||||
|
|
||||||
|
PDFToWord.title = تحويل PDF إلى Word
|
||||||
|
PDFToWord.header = تحويل PDF إلى Word
|
||||||
|
PDFToWord.selectText.1 = تنسيق ملف الإخراج
|
||||||
|
PDFToWord.credit = تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
|
||||||
|
PDFToWord.submit = تحويل
|
||||||
|
|
||||||
|
PDFToPresentation.title = PDF للعرض التقديمي
|
||||||
|
PDFToPresentation.header = PDF للعرض التقديمي
|
||||||
|
PDFToPresentation.selectText.1 = تنسيق ملف الإخراج
|
||||||
|
PDFToPresentation.credit = تستخدم هذه الخدمة LibreOffice لتحويل الملف.
|
||||||
|
PDFToPresentation.submit = تحويل
|
||||||
|
|
||||||
|
|
||||||
|
PDFToText.title = تحويل PDF إلى نص / RTF
|
||||||
|
PDFToText.header = تحويل PDF إلى نص / RTF
|
||||||
|
PDFToText.selectText.1 = تنسيق ملف الإخراج
|
||||||
|
PDFToText.credit = تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
|
||||||
|
PDFToText.submit = تحويل
|
||||||
|
|
||||||
|
|
||||||
|
PDFToHTML.title = PDF إلى HTML
|
||||||
|
PDFToHTML.header = PDF إلى HTML
|
||||||
|
PDFToHTML.credit = تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
|
||||||
|
PDFToHTML.submit = تحويل
|
||||||
|
|
||||||
|
PDFToXML.title = تحويل PDF إلى XML
|
||||||
|
PDFToXML.header = تحويل PDF إلى XML
|
||||||
|
PDFToXML.credit = تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
|
||||||
|
PDFToXML.submit = تحويل
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
###########
|
###########
|
||||||
# Generic #
|
# Generic #
|
||||||
###########
|
###########
|
||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
# the direction that the language is written (ltr=left to right, rtl=right to left)
|
||||||
language.direction=ltr
|
language.direction=ltr
|
||||||
|
|
||||||
pdfPrompt=PDF auswählen
|
pdfPrompt=PDF auswählen
|
||||||
@@ -16,7 +16,7 @@ true=Wahr
|
|||||||
false=Falsch
|
false=Falsch
|
||||||
unknown=Unbekannt
|
unknown=Unbekannt
|
||||||
save=Speichern
|
save=Speichern
|
||||||
close=Schließen
|
close=Schließen
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -70,49 +70,76 @@ home.removePassword.desc=Den Passwortschutz eines PDFs entfernen.
|
|||||||
home.compressPdfs.title=PDF komprimieren
|
home.compressPdfs.title=PDF komprimieren
|
||||||
home.compressPdfs.desc=PDF komprimieren um die Dateigröße zu reduzieren.
|
home.compressPdfs.desc=PDF komprimieren um die Dateigröße zu reduzieren.
|
||||||
|
|
||||||
home.changeMetadata.title=Metadaten ändern
|
home.changeMetadata.title=Metadaten ändern
|
||||||
home.changeMetadata.desc=Ändern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument
|
home.changeMetadata.desc=Ändern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument
|
||||||
|
|
||||||
home.fileToPDF.title=Datei in PDF konvertieren
|
home.fileToPDF.title=Datei in PDF konvertieren
|
||||||
home.fileToPDF.desc=Konvertieren Sie nahezu jede Datei in PDF (DOCX, PNG, XLS, PPT, TXT und mehr)
|
home.fileToPDF.desc=Konvertieren Sie nahezu jede Datei in PDF (DOCX, PNG, XLS, PPT, TXT und mehr)
|
||||||
|
|
||||||
home.ocr.title=OCR auf PDF ausführen
|
home.ocr.title=Führe OCR auf PDF- und/oder Cleanup-Scans aus
|
||||||
home.ocr.desc=Scannt und erkennt Text aus Bildern in einer PDF-Datei und fügt ihn erneut als Text hinzu.
|
home.ocr.desc=Cleanup scannt und erkennt Text aus Bildern in einer PDF-Datei und fügt ihn erneut als Text hinzu.
|
||||||
|
|
||||||
home.extractImages.title=Bilder extrahieren
|
home.extractImages.title=Bilder extrahieren
|
||||||
home.extractImages.desc=Extrahiert alle Bilder aus einer PDF-Datei und speichert sie als Zip-Datei
|
home.extractImages.desc=Extrahiert alle Bilder aus einer PDF-Datei und speichert sie als Zip-Datei
|
||||||
|
|
||||||
|
home.pdfToPDFA.title=PDF zu PDF/A konvertieren
|
||||||
|
home.pdfToPDFA.desc=PDF zu PDF/A für Langzeitarchivierung konvertieren
|
||||||
|
|
||||||
|
home.PDFToWord.title=PDF zu Word
|
||||||
|
home.PDFToWord.desc=PDF in Word-Formate konvertieren (DOC, DOCX und ODT)
|
||||||
|
|
||||||
|
home.PDFToPresentation.title=PDF zu Präsentation
|
||||||
|
home.PDFToPresentation.desc=PDF in Präsentationsformate konvertieren (PPT, PPTX und ODP)
|
||||||
|
|
||||||
|
home.PDFToText.title=PDF in Text/RTF
|
||||||
|
home.PDFToText.desc=PDF in Text- oder RTF-Format konvertieren
|
||||||
|
|
||||||
|
home.PDFToHTML.title=PDF in HTML
|
||||||
|
home.PDFToHTML.desc=PDF in HTML-Format konvertieren
|
||||||
|
|
||||||
|
home.PDFToXML.title=PDF in XML
|
||||||
|
home.PDFToXML.desc=PDF in XML-Format konvertieren
|
||||||
|
|
||||||
|
|
||||||
navbar.settings=Einstellungen
|
navbar.settings=Einstellungen
|
||||||
settings.title=Einstellungen
|
settings.title=Einstellungen
|
||||||
settings.update=Update verfügbar
|
settings.update=Update verfügbar
|
||||||
settings.appVersion=App-Version:
|
settings.appVersion=App-Version:
|
||||||
settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind):
|
settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind):
|
||||||
settings.downloadOption.1=Im selben Fenster öffnen
|
settings.downloadOption.1=Im selben Fenster öffnen
|
||||||
settings.downloadOption.2=In neuem Fenster öffnen
|
settings.downloadOption.2=In neuem Fenster öffnen
|
||||||
settings.downloadOption.3=Datei herunterladen
|
settings.downloadOption.3=Datei herunterladen
|
||||||
settings.zip=Dateien mit mehrfachem Download zippen
|
settings.zipThreshold=Dateien komprimieren, wenn die Anzahl der heruntergeladenen Dateien überschritten wird
|
||||||
|
|
||||||
#OCR
|
#OCR
|
||||||
ocr.title=OCR
|
ocr.title=OCR / Scan-Bereinigung
|
||||||
ocr.header=OCR (Optische Zeichenerkennung)
|
ocr.header=Scans bereinigen / OCR (Optical Character Recognition)
|
||||||
ocr.selectText.1=Wählen Sie die Sprachen aus, die in der PDF-Datei erkannt werden sollen (die aufgelisteten sind die aktuell erkannten):
|
ocr.selectText.1=Sprachen auswählen, die im PDF erkannt werden sollen (die aufgelisteten sind die aktuell erkannten):
|
||||||
ocr.selectText.2=Textdatei mit OCR-Text neben der OCR-PDF-Datei erstellen
|
ocr.selectText.2=Textdatei erzeugen, die OCR-Text neben dem OCR-bearbeiteten PDF enthält
|
||||||
ocr.help=Bitte lesen Sie diese Dokumentation, um zu erfahren, wie Sie dies für andere Sprachen verwenden und/oder nicht in Docker verwenden können
|
ocr.selectText.3=Korrekte Seiten wurden in einem schiefen Winkel gescannt, indem sie wieder an ihren Platz gedreht wurden
|
||||||
ocr.credit=Dieser Dienst verwendet OCRmyPDF und Tesseract für OCR.
|
ocr.selectText.4=Seite säubern, daher ist es weniger wahrscheinlich, dass OCR Text im Hintergrundrauschen findet. (Keine Ausgangsänderung)
|
||||||
|
ocr.selectText.5=Seite säubern, sodass es weniger wahrscheinlich ist, dass OCR Text im Hintergrundrauschen findet, Bereinigung der Ausgabe wird beibehalten.
|
||||||
|
ocr.selectText.6=Ignoriert Seiten mit interaktivem Text, nur OCR-Seiten, die Bilder sind
|
||||||
|
ocr.selectText.7=OCR erzwingen, OCR wird jede Seite entfernen und alle ursprünglichen Textelemente entfernen
|
||||||
|
ocr.selectText.8=Normal (Fehler, wenn PDF Text enthält)
|
||||||
|
ocr.selectText.9=Zusätzliche Einstellungen
|
||||||
|
ocr.selectText.10=OCR-Modus
|
||||||
|
ocr.help=Bitte lesen Sie diese Dokumentation, um zu erfahren, wie Sie dies für andere Sprachen verwenden und/oder nicht in Docker verwenden können
|
||||||
|
ocr.credit=Dieser Dienst verwendet OCRmyPDF und Tesseract für OCR.
|
||||||
ocr.submit=PDF mit OCR verarbeiten
|
ocr.submit=PDF mit OCR verarbeiten
|
||||||
|
|
||||||
|
|
||||||
extractImages.title=Bilder extrahieren
|
extractImages.title=Bilder extrahieren
|
||||||
extractImages.header=Bilder extrahieren
|
extractImages.header=Bilder extrahieren
|
||||||
extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen
|
extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen
|
||||||
extractImages.submit=Extrahieren
|
extractImages.submit=Extrahieren
|
||||||
|
|
||||||
|
|
||||||
#File to PDF
|
#File to PDF
|
||||||
fileToPDF.title=Datei in PDF
|
fileToPDF.title=Datei in PDF
|
||||||
fileToPDF.header=Beliebige Dateien in PDF konvertieren
|
fileToPDF.header=Beliebige Dateien in PDF konvertieren
|
||||||
fileToPDF.credit=Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung.
|
fileToPDF.credit=Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung.
|
||||||
fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enthalten, eine vollständige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation
|
fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enthalten, eine vollständige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation
|
||||||
fileToPDF.submit=In PDF konvertieren
|
fileToPDF.submit=In PDF konvertieren
|
||||||
|
|
||||||
|
|
||||||
@@ -122,12 +149,20 @@ fileToPDF.submit=In PDF konvertieren
|
|||||||
#Add image
|
#Add image
|
||||||
addImage.title=Bild hinzufügen
|
addImage.title=Bild hinzufügen
|
||||||
addImage.header=Ein Bild einfügen (Work in progress)
|
addImage.header=Ein Bild einfügen (Work in progress)
|
||||||
|
addImage.everyPage=Jede Seite?
|
||||||
addImage.submit=Bild hinzufügen
|
addImage.submit=Bild hinzufügen
|
||||||
|
|
||||||
#compress
|
#compress
|
||||||
compress.title=Komprimieren
|
compress.title=Komprimieren
|
||||||
compress.header=PDF komprimieren
|
compress.header=PDF komprimieren
|
||||||
compress.compressLevel=Wert zwischen 1 und 100 (1 ist am meisten komprimiert)
|
compress.credit=Dieser Dienst verwendet OCRmyPDF für die PDF-Komprimierung/-Optimierung.
|
||||||
|
compress.selectText.1=Optimierungsstufe:
|
||||||
|
compress.selectText.2=0 (Keine Optimierung)
|
||||||
|
compress.selectText.3=1 (Standard, verlustfreie Optimierung)
|
||||||
|
compress.selectText.4=2 (Verlustbehaftete Optimierung)
|
||||||
|
compress.selectText.5=3 (Verlustbehaftete Optimierung, aggressiver)
|
||||||
|
compress.selectText.6=Schnelle Webansicht aktivieren (PDF linearisieren)
|
||||||
|
compress.selectText.7=Verlustbehaftete JBIG2-Kodierung aktivieren
|
||||||
compress.submit=Komprimieren
|
compress.submit=Komprimieren
|
||||||
|
|
||||||
|
|
||||||
@@ -176,18 +211,23 @@ split.submit=Aufteilen
|
|||||||
imageToPDF.title=Bild zu PDF
|
imageToPDF.title=Bild zu PDF
|
||||||
imageToPDF.header=Bild zu PDF
|
imageToPDF.header=Bild zu PDF
|
||||||
imageToPDF.submit=Umwandeln
|
imageToPDF.submit=Umwandeln
|
||||||
|
imageToPDF.selectText.1=Auf Seite strecken
|
||||||
|
imageToPDF.selectText.2=PDF automatisch drehen
|
||||||
|
imageToPDF.selectText.3=Mehrere Dateien verarbeiten (nur aktiv, wenn Sie mit mehreren Bildern arbeiten)
|
||||||
|
imageToPDF.selectText.4=In ein einziges PDF zusammenführen
|
||||||
|
imageToPDF.selectText.5=In separate PDFs konvertieren
|
||||||
|
|
||||||
#pdfToImage
|
#pdfToImage
|
||||||
pdfToImage.title=PDF zu Bild
|
pdfToImage.title=PDF zu Bild
|
||||||
pdfToImage.header=PDF zu Bild
|
pdfToImage.header=PDF zu Bild
|
||||||
pdfToImage.selectText=Bildformat
|
pdfToImage.selectText=Bildformat
|
||||||
pdfToImage.singleOrMultiple=Bildergebnistyp
|
pdfToImage.singleOrMultiple=Bildergebnistyp
|
||||||
pdfToImage.single=Einzelnes großes Bild
|
pdfToImage.single=Einzelnes großes Bild
|
||||||
pdfToImage.multi=Mehrere Bilder
|
pdfToImage.multi=Mehrere Bilder
|
||||||
pdfToImage.colorType=Farbtyp
|
pdfToImage.colorType=Farbtyp
|
||||||
pdfToImage.color=Farbe
|
pdfToImage.color=Farbe
|
||||||
pdfToImage.grey=Graustufen
|
pdfToImage.grey=Graustufen
|
||||||
pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!)
|
pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!)
|
||||||
pdfToImage.submit=Umwandeln
|
pdfToImage.submit=Umwandeln
|
||||||
|
|
||||||
#addPassword
|
#addPassword
|
||||||
@@ -217,12 +257,13 @@ watermark.selectText.3=Schriftgröße:
|
|||||||
watermark.selectText.4=Drehung (0-360):
|
watermark.selectText.4=Drehung (0-360):
|
||||||
watermark.selectText.5=breiteSpacer (horizontaler Abstand zwischen den einzelnen Wasserzeichen):
|
watermark.selectText.5=breiteSpacer (horizontaler Abstand zwischen den einzelnen Wasserzeichen):
|
||||||
watermark.selectText.6=höheSpacer (vertikaler Abstand zwischen den einzelnen Wasserzeichen):
|
watermark.selectText.6=höheSpacer (vertikaler Abstand zwischen den einzelnen Wasserzeichen):
|
||||||
|
watermark.selectText.7=Deckkraft (0% - 100 %):
|
||||||
watermark.submit=Wasserzeichen hinzufügen
|
watermark.submit=Wasserzeichen hinzufügen
|
||||||
|
|
||||||
#remove-watermark
|
#remove-watermark
|
||||||
remove-watermark.title=Wasserzeichen entfernen
|
remove-watermark.title=Wasserzeichen entfernen
|
||||||
remove-watermark.header=Wasserzeichen entfernen
|
remove-watermark.header=Wasserzeichen entfernen
|
||||||
remove-watermark.selectText.1=PDF auswählen, um Wasserzeichen zu entfernen von:
|
remove-watermark.selectText.1=PDF auswählen, um Wasserzeichen zu entfernen von:
|
||||||
remove-watermark.selectText.2=Wasserzeichentext:
|
remove-watermark.selectText.2=Wasserzeichentext:
|
||||||
remove-watermark.submit=Wasserzeichen entfernen
|
remove-watermark.submit=Wasserzeichen entfernen
|
||||||
|
|
||||||
@@ -250,39 +291,70 @@ removePassword.selectText.2=Passwort
|
|||||||
removePassword.submit=Entfernen
|
removePassword.submit=Entfernen
|
||||||
|
|
||||||
|
|
||||||
changeMetadata.title=Metadaten ändern
|
changeMetadata.title=Metadaten ändern
|
||||||
changeMetadata.header=Metadaten ändern
|
changeMetadata.header=Metadaten ändern
|
||||||
changeMetadata.selectText.1=Bitte bearbeiten Sie die Variablen, die Sie ändern möchten
|
changeMetadata.selectText.1=Bitte bearbeiten Sie die Variablen, die Sie ändern möchten
|
||||||
changeMetadata.selectText.2=Alle Metadaten löschen
|
changeMetadata.selectText.2=Alle Metadaten löschen
|
||||||
changeMetadata.selectText.3=Benutzerdefinierte Metadaten anzeigen:
|
changeMetadata.selectText.3=Benutzerdefinierte Metadaten anzeigen:
|
||||||
changeMetadata.author=Autor:
|
changeMetadata.author=Autor:
|
||||||
changeMetadata.creationDate=Erstellungsdatum (jjjj/MM/tt HH:mm:ss):
|
changeMetadata.creationDate=Erstellungsdatum (jjjj/MM/tt HH:mm:ss):
|
||||||
changeMetadata.creator=Ersteller:
|
changeMetadata.creator=Ersteller:
|
||||||
changeMetadata.keywords=Schlüsselwörter:
|
changeMetadata.keywords=Schlüsselwörter:
|
||||||
changeMetadata.modDate=Änderungsdatum (JJJJ/MM/TT HH:mm:ss):
|
changeMetadata.modDate=Änderungsdatum (JJJJ/MM/TT HH:mm:ss):
|
||||||
changeMetadata.producer=Produzent:
|
changeMetadata.producer=Produzent:
|
||||||
changeMetadata.subject=Betreff:
|
changeMetadata.subject=Betreff:
|
||||||
changeMetadata.title=Titel:
|
changeMetadata.title=Titel:
|
||||||
changeMetadata.trapped=Gefangen:
|
changeMetadata.trapped=Gefangen:
|
||||||
changeMetadata.selectText.4=Andere Metadaten:
|
changeMetadata.selectText.4=Andere Metadaten:
|
||||||
changeMetadata.selectText.5=Benutzerdefinierten Metadateneintrag hinzufügen
|
changeMetadata.selectText.5=Benutzerdefinierten Metadateneintrag hinzufügen
|
||||||
changeMetadata.submit=Ändern
|
changeMetadata.submit=Ändern
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xlsToPdf.title=Excel in PDF
|
xlsToPdf.title=Excel in PDF
|
||||||
xlsToPdf.header=Excel in PDF
|
xlsToPdf.header=Excel in PDF
|
||||||
xlsToPdf.selectText.1=XLS- oder XLSX-Excel-Tabelle zum Konvertieren auswählen
|
xlsToPdf.selectText.1=XLS- oder XLSX-Excel-Tabelle zum Konvertieren auswählen
|
||||||
xlsToPdf.convert=konvertieren
|
xlsToPdf.convert=konvertieren
|
||||||
|
|
||||||
|
|
||||||
|
pdfToPDFA.title=PDF zu PDF/A
|
||||||
|
pdfToPDFA.header=PDF zu PDF/A
|
||||||
|
pdfToPDFA.credit=Dieser Dienst verwendet OCRmyPDF für die PDF/A-Konvertierung
|
||||||
|
pdfToPDFA.submit=Konvertieren
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PDFToWord.title=PDF zu Word
|
||||||
|
PDFToWord.header=PDF zu Word
|
||||||
|
PDFToWord.selectText.1=Ausgabedateiformat
|
||||||
|
PDFToWord.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
|
||||||
|
PDFToWord.submit=Konvertieren
|
||||||
|
|
||||||
|
PDFToPresentation.title=PDF zu Präsentation
|
||||||
|
PDFToPresentation.header=PDF zu Präsentation
|
||||||
|
PDFToPresentation.selectText.1=Ausgabedateiformat
|
||||||
|
PDFToPresentation.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
|
||||||
|
PDFToPresentation.submit=Konvertieren
|
||||||
|
|
||||||
|
|
||||||
|
PDFToText.title=PDF in Text/RTF
|
||||||
|
PDFToText.header=PDF in Text/RTF
|
||||||
|
PDFToText.selectText.1=Ausgabedateiformat
|
||||||
|
PDFToText.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
|
||||||
|
PDFToText.submit=Konvertieren
|
||||||
|
|
||||||
|
|
||||||
|
PDFToHTML.title=PDF in HTML
|
||||||
|
PDFToHTML.header=PDF in HTML
|
||||||
|
PDFToHTML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
|
||||||
|
PDFToHTML.submit=Konvertieren
|
||||||
|
|
||||||
|
PDFToXML.title=PDF in XML
|
||||||
|
PDFToXML.header=PDF in XML
|
||||||
|
PDFToXML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
|
||||||
|
PDFToXML.submit=Konvertieren
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
||||||
language.direction=ltr
|
language.direction=ltr
|
||||||
|
|
||||||
pdfPrompt=Choose PDF
|
pdfPrompt=Select PDF(s)
|
||||||
multiPdfPrompt=Choose PDFs (2+)
|
multiPdfPrompt=Select PDFs (2+)
|
||||||
multiPdfDropPrompt=Select (or drag & drop) all PDFs you require
|
multiPdfDropPrompt=Select (or drag & drop) all PDFs you require
|
||||||
imgPrompt=Choose Image
|
imgPrompt=Select Image(s)
|
||||||
genericSubmit=Submit
|
genericSubmit=Submit
|
||||||
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
||||||
pageOrderPrompt=Page Order (Enter a comma-separated list of page numbers) :
|
pageOrderPrompt=Page Order (Enter a comma-separated list of page numbers) :
|
||||||
@@ -76,12 +76,31 @@ home.changeMetadata.desc=Change/Remove/Add metadata from a PDF document
|
|||||||
home.fileToPDF.title=Convert file to PDF
|
home.fileToPDF.title=Convert file to PDF
|
||||||
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)
|
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)
|
||||||
|
|
||||||
home.ocr.title=Run OCR on PDF
|
home.ocr.title=Run OCR on PDF and/or Cleanup scans
|
||||||
home.ocr.desc=Scans and detects text from images within a PDF and re-adds it as text.
|
home.ocr.desc=Cleanup scans and detects text from images within a PDF and re-adds it as text.
|
||||||
|
|
||||||
home.extractImages.title=Extract Images
|
home.extractImages.title=Extract Images
|
||||||
home.extractImages.desc=Extracts all images from a PDF and saves them to zip
|
home.extractImages.desc=Extracts all images from a PDF and saves them to zip
|
||||||
|
|
||||||
|
home.pdfToPDFA.title=Convert PDF to PDF/A
|
||||||
|
home.pdfToPDFA.desc=Convert PDF to PDF/A for long-term storage
|
||||||
|
|
||||||
|
home.PDFToWord.title=PDF to Word
|
||||||
|
home.PDFToWord.desc=Convert PDF to Word formats (DOC, DOCX and ODT)
|
||||||
|
|
||||||
|
home.PDFToPresentation.title=PDF to Presentation
|
||||||
|
home.PDFToPresentation.desc=Convert PDF to Presentation formats (PPT, PPTX and ODP)
|
||||||
|
|
||||||
|
home.PDFToText.title=PDF to Text/RTF
|
||||||
|
home.PDFToText.desc=Convert PDF to Text or RTF format
|
||||||
|
|
||||||
|
home.PDFToHTML.title=PDF to HTML
|
||||||
|
home.PDFToHTML.desc=Convert PDF to HTML format
|
||||||
|
|
||||||
|
home.PDFToXML.title=PDF to XML
|
||||||
|
home.PDFToXML.desc=Convert PDF to XML format
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
navbar.settings=Settings
|
navbar.settings=Settings
|
||||||
settings.title=Settings
|
settings.title=Settings
|
||||||
@@ -91,17 +110,30 @@ settings.downloadOption.title=Choose download option (For single file non zip do
|
|||||||
settings.downloadOption.1=Open in same window
|
settings.downloadOption.1=Open in same window
|
||||||
settings.downloadOption.2=Open in new window
|
settings.downloadOption.2=Open in new window
|
||||||
settings.downloadOption.3=Download file
|
settings.downloadOption.3=Download file
|
||||||
settings.zip=Zip multi-download files
|
settings.zipThreshold=Zip files when the number of downloaded files exceeds
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#OCR
|
#OCR
|
||||||
ocr.title=OCR
|
ocr.title=OCR / Scan Cleanup
|
||||||
ocr.header=OCR (Optical Character Recognition)
|
ocr.header=Cleanup Scans / OCR (Optical Character Recognition)
|
||||||
ocr.selectText.1=Select languages that are to be detected within the PDF (Ones listed are the ones currently detected):
|
ocr.selectText.1=Select languages that are to be detected within the PDF (Ones listed are the ones currently detected):
|
||||||
ocr.selectText.2=Produce text file containing OCR text alongside the OCR'ed PDF
|
ocr.selectText.2=Produce text file containing OCR text alongside the OCR'ed PDF
|
||||||
|
ocr.selectText.3=Correct pages were scanned at a skewed angle by rotating them back into place
|
||||||
|
ocr.selectText.4=Clean page so its less likely that OCR will find text in background noise. (No output change)
|
||||||
|
ocr.selectText.5=Clean page so its less likely that OCR will find text in background noise, maintains cleanup in output.
|
||||||
|
ocr.selectText.6=Ignores pages that have interacive text on them, only OCRs pages that are images
|
||||||
|
ocr.selectText.7=Force OCR, will OCR Every page removing all original text elements
|
||||||
|
ocr.selectText.8=Normal (Will error if PDF contains text)
|
||||||
|
ocr.selectText.9=Additional Settings
|
||||||
|
ocr.selectText.10=OCR Mode
|
||||||
ocr.help=Please read this documentation on how to use this for other languages and/or use not in docker
|
ocr.help=Please read this documentation on how to use this for other languages and/or use not in docker
|
||||||
ocr.credit=This service uses OCRmyPDF and Tesseract for OCR.
|
ocr.credit=This service uses OCRmyPDF and Tesseract for OCR.
|
||||||
ocr.submit=Process PDF with OCR
|
ocr.submit=Process PDF with OCR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extractImages.title=Extract Images
|
extractImages.title=Extract Images
|
||||||
extractImages.header=Extract Images
|
extractImages.header=Extract Images
|
||||||
extractImages.selectText=Select image format to convert extracted images to
|
extractImages.selectText=Select image format to convert extracted images to
|
||||||
@@ -133,6 +165,7 @@ compress.submit=Compress
|
|||||||
#Add image
|
#Add image
|
||||||
addImage.title=Add Image
|
addImage.title=Add Image
|
||||||
addImage.header=Add image to PDF (Work in progress)
|
addImage.header=Add image to PDF (Work in progress)
|
||||||
|
addImage.everyPage=Every Page?
|
||||||
addImage.submit=Add image
|
addImage.submit=Add image
|
||||||
|
|
||||||
|
|
||||||
@@ -181,6 +214,11 @@ split.submit=Split
|
|||||||
imageToPDF.title=Image to PDF
|
imageToPDF.title=Image to PDF
|
||||||
imageToPDF.header=Image to PDF
|
imageToPDF.header=Image to PDF
|
||||||
imageToPDF.submit=Convert
|
imageToPDF.submit=Convert
|
||||||
|
imageToPDF.selectText.1=Stretch to fit
|
||||||
|
imageToPDF.selectText.2=Auto rotate PDF
|
||||||
|
imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images)
|
||||||
|
imageToPDF.selectText.4=Merge into single PDF
|
||||||
|
imageToPDF.selectText.5=Convert to separate PDFs
|
||||||
|
|
||||||
#pdfToImage
|
#pdfToImage
|
||||||
pdfToImage.title=PDF to Image
|
pdfToImage.title=PDF to Image
|
||||||
@@ -222,6 +260,7 @@ watermark.selectText.3=Font Size:
|
|||||||
watermark.selectText.4=Rotation (0-360):
|
watermark.selectText.4=Rotation (0-360):
|
||||||
watermark.selectText.5=widthSpacer (Space between each watermark horizontally):
|
watermark.selectText.5=widthSpacer (Space between each watermark horizontally):
|
||||||
watermark.selectText.6=heightSpacer (Space between each watermark vertically):
|
watermark.selectText.6=heightSpacer (Space between each watermark vertically):
|
||||||
|
watermark.selectText.7=Opacity (0% - 100%):
|
||||||
watermark.submit=Add Watermark
|
watermark.submit=Add Watermark
|
||||||
|
|
||||||
#remove-watermark
|
#remove-watermark
|
||||||
@@ -280,15 +319,42 @@ xlsToPdf.convert=convert
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdfToPDFA.title=PDF To PDF/A
|
||||||
|
pdfToPDFA.header=PDF To PDF/A
|
||||||
|
pdfToPDFA.credit=This service uses OCRmyPDF for PDF/A conversion
|
||||||
|
pdfToPDFA.submit=Convert
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PDFToWord.title=PDF to Word
|
||||||
|
PDFToWord.header=PDF to Word
|
||||||
|
PDFToWord.selectText.1=Output file format
|
||||||
|
PDFToWord.credit=This service uses LibreOffice for file conversion.
|
||||||
|
PDFToWord.submit=Convert
|
||||||
|
|
||||||
|
PDFToPresentation.title=PDF to Presentation
|
||||||
|
PDFToPresentation.header=PDF to Presentation
|
||||||
|
PDFToPresentation.selectText.1=Output file format
|
||||||
|
PDFToPresentation.credit=This service uses LibreOffice for file conversion.
|
||||||
|
PDFToPresentation.submit=Convert
|
||||||
|
|
||||||
|
|
||||||
|
PDFToText.title=PDF to Text/RTF
|
||||||
|
PDFToText.header=PDF to Text/RTF
|
||||||
|
PDFToText.selectText.1=Output file format
|
||||||
|
PDFToText.credit=This service uses LibreOffice for file conversion.
|
||||||
|
PDFToText.submit=Convert
|
||||||
|
|
||||||
|
|
||||||
|
PDFToHTML.title=PDF to HTML
|
||||||
|
PDFToHTML.header=PDF to HTML
|
||||||
|
PDFToHTML.credit=This service uses LibreOffice for file conversion.
|
||||||
|
PDFToHTML.submit=Convert
|
||||||
|
|
||||||
|
PDFToXML.title=PDF to XML
|
||||||
|
PDFToXML.header=PDF to XML
|
||||||
|
PDFToXML.credit=This service uses LibreOffice for file conversion.
|
||||||
|
PDFToXML.submit=Convert
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,285 +0,0 @@
|
|||||||
###########
|
|
||||||
# Generic #
|
|
||||||
###########
|
|
||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
|
||||||
language.direction=ltr
|
|
||||||
|
|
||||||
pdfPrompt=Choose PDF
|
|
||||||
multiPdfPrompt=Choose PDFs (2+)
|
|
||||||
multiPdfDropPrompt=Select (or drag & drop) all PDFs you require
|
|
||||||
imgPrompt=Choose Image
|
|
||||||
genericSubmit=Submit
|
|
||||||
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
|
||||||
pageOrderPrompt=Page Order (Enter a comma-separated list of page numbers) :
|
|
||||||
goToPage=Go
|
|
||||||
true=True
|
|
||||||
false=False
|
|
||||||
unknown=Unknown
|
|
||||||
save=Save
|
|
||||||
close=Close
|
|
||||||
|
|
||||||
#############
|
|
||||||
# HOME-PAGE #
|
|
||||||
#############
|
|
||||||
home.desc=Your locally hosted one-stop-shop for all your PDF needs.
|
|
||||||
|
|
||||||
navbar.convert=Convert
|
|
||||||
navbar.security=Security
|
|
||||||
navbar.other=Other
|
|
||||||
navbar.darkmode=Dark Mode
|
|
||||||
|
|
||||||
home.merge.title=Merge PDFs
|
|
||||||
home.merge.desc=Easily merge multiple PDFs into one.
|
|
||||||
|
|
||||||
home.split.title=Split PDFs
|
|
||||||
home.split.desc=Split PDFs into multiple documents
|
|
||||||
|
|
||||||
home.rotate.title=Rotate PDFs
|
|
||||||
home.rotate.desc=Easily rotate your PDFs.
|
|
||||||
|
|
||||||
home.imageToPdf.title=Image to PDF
|
|
||||||
home.imageToPdf.desc=Convert a images (PNG, JPEG, GIF) to PDF.
|
|
||||||
|
|
||||||
home.pdfToImage.title=PDF to Image
|
|
||||||
home.pdfToImage.desc=Convert a PDF to a image. (PNG, JPEG, GIF)
|
|
||||||
|
|
||||||
home.pdfOrganiser.title=PDF Organizer
|
|
||||||
home.pdfOrganiser.desc=Remove/Rearrange pages in any order
|
|
||||||
|
|
||||||
home.addImage.title=Add image onto PDF
|
|
||||||
home.addImage.desc=Adds a image onto a set location on the PDF (Work in progress)
|
|
||||||
|
|
||||||
home.watermark.title=Add Watermark
|
|
||||||
home.watermark.desc=Add a custom watermark to your PDF document.
|
|
||||||
|
|
||||||
home.remove-watermark.title=Remove Watermark
|
|
||||||
home.remove-watermark.desc=Remove watermarks from your PDF document.
|
|
||||||
|
|
||||||
home.permissions.title=Change Permissions
|
|
||||||
home.permissions.desc=Change the permissions of your PDF document
|
|
||||||
|
|
||||||
home.removePages.title=Remove Pages
|
|
||||||
home.removePages.desc=Delete unwanted pages from your PDF document.
|
|
||||||
|
|
||||||
home.addPassword.title=Add Password
|
|
||||||
home.addPassword.desc=Encrypt your PDF document with a password.
|
|
||||||
|
|
||||||
home.removePassword.title=Remove Password
|
|
||||||
home.removePassword.desc=Remove password protection from your PDF document.
|
|
||||||
|
|
||||||
home.compressPdfs.title=Compress PDFs
|
|
||||||
home.compressPdfs.desc=Compress PDFs to reduce their file size.
|
|
||||||
|
|
||||||
home.changeMetadata.title=Change Metadata
|
|
||||||
home.changeMetadata.desc=Change/Remove/Add metadata from a PDF document
|
|
||||||
|
|
||||||
home.fileToPDF.title=Convert file to PDF
|
|
||||||
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)
|
|
||||||
|
|
||||||
home.ocr.title=Run OCR on PDF
|
|
||||||
home.ocr.desc=Scans and detects text from images within a PDF and re-adds it as text.
|
|
||||||
|
|
||||||
home.extractImages.title=Extract Images
|
|
||||||
home.extractImages.desc=Extracts all images from a PDF and saves them to zip
|
|
||||||
|
|
||||||
|
|
||||||
navbar.settings=Settings
|
|
||||||
settings.title=Settings
|
|
||||||
settings.update=Update available
|
|
||||||
settings.appVersion=App Version:
|
|
||||||
settings.downloadOption.title=Choose download option (For single file non zip downloads):
|
|
||||||
settings.downloadOption.1=Open in same window
|
|
||||||
settings.downloadOption.2=Open in new window
|
|
||||||
settings.downloadOption.3=Download file
|
|
||||||
settings.zip=Zip multi-download files
|
|
||||||
|
|
||||||
#OCR
|
|
||||||
ocr.title=OCR
|
|
||||||
ocr.header=OCR (Optical Character Recognition)
|
|
||||||
ocr.selectText.1=Select languages that are to be detected within the PDF (Ones listed are the ones currently detected):
|
|
||||||
ocr.selectText.2=Produce text file containing OCR text alongside the OCR'ed PDF
|
|
||||||
ocr.help=Please read this documentation on how to use this for other languages and/or use not in docker
|
|
||||||
ocr.credit=This service uses OCRmyPDF and Tesseract for OCR.
|
|
||||||
ocr.submit=Process PDF with OCR
|
|
||||||
|
|
||||||
extractImages.title=Extract Images
|
|
||||||
extractImages.header=Extract Images
|
|
||||||
extractImages.selectText=Select image format to convert extracted images to
|
|
||||||
extractImages.submit=Extract
|
|
||||||
|
|
||||||
|
|
||||||
#File to PDF
|
|
||||||
fileToPDF.title=File to PDF
|
|
||||||
fileToPDF.header=Convert any file to PDF
|
|
||||||
fileToPDF.credit=This service uses LibreOffice and Unoconv for file conversion.
|
|
||||||
fileToPDF.supportedFileTypes=Supported file types should include the below however for a full updated list of supported formats, please refer to the LibreOffice documentation
|
|
||||||
fileToPDF.submit=Convert to PDF
|
|
||||||
|
|
||||||
|
|
||||||
#Add image
|
|
||||||
addImage.title=Add Image
|
|
||||||
addImage.header=Add image to PDF (Work in progress)
|
|
||||||
addImage.submit=Add image
|
|
||||||
|
|
||||||
#compress
|
|
||||||
compress.title=Compress
|
|
||||||
compress.header=Compress PDF
|
|
||||||
compress.compressLevel=Value between 1 and 100 (1 being most reduced)
|
|
||||||
compress.submit=Compress
|
|
||||||
|
|
||||||
|
|
||||||
#merge
|
|
||||||
merge.title=Merge
|
|
||||||
merge.header=Merge multiple PDFs (2+)
|
|
||||||
merge.submit=Merge
|
|
||||||
|
|
||||||
#pdfOrganiser
|
|
||||||
pdfOrganiser.title=Page Organizer
|
|
||||||
pdfOrganiser.header=PDF Page Organizer
|
|
||||||
pdfOrganiser.submit=Rearrange Pages
|
|
||||||
|
|
||||||
|
|
||||||
#pageRemover
|
|
||||||
pageRemover.title=Page Remover
|
|
||||||
pageRemover.header=PDF Page remover
|
|
||||||
pageRemover.pagesToDelete=Pages to delete (Enter a comma-separated list of page numbers) :
|
|
||||||
pageRemover.submit=Delete Pages
|
|
||||||
|
|
||||||
#rotate
|
|
||||||
rotate.title=Rotate PDF
|
|
||||||
rotate.header=Rotate PDF
|
|
||||||
rotate.selectAngle=Select rotation angle (in multiples of 90 degrees):
|
|
||||||
rotate.submit=Rotate
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#merge
|
|
||||||
split.title=Split PDF
|
|
||||||
split.header=Split PDF
|
|
||||||
split.desc.1=The numbers you select are the page number you wish to do a split on
|
|
||||||
split.desc.2=As such selecting 1,3,7-8 would split a 10 page document into 6 separate PDFS with:
|
|
||||||
split.desc.3=Document #1: Page 1
|
|
||||||
split.desc.4=Document #2: Page 2 and 3
|
|
||||||
split.desc.5=Document #3: Page 4, 5 and 6
|
|
||||||
split.desc.6=Document #4: Page 7
|
|
||||||
split.desc.7=Document #5: Page 8
|
|
||||||
split.desc.8=Document #6: Page 9 and 10
|
|
||||||
split.splitPages=Enter pages to split on:
|
|
||||||
split.submit=Split
|
|
||||||
|
|
||||||
|
|
||||||
#merge
|
|
||||||
imageToPDF.title=Image to PDF
|
|
||||||
imageToPDF.header=Image to PDF
|
|
||||||
imageToPDF.submit=Convert
|
|
||||||
|
|
||||||
#pdfToImage
|
|
||||||
pdfToImage.title=PDF to Image
|
|
||||||
pdfToImage.header=PDF to Image
|
|
||||||
pdfToImage.selectText=Image Format
|
|
||||||
pdfToImage.singleOrMultiple=Image result type
|
|
||||||
pdfToImage.single=Single Big Image
|
|
||||||
pdfToImage.multi=Multiple Images
|
|
||||||
pdfToImage.colorType=Color type
|
|
||||||
pdfToImage.color=Color
|
|
||||||
pdfToImage.grey=Grayscale
|
|
||||||
pdfToImage.blackwhite=Black and White (May lose data!)
|
|
||||||
pdfToImage.submit=Convert
|
|
||||||
|
|
||||||
|
|
||||||
#addPassword
|
|
||||||
addPassword.title=Add Password
|
|
||||||
addPassword.header=Add password (Encrypt)
|
|
||||||
addPassword.selectText.1=Select PDF to encrypt
|
|
||||||
addPassword.selectText.2=Password
|
|
||||||
addPassword.selectText.3=Encryption Key Length
|
|
||||||
addPassword.selectText.4=Higher values are stronger, but lower values have better compatibility.
|
|
||||||
addPassword.selectText.5=Permissions to set
|
|
||||||
addPassword.selectText.6=Prevent assembly of document
|
|
||||||
addPassword.selectText.7=Prevent content extraction
|
|
||||||
addPassword.selectText.8=Prevent extraction for accessibility
|
|
||||||
addPassword.selectText.9=Prevent filling in form
|
|
||||||
addPassword.selectText.10=Prevent modification
|
|
||||||
addPassword.selectText.11=Prevent annotation modification
|
|
||||||
addPassword.selectText.12=Prevent printing
|
|
||||||
addPassword.selectText.13=Prevent printing different formats
|
|
||||||
addPassword.submit=Encrypt
|
|
||||||
|
|
||||||
#watermark
|
|
||||||
watermark.title=Add Watermark
|
|
||||||
watermark.header=Add Watermark
|
|
||||||
watermark.selectText.1=Select PDF to add watermark to:
|
|
||||||
watermark.selectText.2=Watermark Text:
|
|
||||||
watermark.selectText.3=Font Size:
|
|
||||||
watermark.selectText.4=Rotation (0-360):
|
|
||||||
watermark.selectText.5=widthSpacer (Space between each watermark horizontally):
|
|
||||||
watermark.selectText.6=heightSpacer (Space between each watermark vertically):
|
|
||||||
watermark.submit=Add Watermark
|
|
||||||
|
|
||||||
#remove-watermark
|
|
||||||
remove-watermark.title=Remove Watermark
|
|
||||||
remove-watermark.header=Remove Watermark
|
|
||||||
remove-watermark.selectText.1=Select PDF to remove watermark from:
|
|
||||||
remove-watermark.selectText.2=Watermark Text:
|
|
||||||
remove-watermark.submit=Remove Watermark
|
|
||||||
|
|
||||||
#Change permissions
|
|
||||||
permissions.title=Change Permissions
|
|
||||||
permissions.header=Change Permissions
|
|
||||||
permissions.warning=Warning to have these permissions be unchangeable it is recommended to set them with a password via the add-password page
|
|
||||||
permissions.selectText.1=Select PDF to change permissions
|
|
||||||
permissions.selectText.2=Permissions to set
|
|
||||||
permissions.selectText.3=Prevent assembly of document
|
|
||||||
permissions.selectText.4=Prevent content extraction
|
|
||||||
permissions.selectText.5=Prevent extraction for accessibility
|
|
||||||
permissions.selectText.6=Prevent filling in form
|
|
||||||
permissions.selectText.7=Prevent modification
|
|
||||||
permissions.selectText.8=Prevent annotation modification
|
|
||||||
permissions.selectText.9=Prevent printing
|
|
||||||
permissions.selectText.10=Prevent printing different formats
|
|
||||||
permissions.submit=Change
|
|
||||||
|
|
||||||
#remove password
|
|
||||||
removePassword.title=Remove password
|
|
||||||
removePassword.header=Remove password (Decrypt)
|
|
||||||
removePassword.selectText.1=Select PDF to Decrypt
|
|
||||||
removePassword.selectText.2=Password
|
|
||||||
removePassword.submit=Remove
|
|
||||||
|
|
||||||
changeMetadata.title=Change Metadata
|
|
||||||
changeMetadata.header=Change Metadata
|
|
||||||
changeMetadata.selectText.1=Please edit the variables you wish to change
|
|
||||||
changeMetadata.selectText.2=Delete all metadata
|
|
||||||
changeMetadata.selectText.3=Show Custom Metadata:
|
|
||||||
changeMetadata.author=Author:
|
|
||||||
changeMetadata.creationDate=Creation Date (yyyy/MM/dd HH:mm:ss):
|
|
||||||
changeMetadata.creator=Creator:
|
|
||||||
changeMetadata.keywords=Keywords:
|
|
||||||
changeMetadata.modDate=Modification Date (yyyy/MM/dd HH:mm:ss):
|
|
||||||
changeMetadata.producer=Producer:
|
|
||||||
changeMetadata.subject=Subject:
|
|
||||||
changeMetadata.title=Title:
|
|
||||||
changeMetadata.trapped=Trapped:
|
|
||||||
changeMetadata.selectText.4=Other Metadata:
|
|
||||||
changeMetadata.selectText.5=Add Custom Metadata Entry
|
|
||||||
changeMetadata.submit=Change
|
|
||||||
|
|
||||||
|
|
||||||
fileToPDF.credit=This service uses LibreOffice and Unoconv for file conversion.
|
|
||||||
fileToPDF.supportedFileTypes=Supported file types should include the below however for a full updated list of supported formats, please refer to the LibreOffice documentation
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
356
src/main/resources/messages_es_ES.properties
Normal file
356
src/main/resources/messages_es_ES.properties
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
###########
|
||||||
|
# Generic #
|
||||||
|
###########
|
||||||
|
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
||||||
|
language.direction=ltr
|
||||||
|
|
||||||
|
pdfPrompt=Selecciona PDF(s)
|
||||||
|
multiPdfPrompt=Selecciona PDFs (2+)
|
||||||
|
multiPdfDropPrompt=Selecciona (o arrastra y suelta) todos los PDFs que quieras
|
||||||
|
imgPrompt=Selecciona Imagen(es)
|
||||||
|
genericSubmit=Enviar
|
||||||
|
processTimeWarning=Advertencia: este proceso puede tardar hasta un minuto dependiendo del tamaño del archivo
|
||||||
|
pageOrderPrompt=Orden de páginas (Introduzca una lista de números de página separados por coma):
|
||||||
|
goToPage=Ir
|
||||||
|
true=Verdadero
|
||||||
|
false=Falso
|
||||||
|
unknown=Desconocido
|
||||||
|
save=Guardar
|
||||||
|
close=Cerrar
|
||||||
|
|
||||||
|
#############
|
||||||
|
# HOME-PAGE #
|
||||||
|
#############
|
||||||
|
home.desc=Tu autohospedada ventanilla única para todas tus necesidades PDF.
|
||||||
|
|
||||||
|
navbar.convert=Convertir
|
||||||
|
navbar.security=Seguridad
|
||||||
|
navbar.other=Otro
|
||||||
|
navbar.darkmode=Modo oscuro
|
||||||
|
|
||||||
|
home.merge.title=Une PDFs
|
||||||
|
home.merge.desc=Unir fácilmente múltiples PDFs en uno.
|
||||||
|
|
||||||
|
home.split.title=Divide PDFs
|
||||||
|
home.split.desc=Divide PDFs en múltiples documentos
|
||||||
|
|
||||||
|
home.rotate.title=Rota PDFs
|
||||||
|
home.rotate.desc=Rota fácilmente tus PDFs.
|
||||||
|
|
||||||
|
home.imageToPdf.title=Imagen a PDF
|
||||||
|
home.imageToPdf.desc=Convierte una imagen (PNG, JPEG, GIF) a PDF.
|
||||||
|
|
||||||
|
home.pdfToImage.title=PDF a Imagen
|
||||||
|
home.pdfToImage.desc=Convierte un PDF a una imagen. (PNG, JPEG, GIF)
|
||||||
|
|
||||||
|
home.pdfOrganiser.title=Organizador PDF
|
||||||
|
home.pdfOrganiser.desc=Elimina/Reorganiza páginas en cualquier orden
|
||||||
|
|
||||||
|
home.addImage.title=Agregar imagen al PDF
|
||||||
|
home.addImage.desc=Agrega una imagen en una ubicación establecida en el PDF (trabajo en progreso)
|
||||||
|
|
||||||
|
home.watermark.title=Añade marca de agua
|
||||||
|
home.watermark.desc=Añade una marca de agua predefinida a tu documento PDF.
|
||||||
|
|
||||||
|
home.remove-watermark.title=Elimina marca de agua
|
||||||
|
home.remove-watermark.desc=Elimina marcas de agua de tu documento PDF.
|
||||||
|
|
||||||
|
home.permissions.title=Cambia Permisos
|
||||||
|
home.permissions.desc=Cambia los permisos de tu documento PDF
|
||||||
|
|
||||||
|
home.removePages.title=Elimina Páginas
|
||||||
|
home.removePages.desc=Elimina páginas no deseadas de tu documento PDF.
|
||||||
|
|
||||||
|
home.addPassword.title=Añade Contraseña
|
||||||
|
home.addPassword.desc=Encripta tu documento PDF con una contraseña.
|
||||||
|
|
||||||
|
home.removePassword.title=Elimina Contraseña
|
||||||
|
home.removePassword.desc=Elimina la contraseña de tu documento PDF.
|
||||||
|
|
||||||
|
home.compressPdfs.title=Comprime PDFs
|
||||||
|
home.compressPdfs.desc=Comprime PDFs para reducir el tamaño del fichero.
|
||||||
|
|
||||||
|
home.changeMetadata.title=Cambia Metadatos
|
||||||
|
home.changeMetadata.desc=Cambia/Elimina/Añade metadatos a tu documento PDF.
|
||||||
|
|
||||||
|
home.fileToPDF.title=Convierte fichero a PDF
|
||||||
|
home.fileToPDF.desc=Convierte casi cualquier archivo a PDF (DOCX, PNG, XLS, PPT, TXT y más)
|
||||||
|
|
||||||
|
home.ocr.title=Ejecute OCR en PDF y/o escaneos de limpieza
|
||||||
|
home.ocr.desc=Escaneos de limpieza y detecta texto de imágenes dentro de un PDF y lo vuelve a agregar como texto.
|
||||||
|
|
||||||
|
home.extractImages.title=Extraer imágenes
|
||||||
|
home.extractImages.desc=Extrae todas las imágenes de un PDF y las guarda en zip
|
||||||
|
|
||||||
|
home.pdfToPDFA.title=Convierte PDF to PDF/A
|
||||||
|
home.pdfToPDFA.desc=Convierte PDF to PDF/A para almacenamiento a largo plazo
|
||||||
|
|
||||||
|
home.PDFToWord.title=PDF a Word
|
||||||
|
home.PDFToWord.desc=Convertir formatos PDF a Word (DOC, DOCX y ODT)
|
||||||
|
|
||||||
|
home.PDFToPresentation.title=PDF a presentación
|
||||||
|
home.PDFToPresentation.desc=Convertir PDF a formatos de presentación (PPT, PPTX y ODP)
|
||||||
|
|
||||||
|
home.PDFToText.title=PDF a texto/RTF
|
||||||
|
home.PDFToText.desc=Convertir PDF a texto o formato RTF
|
||||||
|
|
||||||
|
home.PDFToHTML.title=PDF a HTML
|
||||||
|
home.PDFToHTML.desc=Convertir PDF a formato HTML
|
||||||
|
|
||||||
|
home.PDFToXML.title=PDF a XML
|
||||||
|
home.PDFToXML.desc=Convertir PDF a formato XML
|
||||||
|
|
||||||
|
|
||||||
|
navbar.settings=Ajustes
|
||||||
|
settings.title=Ajustes
|
||||||
|
settings.update=Actualización disponible
|
||||||
|
settings.appVersion=Version de la aplicacion:
|
||||||
|
settings.downloadOption.title=Elija la opción de descarga (para descargas de un solo archivo sin zip):
|
||||||
|
settings.downloadOption.1=Abre en la misma ventana
|
||||||
|
settings.downloadOption.2=Abre en una nueva ventana
|
||||||
|
settings.downloadOption.3=Descarga el fichero
|
||||||
|
settings.zipThreshold=Ficheros Zip cuando excede el número de ficheros descargados
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#OCR
|
||||||
|
ocr.title=OCR / Escaneo de limpieza
|
||||||
|
ocr.header=Escaneos de limpieza / OCR (Reconocimiento óptico de caracteres)
|
||||||
|
ocr.SeleccionaText.1=Selecciona los idiomas que se detectarán en el PDF (Los enumerados son los detectados actualmente):
|
||||||
|
ocr.SeleccionaText.2=Produzca un archivo de texto que contenga texto OCR junto con el PDF editado con OCR
|
||||||
|
ocr.SeleccionaText.3=Corrija las páginas que se escanearon en un ángulo torcido girándolas nuevamente a su lugar
|
||||||
|
ocr.SeleccionaText.4=Limpie la página para que sea menos probable que el OCR encuentre texto en el ruido de fondo. (Sin cambio de salida)
|
||||||
|
ocr.SeleccionaText.5=Limpie la página para que sea menos probable que el OCR encuentre texto en el ruido de fondo, mantiene la limpieza en la salida.
|
||||||
|
ocr.SeleccionaText.6=Ignora las páginas que tienen texto interactivo, solo las páginas OCR que son imágenes
|
||||||
|
ocr.SeleccionaText.7=Fuerza OCR, OCR eliminará en cada página todo el texto original
|
||||||
|
ocr.SeleccionaText.8=Normal (Se producirá un error si el PDF contiene texto)
|
||||||
|
ocr.SeleccionaText.9=Ajustes Adicionales
|
||||||
|
ocr.SeleccionaText.10=Modo OCR
|
||||||
|
ocr.help=Lea esta documentación sobre cómo usar esto para otros idiomas y/o no usarlo en docker
|
||||||
|
ocr.credit=Este servicio utiliza OCRmyPDF y Tesseract para OCR.
|
||||||
|
ocr.submit=Procesa PDF con OCR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extractImages.title=Extraer imágenes
|
||||||
|
extractImages.header=Extraer imágenes
|
||||||
|
extractImages.SeleccionaText=Selecciona el formato de imagen para convertir las imágenes extraÃdas
|
||||||
|
extractImages.submit=Extraer
|
||||||
|
|
||||||
|
|
||||||
|
#File to PDF
|
||||||
|
fileToPDF.title=Fichero a PDF
|
||||||
|
fileToPDF.header=Convierte cualquier fichero 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.submit=Convertir a PDF
|
||||||
|
|
||||||
|
|
||||||
|
#compress
|
||||||
|
compress.title=Comprimir
|
||||||
|
compress.header=Comprimir PDF
|
||||||
|
compress.credit=Este servicio usa OCRmyPDF para la Compresión/Optimizatión del PDF.
|
||||||
|
compress.SeleccionaText.1=Nivel de Optimización:
|
||||||
|
compress.SeleccionaText.2=0 (Sin optimización)
|
||||||
|
compress.SeleccionaText.3=1 (Por defecto, optimización sin pérdidas)
|
||||||
|
compress.SeleccionaText.4=2 (Optimización con pérdida)
|
||||||
|
compress.SeleccionaText.5=3 (Optimización con pérdida, más agresiva)
|
||||||
|
compress.SeleccionaText.6=Habilita la vista web rápida (linealizar PDF)
|
||||||
|
compress.SeleccionaText.7=Habilita la codificación JBIG2 con pérdida
|
||||||
|
compress.submit=Comprimir
|
||||||
|
|
||||||
|
|
||||||
|
#Add image
|
||||||
|
addImage.title=Añade Imagen
|
||||||
|
addImage.header=Añade image de PDF (Trabajo en progreso)
|
||||||
|
addImage.everyPage=¿Todas las páginas?
|
||||||
|
addImage.submit=Añade imagen
|
||||||
|
|
||||||
|
|
||||||
|
#merge
|
||||||
|
merge.title=Mezcla
|
||||||
|
merge.header=Mezcla múltiples PDFs (2+)
|
||||||
|
merge.submit=Mezcla
|
||||||
|
|
||||||
|
#pdfOrganiser
|
||||||
|
pdfOrganiser.title=Organizador de páginas
|
||||||
|
pdfOrganiser.header=Organizador de páginas PDF
|
||||||
|
pdfOrganiser.submit=Organiza páginas
|
||||||
|
|
||||||
|
|
||||||
|
#pageRemover
|
||||||
|
pageRemover.title=Eliminador de páginas
|
||||||
|
pageRemover.header=Eliminador de páginas PDF
|
||||||
|
pageRemover.pagesToDelete=Páginas a eliminar (Introduzca una lista de números de página separados por coma):
|
||||||
|
pageRemover.submit=Elimina Páginas
|
||||||
|
|
||||||
|
#rotate
|
||||||
|
rotate.title=Rotar PDF
|
||||||
|
rotate.header=Rotar PDF
|
||||||
|
rotate.SeleccionaAngle=Selecciona ángulo de rotación (múltiple de 90 grados):
|
||||||
|
rotate.submit=Rotar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#merge
|
||||||
|
split.title=Dividir PDF
|
||||||
|
split.header=Dividir PDF
|
||||||
|
split.desc.1=Los números que selecciona son el número de página en el que desea hacer una división
|
||||||
|
split.desc.2=Como tal, seleccionar 1,3,7-8 dividirÃa un documento de 10 páginas en 6 archivos PDF separados con:
|
||||||
|
split.desc.3=Documento #1: Page 1
|
||||||
|
split.desc.4=Documento #2: Page 2 and 3
|
||||||
|
split.desc.5=Documento #3: Page 4, 5 and 6
|
||||||
|
split.desc.6=Documento #4: Page 7
|
||||||
|
split.desc.7=Documento #5: Page 8
|
||||||
|
split.desc.8=Documento #6: Page 9 and 10
|
||||||
|
split.splitPages=Introduzca las páginas para dividir en:
|
||||||
|
split.submit=Dividir
|
||||||
|
|
||||||
|
|
||||||
|
#merge
|
||||||
|
imageToPDF.title=Imagen a PDF
|
||||||
|
imageToPDF.header=Imagen a PDF
|
||||||
|
imageToPDF.submit=Convertir
|
||||||
|
imageToPDF.SeleccionaText.1=Estirar para ajustar
|
||||||
|
imageToPDF.SeleccionaText.2=Auto rotación PDF
|
||||||
|
imageToPDF.SeleccionaText.3=Lógica de archivos múltiples (Únicamente activado si funciona con multiples imágenes)
|
||||||
|
imageToPDF.SeleccionaText.4=Une en un único PDF
|
||||||
|
imageToPDF.SeleccionaText.5=Convertir a PDFs separados
|
||||||
|
|
||||||
|
#pdfToImage
|
||||||
|
pdfToImage.title=PDF a Imagen
|
||||||
|
pdfToImage.header=PDF a Imagen
|
||||||
|
pdfToImage.SeleccionaText=Formato de Imagen
|
||||||
|
pdfToImage.singleOrMultiple=Tipo resultante de imagen
|
||||||
|
pdfToImage.single=Imagen Grande Única
|
||||||
|
pdfToImage.multi=Múltiples Imágenes
|
||||||
|
pdfToImage.colorType=Tipo de color
|
||||||
|
pdfToImage.color=Color
|
||||||
|
pdfToImage.grey=Escala de Grises
|
||||||
|
pdfToImage.blackwhite=Blanco y Negro (¡Puedes perder datos!)
|
||||||
|
pdfToImage.submit=Convertir
|
||||||
|
|
||||||
|
#addPassword
|
||||||
|
addPassword.title=Añade Contraseña
|
||||||
|
addPassword.header=Añade contraseña (Encripta)
|
||||||
|
addPassword.SeleccionaText.1=Selecciona PDF para encriptar
|
||||||
|
addPassword.SeleccionaText.2=Contraseña
|
||||||
|
addPassword.SeleccionaText.3=Longitud de la clave de cifrado
|
||||||
|
addPassword.SeleccionaText.4=Valores altos son más fuertes, pero valores bajos tienen mejor compatibilidad.
|
||||||
|
addPassword.SeleccionaText.5=Permisos para establecer
|
||||||
|
addPassword.SeleccionaText.6=Impedir el ensamblaje del documento
|
||||||
|
addPassword.SeleccionaText.7=Impedir la extracción de contenido
|
||||||
|
addPassword.SeleccionaText.8=Impedir la extracción para la accesibilidad
|
||||||
|
addPassword.SeleccionaText.9=Impedir rellenar formulario
|
||||||
|
addPassword.SeleccionaText.10=Impedir modificación
|
||||||
|
addPassword.SeleccionaText.11=Impedir modificación de anotaciones
|
||||||
|
addPassword.SeleccionaText.12=Impedir imprimir
|
||||||
|
addPassword.SeleccionaText.13=Impedir imprimir diferentes formatos
|
||||||
|
addPassword.submit=Encripta
|
||||||
|
|
||||||
|
#watermark
|
||||||
|
watermark.title=Añade marca de agua
|
||||||
|
watermark.header=Añade marca de agua
|
||||||
|
watermark.SeleccionaText.1=Selecciona PDF para añadir marca de agua:
|
||||||
|
watermark.SeleccionaText.2=Texto de la marca de agua:
|
||||||
|
watermark.SeleccionaText.3=Tamaño de la Fuente:
|
||||||
|
watermark.SeleccionaText.4=Rotación (0-360):
|
||||||
|
watermark.SeleccionaText.5=Ancho (Espacio entre cada marca de agua horizontalmente):
|
||||||
|
watermark.SeleccionaText.6=Alto (Espacio entre cada marca de agua verticalmente):
|
||||||
|
watermark.SeleccionaText.7=Opacidad (0% - 100%):
|
||||||
|
watermark.submit=Añade marca de agua
|
||||||
|
|
||||||
|
#remove-watermark
|
||||||
|
remove-watermark.title=Elimina marca de agua
|
||||||
|
remove-watermark.header=Elimina marca de agua
|
||||||
|
remove-watermark.SeleccionaText.1=Selecciona PDF para eliminar la marca de agua:
|
||||||
|
remove-watermark.SeleccionaText.2=Texto de la marca de agua:
|
||||||
|
remove-watermark.submit=Elimina marca de agua
|
||||||
|
|
||||||
|
#Change permissions
|
||||||
|
permissions.title=Cambiar Permisos
|
||||||
|
permissions.header=Cambiar Permisos
|
||||||
|
permissions.warning=Advertencia para que estos permisos no se puedan cambiar, se recomienda configurarlos con una contraseña a través de la página de cambio de contraseña
|
||||||
|
permissions.SeleccionaText.1=Selecciona PDF para cambiar los permisos
|
||||||
|
permissions.SeleccionaText.2=Permisos a establecer
|
||||||
|
permissions.SeleccionaText.3=Impedir el ensamblaje del documento
|
||||||
|
permissions.SeleccionaText.4=Impedir la extracción de contenido
|
||||||
|
permissions.SeleccionaText.5=Impedir la extracción para la accesibilidad
|
||||||
|
permissions.SeleccionaText.6=Impedir rellenar formulario
|
||||||
|
permissions.SeleccionaText.7=Impedir modificación
|
||||||
|
permissions.SeleccionaText.8=Impedir modificación de anotaciones
|
||||||
|
permissions.SeleccionaText.9=Impedir imprimir
|
||||||
|
permissions.SeleccionaText.10=Impedir imprimir diferentes formatos
|
||||||
|
permissions.submit=Cambiar
|
||||||
|
|
||||||
|
#remove password
|
||||||
|
removePassword.title=Elimina contraseña
|
||||||
|
removePassword.header=Elimina contraseña (Desencripta)
|
||||||
|
removePassword.SeleccionaText.1=Selecciona PDF para Desencriptar
|
||||||
|
removePassword.SeleccionaText.2=Contraseña
|
||||||
|
removePassword.submit=Elimina
|
||||||
|
|
||||||
|
changeMetadata.title=Cambia Metadatos
|
||||||
|
changeMetadata.header=Cambia Metadatos
|
||||||
|
changeMetadata.SeleccionaText.1=Edite las variables que desea cambiar
|
||||||
|
changeMetadata.SeleccionaText.2=Elimina todos los metadatos
|
||||||
|
changeMetadata.SeleccionaText.3=Mostrar metadatos personalizados:
|
||||||
|
changeMetadata.author=Autor:
|
||||||
|
changeMetadata.creationDate=Fecha de Creación (yyyy/MM/dd HH:mm:ss):
|
||||||
|
changeMetadata.creator=Creador:
|
||||||
|
changeMetadata.keywords=Palabras clave:
|
||||||
|
changeMetadata.modDate=Fecha de Modificación (yyyy/MM/dd HH:mm:ss):
|
||||||
|
changeMetadata.producer=Productor:
|
||||||
|
changeMetadata.subject=Asunto:
|
||||||
|
changeMetadata.title=TÃtulo:
|
||||||
|
changeMetadata.trapped=Trapped:
|
||||||
|
changeMetadata.SeleccionaText.4=Otros Metadatos:
|
||||||
|
changeMetadata.SeleccionaText.5=Agregar entrada de metadatos personalizados
|
||||||
|
changeMetadata.submit=Cambia
|
||||||
|
|
||||||
|
xlsToPdf.title=Excel a PDF
|
||||||
|
xlsToPdf.header=Excel a PDF
|
||||||
|
xlsToPdf.SeleccionaText.1=Selecciona hoja de cálculo de Excel XLS o XLSX para convertir
|
||||||
|
xlsToPdf.convert=convertir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdfToPDFA.title=PDF a PDF/A
|
||||||
|
pdfToPDFA.header=PDF a PDF/A
|
||||||
|
pdfToPDFA.credit=Este servicio usa OCRmyPDF para la conversión a PDF/A
|
||||||
|
pdfToPDFA.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PDFToWord.title=PDF a Word
|
||||||
|
PDFToWord.header=PDF a Word
|
||||||
|
PDFToWord.selectText.1=Formato de archivo de salida
|
||||||
|
PDFToWord.credit=Este servicio utiliza LibreOffice para la conversión de archivos.
|
||||||
|
PDFToWord.submit=Convertir
|
||||||
|
|
||||||
|
PDFToPresentation.title=PDF a presentación
|
||||||
|
PDFToPresentation.header=PDF a presentación
|
||||||
|
PDFToPresentation.selectText.1=Formato de archivo de salida
|
||||||
|
PDFToPresentation.credit=Este servicio utiliza LibreOffice para la conversión de archivos.
|
||||||
|
PDFToPresentation.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
PDFToText.title=PDF a texto/RTF
|
||||||
|
PDFToText.header=PDF a texto/RTF
|
||||||
|
PDFToText.selectText.1=Formato de archivo de salida
|
||||||
|
PDFToText.credit=Este servicio utiliza LibreOffice para la conversión de archivos.
|
||||||
|
PDFToText.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
PDFToHTML.title=PDF a HTML
|
||||||
|
PDFToHTML.header=PDF a HTML
|
||||||
|
PDFToHTML.credit=Este servicio utiliza LibreOffice para la conversión de archivos.
|
||||||
|
PDFToHTML.submit=Convertir
|
||||||
|
|
||||||
|
PDFToXML.title=PDF a XML
|
||||||
|
PDFToXML.header=PDF a XML
|
||||||
|
PDFToXML.credit=Este servicio utiliza LibreOffice para la conversión de archivos.
|
||||||
|
PDFToXML.submit=Convertir
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
###########
|
###########
|
||||||
# Generic #
|
# Generic #
|
||||||
###########
|
###########
|
||||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
# the direction that the language is written (ltr=left to right, rtl=right to left)
|
||||||
language.direction=ltr
|
language.direction=ltr
|
||||||
|
|
||||||
pdfPrompt=Choisir PDF
|
pdfPrompt=Choisir PDF
|
||||||
@@ -13,8 +13,8 @@ multiPdfPrompt=Choisir des PDF (2+)
|
|||||||
multiPdfDropPrompt=Sélectionnez (ou glissez-déposez) tous les PDF dont vous avez besoin
|
multiPdfDropPrompt=Sélectionnez (ou glissez-déposez) tous les PDF dont vous avez besoin
|
||||||
imgPrompt=Choisir une image
|
imgPrompt=Choisir une image
|
||||||
genericSubmit=Soumettre
|
genericSubmit=Soumettre
|
||||||
processTimeWarning=AttentionÂ: ce processus peut prendre jusqu'Ã une minute en fonction de la taille du fichier
|
processTimeWarning=Attention<EFBFBD>: ce processus peut prendre jusqu'à une minute en fonction de la taille du fichier
|
||||||
pageOrderPrompt=Ordre des pages (Entrez une liste de numéros de page séparés par des virgules)Â:
|
pageOrderPrompt=Ordre des pages (Entrez une liste de numéros de page séparés par des virgules):
|
||||||
goToPage=Aller
|
goToPage=Aller
|
||||||
true=Vrai
|
true=Vrai
|
||||||
false=Faux
|
false=Faux
|
||||||
@@ -74,66 +74,98 @@ home.removePassword.desc=Supprimez la protection par mot de passe de votre docum
|
|||||||
home.compressPdfs.title=Compresser les PDF
|
home.compressPdfs.title=Compresser les PDF
|
||||||
home.compressPdfs.desc=Compressez les PDF pour réduire leur taille de fichier.
|
home.compressPdfs.desc=Compressez les PDF pour réduire leur taille de fichier.
|
||||||
|
|
||||||
home.changeMetadata.title=Modifier les métadonnées
|
home.changeMetadata.title=Modifier les métadonnées
|
||||||
home.changeMetadata.desc=Modifier/Supprimer/Ajouter des métadonnées d'un document PDF
|
home.changeMetadata.desc=Modifier/Supprimer/Ajouter des métadonnées d'un document PDF
|
||||||
|
|
||||||
|
|
||||||
home.fileToPDF.title=Convertir un fichier en PDF
|
home.fileToPDF.title=Convertir un fichier en PDF
|
||||||
home.fileToPDF.desc=Convertissez presque n\u2019importe quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT et plus)
|
home.fileToPDF.desc=Convertissez presque n\u2019importe quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT et plus)
|
||||||
|
|
||||||
home.ocr.title=Exécuter OCR sur PDF
|
home.ocr.title=Exécuter l'OCR sur les scans PDF et/ou de nettoyage
|
||||||
home.ocr.desc=Analyse et détecte le texte des images d\u2019un fichier PDF et le rajoute en tant que texte.
|
home.ocr.desc=Le nettoyage analyse et détecte le texte des images dans un PDF et le rajoute en tant que texte.
|
||||||
|
|
||||||
home.extractImages.title=Extraire les images
|
home.extractImages.title=Extraire les images
|
||||||
home.extractImages.desc=Extrait toutes les images d\u2019un PDF et les enregistre au format zip
|
home.extractImages.desc=Extrait toutes les images d\u2019un PDF et les enregistre au format zip
|
||||||
|
|
||||||
|
|
||||||
navbar.settings=Paramètres
|
home.pdfToPDFA.title=Convertir PDF en PDF/A
|
||||||
settings.title=Paramètres
|
home.pdfToPDFA.desc=Convertir un PDF en PDF/A pour un stockage à long terme
|
||||||
settings.update=Mise à jour disponible
|
|
||||||
settings.appVersion=Version de l\u2019application :
|
home.PDFToWord.title=PDF vers Word
|
||||||
settings.downloadOption.title=Choisissez l\u2019option de téléchargement (pour les téléchargements sans fichier unique) :
|
home.PDFToWord.desc=Convertir les formats PDF en Word (DOC, DOCX et ODT)
|
||||||
settings.downloadOption.1=Ouvrir dans la même fenêtre
|
|
||||||
settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre
|
home.PDFToPresentation.title=PDF vers présentation
|
||||||
settings.downloadOption.3=Fichier téléchargé
|
home.PDFToPresentation.desc=Convertir des PDF en formats de présentation (PPT, PPTX et ODP)
|
||||||
settings.zip=Fichiers multi-téléchargements Zip
|
|
||||||
|
home.PDFToText.title=PDF vers texte/RTF
|
||||||
|
home.PDFToText.desc=Convertir un PDF au format Texte ou RTF
|
||||||
|
|
||||||
|
home.PDFToHTML.title=PDF vers HTML
|
||||||
|
home.PDFToHTML.desc=Convertir le PDF au format HTML
|
||||||
|
|
||||||
|
home.PDFToXML.title=PDF vers XML
|
||||||
|
home.PDFToXML.desc=Convertir le PDF au format XML
|
||||||
|
|
||||||
|
navbar.settings=Paramètres
|
||||||
|
settings.title=Paramètres
|
||||||
|
settings.update=Mise à jour disponible
|
||||||
|
settings.appVersion=Version de l'application :
|
||||||
|
settings.downloadOption.title=Choisissez l'option de téléchargement (pour les téléchargements sans fichier unique) :
|
||||||
|
settings.downloadOption.1=Ouvrir dans la même fenêtre
|
||||||
|
settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre
|
||||||
|
settings.downloadOption.3=Fichier téléchargé
|
||||||
|
settings.zipThreshold=Zip les fichiers lorsque le nombre de fichiers téléchargés dépasse
|
||||||
|
|
||||||
|
|
||||||
#OCR
|
#OCR
|
||||||
ocr.title=OCR
|
ocr.title=OCR / Nettoyage de numérisation
|
||||||
ocr.header=OCR (reconnaissance optique de caractères)
|
ocr.header=Nettoyage des scans / OCR (reconnaissance optique des caractères)
|
||||||
ocr.selectText.1=Sélectionnez les langues à détecter dans le fichier PDF (celles répertoriées sont celles actuellement détectées) :
|
ocr.selectText.1=Sélectionnez les langues à détecter dans le PDF (celles répertoriées sont celles actuellement détectées) :
|
||||||
ocr.selectText.2=Produire un fichier texte contenant du texte OCR à côté du PDF OCR
|
ocr.selectText.2=Produire un fichier texte contenant du texte OCR avec le PDF OCR
|
||||||
ocr.help=Veuillez lire cette documentation pour savoir comment l\u2019utiliser pour d\u2019autres langues et/ou une utilisation non dans docker
|
ocr.selectText.3=Les pages correctes ont été numérisées à un angle oblique en les remettant en place
|
||||||
ocr.credit=Ce service utilise OCRmyPDF et Tesseract pour l\u2019OCR.
|
ocr.selectText.4=Nettoyer la page pour qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond. (Pas de changement de sortie)
|
||||||
|
ocr.selectText.5=Nettoyer la page afin qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond, maintient le nettoyage dans la sortie.
|
||||||
|
ocr.selectText.6=Ignore les pages contenant du texte interactif, seulement les pages OCR qui sont des images
|
||||||
|
ocr.selectText.7=Forcer l'OCR, OCR chaque page supprimera tous les éléments de texte d'origine
|
||||||
|
ocr.selectText.8=Normal (Erreur si le PDF contient du texte)
|
||||||
|
ocr.selectText.9=Paramètres supplémentaires
|
||||||
|
ocr.selectText.10=Mode ROC
|
||||||
|
ocr.help=Veuillez lire cette documentation pour savoir comment l'utiliser pour d'autres langues et/ou une utilisation non dans docker
|
||||||
|
ocr.credit=Ce service utilise OCRmyPDF et Tesseract pour l'OCR.
|
||||||
ocr.submit=Traiter PDF avec OCR
|
ocr.submit=Traiter PDF avec OCR
|
||||||
|
|
||||||
|
|
||||||
extractImages.title=Extraire les images
|
extractImages.title=Extraire les images
|
||||||
extractImages.header=Extraire les images
|
extractImages.header=Extraire les images
|
||||||
extractImages.selectText=Sélectionner le format d\u2019image pour convertir les images extraites en
|
extractImages.selectText=Sélectionner le format d'image pour convertir les images extraites en
|
||||||
extractImages.submit=Extrait
|
extractImages.submit=Extraire
|
||||||
|
|
||||||
|
#File to PDF
|
||||||
#File au format PDF
|
fileToPDF.title=Fichier au format PDF
|
||||||
fileToPDF.title=Fichier au PDF
|
fileToPDF.header=Convertir n'importe quel fichier au format PDF
|
||||||
fileToPDF.header=Convertir n\u2019importe quel fichier au format PDF
|
|
||||||
fileToPDF.credit=Ce service utilise LibreOffice et Unoconv pour la conversion de fichiers.
|
fileToPDF.credit=Ce service utilise LibreOffice et Unoconv pour la conversion de fichiers.
|
||||||
fileToPDF.supportedFileTypes=Les types de fichiers pris en charge doivent inclure les éléments ci-dessous, mais pour une liste complète et mise à jour des formats pris en charge, veuillez vous référer à la documentation de LibreOffice
|
fileToPDF.supportedFileTypes=Les types de fichiers pris en charge doivent inclure les éléments ci-dessous, mais pour une liste complète et mise à jour des formats pris en charge, veuillez vous référer à la documentation de LibreOffice.
|
||||||
fileToPDF.submit=Convertir en PDF
|
fileToPDF.submit=Convertir en PDF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Add image
|
#Add image
|
||||||
addImage.title=Ajouter une image
|
addImage.title=Ajouter une image
|
||||||
addImage.header=Ajouter une image au PDF (Travail en cours)
|
addImage.header=Ajouter une image au PDF (Travail en cours)
|
||||||
|
addImage.everyPage=Chaque page?
|
||||||
addImage.submit=Ajouter une image
|
addImage.submit=Ajouter une image
|
||||||
|
|
||||||
#compress
|
#compress
|
||||||
compress.title=Compresser
|
compress.title=Compresser
|
||||||
compress.header=Compresser le PDF
|
compress.header=Compresser le PDF
|
||||||
compress.compressLevel=Valeur entre 1 et 100 (1 étant le plus réduit)
|
compress.credit=Ce service utilise OCRmyPDF pour la compression/optimisation PDF.
|
||||||
|
compress.selectText.1=Niveau d'optimisation :
|
||||||
|
compress.selectText.2=0 (pas d'optimisation)
|
||||||
|
compress.selectText.3=1 (par défaut, optimisation sans perte)
|
||||||
|
compress.selectText.4=2 (optimisation avec perte)
|
||||||
|
compress.selectText.5=3 (optimisation avec perte, plus agressive)
|
||||||
|
compress.selectText.6=Activer l'affichage Web rapide (linéariser PDF)
|
||||||
|
compress.selectText.7=Activer l'encodage JBIG2 avec perte
|
||||||
compress.submit=Compresser
|
compress.submit=Compresser
|
||||||
|
|
||||||
|
|
||||||
@@ -151,49 +183,50 @@ pdfOrganiser.submit=Réorganiser les pages
|
|||||||
#pageRemover
|
#pageRemover
|
||||||
pageRemover.title=Suppresseur de pages
|
pageRemover.title=Suppresseur de pages
|
||||||
pageRemover.header=Outil de suppression de pages PDF
|
pageRemover.header=Outil de suppression de pages PDF
|
||||||
pageRemover.pagesToDelete=Pages à supprimer (Entrez une liste de numéros de page séparés par des virgules)Â:
|
pageRemover.pagesToDelete=Pages à supprimer (Entrez une liste de numéros de page séparés par des virgules):
|
||||||
pageRemover.submit=Supprimer des pages
|
pageRemover.submit=Supprimer des pages
|
||||||
|
|
||||||
#rotate
|
#rotate
|
||||||
rotate.title=Faire pivoter le PDF
|
rotate.title=Faire pivoter le PDF
|
||||||
rotate.header=Faire pivoter le PDF
|
rotate.header=Faire pivoter le PDF
|
||||||
rotate.selectAngle=S\u00e9lectionner l'angle de rotation (en multiples de 90 degr\u00e9s):
|
rotate.selectAngle=Sélectionner l'angle de rotation (en multiples de 90 degrés) :
|
||||||
rotate.submit=Rotation
|
rotate.submit=Rotation
|
||||||
|
|
||||||
|
#Split PDF
|
||||||
|
|
||||||
|
|
||||||
#merge
|
|
||||||
split.title=Fractionner le PDF
|
split.title=Fractionner le PDF
|
||||||
split.header=Diviser le PDF
|
split.header=Diviser le PDF
|
||||||
split.desc.1=Les numéros que vous sélectionnez sont le numéro de page sur lequel vous souhaitez faire un fractionnement
|
split.desc.1=Les numéros que vous sélectionnez sont le numéro de page sur lequel vous souhaitez faire un fractionnement.
|
||||||
split.desc.2=Ainsi, la sélection de 1,3,7-8 diviserait un document de 10 pages en 6 PDF distincts avecÂ:
|
split.desc.2=Ainsi, la sélection de 1,3,7-8 diviserait un document de 10 pages en 6 PDF distincts avec :
|
||||||
split.desc.3=Document #1Â: Page 1
|
split.desc.3=Document #1 : Page 1
|
||||||
split.desc.4=Document #2Â: Pages 2 et 3
|
split.desc.4=Document #2 : Pages 2 et 3
|
||||||
split.desc.5=Document #3Â: Pages 4, 5 et 6
|
split.desc.5=Document #3 : Pages 4, 5 et 6
|
||||||
split.desc.6=Document #4Â: Page 7
|
split.desc.6=Document #4 : Page 7
|
||||||
split.desc.7=Document #5Â: Page 8
|
split.desc.7=Document #5 : Page 8
|
||||||
split.desc.8=Document #6Â: Pages 9 et 10
|
split.desc.8=Document #6 : Pages 9 et 10
|
||||||
split.splitPages=Entrez les pages sur lesquelles fractionnerÂ:
|
split.splitPages=Entrez les pages sur lesquelles fractionner :
|
||||||
split.submit=Diviser
|
split.submit=Diviser
|
||||||
|
|
||||||
|
#imageToPDF
|
||||||
#merge
|
|
||||||
imageToPDF.title=Image au format PDF
|
imageToPDF.title=Image au format PDF
|
||||||
imageToPDF.header=Image au format PDF
|
imageToPDF.header=Image au format PDF
|
||||||
imageToPDF.submit=Convertir
|
imageToPDF.submit=Convertir
|
||||||
|
imageToPDF.selectText.1=Étirer pour s'adapter
|
||||||
|
imageToPDF.selectText.2=Rotation automatique du PDF
|
||||||
|
imageToPDF.selectText.3=Logique de fichiers multiples (activé uniquement si vous travaillez avec plusieurs images)
|
||||||
|
imageToPDF.selectText.4=Fusionner en un seul PDF
|
||||||
|
imageToPDF.selectText.5=Convertir en PDFs distincts
|
||||||
|
|
||||||
#pdfToImage
|
#PDF to Image
|
||||||
pdfToImage.title=PDF vers image
|
pdfToImage.title=PDF vers image
|
||||||
pdfToImage.header=PDF vers image
|
pdfToImage.header=PDF vers image
|
||||||
pdfToImage.selectText=Format d'image
|
pdfToImage.selectText=Format d'image
|
||||||
pdfToImage.singleOrMultiple=Type de résultat d'image
|
pdfToImage.singleOrMultiple=Type de résultat d'image
|
||||||
pdfToImage.single=Une seule grande image
|
pdfToImage.single=Une seule grande image
|
||||||
pdfToImage.multi=Plusieurs images
|
pdfToImage.multi=Plusieurs images
|
||||||
pdfToImage.colorType=Type de couleur
|
pdfToImage.colorType=Type de couleur
|
||||||
pdfToImage.color=Couleur
|
pdfToImage.color=Couleur
|
||||||
pdfToImage.grey=Niveaux de gris
|
pdfToImage.grey=Niveaux de gris
|
||||||
pdfToImage.blackwhite=Noir et Blanc (Peut perdre des données !)
|
pdfToImage.blackwhite=Noir et Blanc (Peut perdre des données !)
|
||||||
pdfToImage.submit=Convertir
|
pdfToImage.submit=Convertir
|
||||||
|
|
||||||
#addPassword
|
#addPassword
|
||||||
@@ -217,35 +250,36 @@ addPassword.submit=Crypter
|
|||||||
#watermark
|
#watermark
|
||||||
watermark.title=Ajouter un filigrane
|
watermark.title=Ajouter un filigrane
|
||||||
watermark.header=Ajouter un filigrane
|
watermark.header=Ajouter un filigrane
|
||||||
watermark.selectText.1=Sélectionnez le PDF auquel ajouter un filigraneÂ:
|
watermark.selectText.1=Sélectionnez le PDF auquel ajouter un filigrane :
|
||||||
watermark.selectText.2=Texte du filigraneÂ:
|
watermark.selectText.2=Texte du filigrane :
|
||||||
watermark.selectText.3=Taille de la policeÂ:
|
watermark.selectText.3=Taille de la police :
|
||||||
watermark.selectText.4=Rotation (0-360)Â:
|
watermark.selectText.4=Rotation (0-360) :
|
||||||
watermark.selectText.5=widthSpacer (Espace entre chaque filigrane horizontalement)Â:
|
watermark.selectText.5=widthSpacer (Espace entre chaque filigrane horizontalement) :
|
||||||
watermark.selectText.6=heightSpacer (Espace entre chaque filigrane verticalement)Â:
|
watermark.selectText.6=heightSpacer (Espace entre chaque filigrane verticalement) :
|
||||||
|
watermark.selectText.7=Opacité (0 % - 100 %) :
|
||||||
watermark.submit=Ajouter un filigrane
|
watermark.submit=Ajouter un filigrane
|
||||||
|
|
||||||
#remove-watermark
|
#remove-watermark
|
||||||
remove-watermark.title=Supprimer le filigrane
|
remove-watermark.title=Supprimer le filigrane
|
||||||
remove-watermark.header=Supprimer le filigrane
|
remove-watermark.header=Supprimer le filigrane
|
||||||
remove-watermark.selectText.1=Sélectionnez le PDF pour supprimer le filigrane:
|
remove-watermark.selectText.1=Sélectionnez le PDF pour supprimer le filigrane :
|
||||||
remove-watermark.selectText.2=Texte du filigrane:
|
remove-watermark.selectText.2=Texte du filigrane :
|
||||||
remove-watermark.submit=Supprimer le filigrane
|
remove-watermark.submit=Supprimer le filigrane
|
||||||
|
|
||||||
#Change permissions
|
#Change Permissions
|
||||||
permissions.title=Modifier les autorisations
|
permissions.title=Modifier les autorisations
|
||||||
permissions.header=Modifier les autorisations
|
permissions.header=Modifier les autorisations
|
||||||
permissions.warning=Attention pour que ces permissions soient immuables il est recommandé de les définir avec un mot de passe via la page add-password
|
permissions.warning=Attention pour que ces permissions soient immuables il est recommandé de les définir avec un mot de passe via la page add-password.
|
||||||
permissions.selectText.1=Sélectionnez PDF pour modifier les autorisations
|
permissions.selectText.1=Sélectionnez le PDF pour modifier les autorisations :
|
||||||
permissions.selectText.2=Autorisations à définir
|
permissions.selectText.2=Autorisations à définir :
|
||||||
permissions.selectText.3=Employer l'assemblage du document
|
permissions.selectText.3=Employer l'assemblage du document
|
||||||
permissions.selectText.4=Employer l'extraction de contenu
|
permissions.selectText.4=Employer l'extraction de contenu
|
||||||
permissions.selectText.5=Employer l'extraction pour l'accessibilité
|
permissions.selectText.5=Employer l'extraction pour l'accessibilité
|
||||||
permissions.selectText.6=Employer de remplir le formulaire
|
permissions.selectText.6=Employer pour remplir le formulaire
|
||||||
permissions.selectText.7=Employer la modification
|
permissions.selectText.7=Employer pour la modification
|
||||||
permissions.selectText.8=Employer la modification des annotations
|
permissions.selectText.8=Employer pour la modification des annotations
|
||||||
permissions.selectText.9=Employer l'impression
|
permissions.selectText.9=Employer pour l'impression
|
||||||
permissions.selectText.10=Emp�cher l'impression de diff�rents formats
|
permissions.selectText.10=Empêcher l'impression de différents formats
|
||||||
permissions.submit=Modificateur
|
permissions.submit=Modificateur
|
||||||
|
|
||||||
#supprimer le mot de passe
|
#supprimer le mot de passe
|
||||||
@@ -255,27 +289,67 @@ removePassword.selectText.1=Sélectionnez le PDF à déchiffrer
|
|||||||
removePassword.selectText.2=Mot de passe
|
removePassword.selectText.2=Mot de passe
|
||||||
removePassword.submit=Supprimer
|
removePassword.submit=Supprimer
|
||||||
|
|
||||||
changeMetadata.title=Modifier les métadonnées
|
#Change Metadata
|
||||||
changeMetadata.header=Modifier les métadonnées
|
changeMetadata.title=Modifier les métadonnées
|
||||||
changeMetadata.selectText.1=Veuillez modifier les variables que vous souhaitez modifier
|
changeMetadata.header=Modifier les métadonnées
|
||||||
changeMetadata.selectText.2=Supprimer toutes les métadonnées
|
changeMetadata.selectText.1=Veuillez modifier les variables que vous souhaitez modifier.
|
||||||
changeMetadata.selectText.3=Afficher les métadonnées personnalisées:
|
changeMetadata.selectText.2=Supprimer toutes les métadonnées.
|
||||||
changeMetadata.author=Auteur:
|
changeMetadata.selectText.3=Afficher les métadonnées personnalisées :
|
||||||
changeMetadata.creationDate=Date de création (aaaa/MM/jj HH:mm:ss):
|
changeMetadata.author=Auteur :
|
||||||
changeMetadata.creator=Créateur:
|
changeMetadata.creationDate=Date de création (aaaa/MM/jj HH:mm:ss) :
|
||||||
changeMetadata.keywords=Mots clés:
|
changeMetadata.creator=Créateur :
|
||||||
changeMetadata.modDate=Date de modification (aaaa/MM/jj HH:mm:ss):
|
changeMetadata.keywords=Mots clés :
|
||||||
changeMetadata.producer=Producteur:
|
changeMetadata.modDate=Date de modification (aaaa/MM/jj HH:mm:ss) :
|
||||||
changeMetadata.subject=Objet:
|
changeMetadata.producer=Producteur :
|
||||||
changeMetadata.title=Titre:
|
changeMetadata.subject=Objet :
|
||||||
changeMetadata.trapped=Piégé:
|
changeMetadata.title=Titre :
|
||||||
changeMetadata.selectText.4=Autres métadonnées:
|
changeMetadata.trapped=Piégé :
|
||||||
changeMetadata.selectText.5=Ajouter une entrée de métadonnées personnalisées
|
changeMetadata.selectText.4=Autres métadonnées :
|
||||||
|
changeMetadata.selectText.5=Ajouter une entrée de métadonnées personnalisées
|
||||||
changeMetadata.submit=Modifier
|
changeMetadata.submit=Modifier
|
||||||
|
|
||||||
|
#XLS to PDF
|
||||||
xlsToPdf.title=Excel vers PDF
|
xlsToPdf.title=Excel vers PDF
|
||||||
xlsToPdf.header=Excel en PDF
|
xlsToPdf.header=Excel en PDF
|
||||||
xlsToPdf.selectText.1=Sélectionnez une feuille Excel XLS ou XLSX à convertir
|
xlsToPdf.selectText.1=Sélectionnez une feuille Excel XLS ou XLSX à convertir.
|
||||||
xlsToPdf.convert=convertir
|
xlsToPdf.convert=Convertir
|
||||||
|
|
||||||
|
pdfToPDFA.title=PDF vers PDF/A
|
||||||
|
pdfToPDFA.header=PDF vers PDF/A
|
||||||
|
pdfToPDFA.credit=Ce service utilise OCRmyPDF pour la conversion PDF/A
|
||||||
|
pdfToPDFA.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PDFToWord.title=PDF vers Word
|
||||||
|
PDFToWord.header=PDF vers Word
|
||||||
|
PDFToWord.selectText.1=Format du fichier de sortie
|
||||||
|
PDFToWord.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
|
||||||
|
PDFToWord.submit=Convertir
|
||||||
|
|
||||||
|
PDFToPresentation.title=PDF vers présentation
|
||||||
|
PDFToPresentation.header=PDF vers présentation
|
||||||
|
PDFToPresentation.selectText.1=Format du fichier de sortie
|
||||||
|
PDFToPresentation.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
|
||||||
|
PDFToPresentation.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
PDFToText.title=PDF vers Texte/RTF
|
||||||
|
PDFToText.header=PDF vers texte/RTF
|
||||||
|
PDFToText.selectText.1=Format du fichier de sortie
|
||||||
|
PDFToText.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
|
||||||
|
PDFToText.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
PDFToHTML.title=PDF vers HTML
|
||||||
|
PDFToHTML.header=PDF vers HTML
|
||||||
|
PDFToHTML.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
|
||||||
|
PDFToHTML.submit=Convertir
|
||||||
|
|
||||||
|
PDFToXML.title=PDF vers XML
|
||||||
|
PDFToXML.header=PDF vers XML
|
||||||
|
PDFToXML.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
|
||||||
|
PDFToXML.submit=Convertir
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,3 +24,4 @@ body {
|
|||||||
#support-section {
|
#support-section {
|
||||||
background-color: #444 !important;
|
background-color: #444 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{addImage.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{addImage.title})}"></th:block>
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2 th:text="#{addImage.header}"></h2>
|
<h2 th:text="#{addImage.header}"></h2>
|
||||||
<form method="post" th:action="@{add-image}" enctype="multipart/form-data">
|
<form method="post" th:action="@{add-image}" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<input type="file" class="custom-file-input" id="fileInput2" name="fileInput2" required>
|
<input type="file" class="custom-file-input" id="fileInput2" name="fileInput2" accept="image/*" required>
|
||||||
<label class="custom-file-label" for="fileInput2" th:text="#{imgPrompt}"></label>
|
<label class="custom-file-label" for="fileInput2" th:text="#{imgPrompt}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -26,7 +26,10 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="y">Y</label> <input type="number" class="form-control" id="y" name="y" step="0.01" required>
|
<label for="y">Y</label> <input type="number" class="form-control" id="y" name="y" step="0.01" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{addImage.submit}"></button>
|
<div class="form-group">
|
||||||
|
<input type="checkbox" id="everyPage" name="everyPage" value="true"> <label for="everyPage" th:text="#{addImage.everyPage}"></label>
|
||||||
|
</div>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{addImage.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{compress.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{compress.title})}"></th:block>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2 th:text="#{compress.header}"></h2>
|
<h2 th:text="#{compress.header}"></h2>
|
||||||
<form action="#" th:action="@{/compress-pdf}" method="post" enctype="multipart/form-data">
|
<form action="#" th:action="@{/compress-pdf}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div>
|
<div>
|
||||||
<label for="optimizeLevel" th:text="#{compress.selectText.1}"></label>
|
<label for="optimizeLevel" th:text="#{compress.selectText.1}"></label>
|
||||||
<select name="optimizeLevel" id="optimizeLevel">
|
<select name="optimizeLevel" id="optimizeLevel">
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<input type="checkbox" name="jbig2Lossy" id="jbig2Lossy">
|
<input type="checkbox" name="jbig2Lossy" id="jbig2Lossy">
|
||||||
<label for="jbig2Lossy" th:text="#{compress.selectText.7}"></label>
|
<label for="jbig2Lossy" th:text="#{compress.selectText.7}"></label>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" th:text="#{compress.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{compress.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
<p class="mt-3" th:text="#{compress.credit}"></p>
|
<p class="mt-3" th:text="#{compress.credit}"></p>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{fileToPDF.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{fileToPDF.title})}"></th:block>
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<form method="post" enctype="multipart/form-data" th:action="@{file-to-pdf}">
|
<form method="post" enctype="multipart/form-data" th:action="@{file-to-pdf}">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
||||||
<br>
|
<br>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{fileToPDF.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{fileToPDF.submit}"></button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
<p class="mt-3" th:text="#{fileToPDF.credit}"></p>
|
<p class="mt-3" th:text="#{fileToPDF.credit}"></p>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{imageToPDF.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{imageToPDF.title})}"></th:block>
|
||||||
|
|
||||||
@@ -15,12 +15,55 @@
|
|||||||
<h2 th:text="#{imageToPDF.header}"></h2>
|
<h2 th:text="#{imageToPDF.header}"></h2>
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data" th:action="@{img-to-pdf}">
|
<form method="post" enctype="multipart/form-data" th:action="@{img-to-pdf}">
|
||||||
<div class="custom-file">
|
|
||||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" required>
|
|
||||||
<label class="custom-file-label" for="fileInput" th:text="#{imgPrompt}"></label>
|
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='image/*', inputText=#{imgPrompt})}"></div>
|
||||||
|
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" name="stretchToFit" id="stretchToFit">
|
||||||
|
<label class="ml-3" for="stretchToFit" th:text=#{imageToPDF.selectText.1}></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" name="autoRotate" id="autoRotate">
|
||||||
|
<label class="ml-3" for="autoRotate" th:text=#{imageToPDF.selectText.2}></label>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<input type="hidden" id="override" name="override" value="multi">
|
||||||
|
<div class="form-group">
|
||||||
|
<label th:text=#{imageToPDF.selectText.3}></label>
|
||||||
|
<select class="form-control" id="conversionType" name="conversionType" disabled>
|
||||||
|
<option value="merge" th:text=#{imageToPDF.selectText.4}></option>
|
||||||
|
<option value="convert" th:text=#{imageToPDF.selectText.5} selected></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br> <br>
|
<br> <br>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{imageToPDF.submit}"></button>
|
||||||
|
<script>
|
||||||
|
$('#fileInput-input').on('change', function() {
|
||||||
|
var files = document.getElementById("fileInput-input").files;
|
||||||
|
var conversionType = document.getElementById("conversionType");
|
||||||
|
console.log("files.length=" + files.length)
|
||||||
|
if (files.length > 1) {
|
||||||
|
conversionType.disabled = false;
|
||||||
|
} else {
|
||||||
|
conversionType.disabled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#conversionType').change(function() {
|
||||||
|
var selectedValue = $(this).val();
|
||||||
|
var override = document.getElementById("override");
|
||||||
|
console.log("selectedValue=" + selectedValue)
|
||||||
|
if (selectedValue === 'merge') {
|
||||||
|
override.value = "single";
|
||||||
|
} else if (selectedValue === 'convert') {
|
||||||
|
override.value = "multi";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
28
src/main/resources/templates/convert/pdf-to-html.html
Normal file
28
src/main/resources/templates/convert/pdf-to-html.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!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=#{PDFToHTML.title})}"></th:block>
|
||||||
|
<body>
|
||||||
|
<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="#{PDFToHTML.header}"></h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-html}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToHTML.submit}"></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{PDFToHTML.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{pdfToImage.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{pdfToImage.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<h2 th:text="#{pdfToImage.header}"></h2>
|
<h2 th:text="#{pdfToImage.header}"></h2>
|
||||||
<p th:text="#{processTimeWarning}"></p>
|
<p th:text="#{processTimeWarning}"></p>
|
||||||
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-img}">
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-img}">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{pdfToImage.selectText}"></label>
|
<label th:text="#{pdfToImage.selectText}"></label>
|
||||||
<select class="form-control" name="imageFormat">
|
<select class="form-control" name="imageFormat">
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<label for="dpi">DPI:</label>
|
<label for="dpi">DPI:</label>
|
||||||
<input type="number" name="dpi" class="form-control" id="dpi" min="1" max="100" step="1" value="30" required>
|
<input type="number" name="dpi" class="form-control" id="dpi" min="1" max="100" step="1" value="30" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToImage.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
31
src/main/resources/templates/convert/pdf-to-pdfa.html
Normal file
31
src/main/resources/templates/convert/pdf-to-pdfa.html
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<!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=#{pdfToPDFA.title})}"></th:block>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<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="#{pdfToPDFA.header}"></h2>
|
||||||
|
<p>Currently doesn't work for multiple inputs at once</p>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-pdfa}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToPDFA.submit}"></button>
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{pdfToPDFA.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<!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=#{PDFToPresentation.title})}"></th:block>
|
||||||
|
<body>
|
||||||
|
<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="#{PDFToPresentation.header}"></h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-presentation}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label th:text="#{PDFToPresentation.selectText.1}"></label>
|
||||||
|
<select class="form-control" name="outputFormat">
|
||||||
|
<option value="ppt">PPT</option>
|
||||||
|
<option value="pptx">PPTX</option>
|
||||||
|
<option value="odp">ODP</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToPresentation.submit}"></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{PDFToPresentation.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
34
src/main/resources/templates/convert/pdf-to-text.html
Normal file
34
src/main/resources/templates/convert/pdf-to-text.html
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<!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=#{PDFToText.title})}"></th:block>
|
||||||
|
<body>
|
||||||
|
<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="#{PDFToText.header}"></h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-text}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label th:text="#{PDFToText.selectText.1}"></label>
|
||||||
|
<select class="form-control" name="outputFormat">
|
||||||
|
<option value="rtf">RTF</option>
|
||||||
|
<option value="txt:Text">TXT</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToText.submit}"></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{PDFToText.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
40
src/main/resources/templates/convert/pdf-to-word.html
Normal file
40
src/main/resources/templates/convert/pdf-to-word.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!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=#{PDFToWord.title})}"></th:block>
|
||||||
|
<body>
|
||||||
|
<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="#{PDFToWord.header}"></h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-word}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label th:text="#{PDFToWord.selectText.1}"></label>
|
||||||
|
<select class="form-control" name="outputFormat">
|
||||||
|
<option value="doc">Doc</option>
|
||||||
|
<option value="docx">DocX</option>
|
||||||
|
<option value="odt">Odt</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToWord.submit}"></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{PDFToWord.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
28
src/main/resources/templates/convert/pdf-to-xml.html
Normal file
28
src/main/resources/templates/convert/pdf-to-xml.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!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=#{PDFToXML.title})}"></th:block>
|
||||||
|
<body>
|
||||||
|
<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="#{PDFToXML.header}"></h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" th:action="@{pdf-to-xml}">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToXML.submit}"></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<p class="mt-3" th:text="#{PDFToXML.credit}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Error! :(</title>
|
<title>Error! :(</title>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{extractImages.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{extractImages.title})}"></th:block>
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<h2 th:text="#{extractImages.header}"></h2>
|
<h2 th:text="#{extractImages.header}"></h2>
|
||||||
|
|
||||||
<form id="multiPdfForm" th:action="@{extract-images}" method="post" enctype="multipart/form-data">
|
<form id="multiPdfForm" th:action="@{extract-images}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{extractImages.selectText}"></label>
|
<label th:text="#{extractImages.selectText}"></label>
|
||||||
<select class="form-control" name="format">
|
<select class="form-control" name="format">
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<option value="gif">GIF</option>
|
<option value="gif">GIF</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{extractImages.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{extractImages.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<div th:fragment="card" class="feature-card">
|
<div th:fragment="card" class="feature-card">
|
||||||
<h5 class="card-title" th:text="${cardTitle}"></h5>
|
<a th:href="${cardLink}">
|
||||||
|
<h5 class="card-title text-primary" th:text="${cardTitle}"></h5>
|
||||||
<p class="card-text" th:text="${cardText}"></p>
|
<p class="card-text" th:text="${cardText}"></p>
|
||||||
<a class="btn btn-primary" th:href="${cardLink}" th:text="#{goToPage}"></a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
<!-- Metadata -->
|
<!-- Metadata -->
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title th:text="'S-PDF ' + ${title}"></title>
|
|
||||||
|
<title th:text="${@appName} + (${title} != null and ${title} != '' ? ' - ' + ${title} : '')"></title>
|
||||||
<link rel="shortcut icon" href="favicon.svg">
|
<link rel="shortcut icon" href="favicon.svg">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
@@ -63,11 +64,11 @@ function toggleDarkMode() {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<th:block th:fragment="fileSelector(name, multiple)">
|
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}">
|
||||||
<div class="custom-file-chooser">
|
<div class="custom-file-chooser">
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" multiple>
|
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" th:accept="${accept}" multiple>
|
||||||
<label class="custom-file-label" th:for="${name}+'-input'" th:text="#{pdfPrompt}"></label>
|
<label class="custom-file-label" th:for="${name}+'-input'" th:text="${inputText}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selected-files"></div>
|
<div class="selected-files"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,6 +84,10 @@ function toggleDarkMode() {
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
$('form').submit(function(event) {
|
$('form').submit(function(event) {
|
||||||
|
var processing = "Processing..."
|
||||||
|
var submitButtonText = $('#submitBtn').text()
|
||||||
|
|
||||||
|
$('#submitBtn').text('Processing...');
|
||||||
console.log("start download code")
|
console.log("start download code")
|
||||||
var files = $('#fileInput-input')[0].files;
|
var files = $('#fileInput-input')[0].files;
|
||||||
var url = this.action;
|
var url = this.action;
|
||||||
@@ -90,7 +95,9 @@ function toggleDarkMode() {
|
|||||||
event.preventDefault(); // Prevent the default form handling behavior
|
event.preventDefault(); // Prevent the default form handling behavior
|
||||||
/* Check if ${multiple} is false */
|
/* Check if ${multiple} is false */
|
||||||
var multiple = [[${multiple}]] || false;
|
var multiple = [[${multiple}]] || false;
|
||||||
if (!multiple && files.length > 1) {
|
var override = $('#override').val() || '';
|
||||||
|
console.log("override=" + override)
|
||||||
|
if (override === 'multi' || (!multiple && files.length > 1) && override !== 'single' ) {
|
||||||
console.log("multi parallel download")
|
console.log("multi parallel download")
|
||||||
submitMultiPdfForm(event,url);
|
submitMultiPdfForm(event,url);
|
||||||
} else {
|
} else {
|
||||||
@@ -185,31 +192,37 @@ function toggleDarkMode() {
|
|||||||
// Create an error message to display to the user
|
// Create an error message to display to the user
|
||||||
const message = `${errorMessage}\n\n${stackTrace}`;
|
const message = `${errorMessage}\n\n${stackTrace}`;
|
||||||
|
|
||||||
|
$('#submitBtn').text(submitButtonText);
|
||||||
|
|
||||||
// Display the error message to the user
|
// Display the error message to the user
|
||||||
alert(message);
|
alert(message);
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function submitMultiPdfForm(event,url) {
|
}
|
||||||
|
$('#submitBtn').text(submitButtonText);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function submitMultiPdfForm(event, url) {
|
||||||
// Get the selected PDF files
|
// Get the selected PDF files
|
||||||
var files = $('#fileInput-input')[0].files;
|
let files = $('#fileInput-input')[0].files;
|
||||||
|
|
||||||
// Get the existing form data
|
// Get the existing form data
|
||||||
var formData = new FormData($('form')[0]);
|
let formData = new FormData($('form')[0]);
|
||||||
formData.delete('fileInput');
|
formData.delete('fileInput');
|
||||||
|
|
||||||
// Show the progress bar
|
// Show the progress bar
|
||||||
$('#progressBarContainer').show();
|
$('#progressBarContainer').show();
|
||||||
|
|
||||||
// Initialize the progress bar
|
// Initialize the progress bar
|
||||||
var progressBar = $('#progressBar');
|
let progressBar = $('#progressBar');
|
||||||
progressBar.css('width', '0%');
|
progressBar.css('width', '0%');
|
||||||
progressBar.attr('aria-valuenow', 0);
|
progressBar.attr('aria-valuenow', 0);
|
||||||
progressBar.attr('aria-valuemax', files.length);
|
progressBar.attr('aria-valuemax', files.length);
|
||||||
|
|
||||||
// Check the flag in localStorage
|
// Check the flag in localStorage, default to 4
|
||||||
const zipFiles = localStorage.getItem('zipParallelFiles') === 'true';
|
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||||
|
const zipFiles = files.length > zipThreshold;
|
||||||
|
|
||||||
// Initialize JSZip instance if needed
|
// Initialize JSZip instance if needed
|
||||||
let jszip = null;
|
let jszip = null;
|
||||||
@@ -217,39 +230,51 @@ function toggleDarkMode() {
|
|||||||
jszip = new JSZip();
|
jszip = new JSZip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Submit each PDF file in parallel
|
// Submit each PDF file in parallel
|
||||||
var promises = [];
|
let promises = [];
|
||||||
for (var i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
var promise = new Promise(function(resolve, reject) {
|
let promise = new Promise(async function(resolve, reject) {
|
||||||
var fileFormData = new FormData();
|
let fileFormData = new FormData();
|
||||||
fileFormData.append('fileInput', files[i]);
|
fileFormData.append('fileInput', files[i]);
|
||||||
for (var pair of formData.entries()) {
|
for (let pair of formData.entries()) {
|
||||||
fileFormData.append(pair[0], pair[1]);
|
fileFormData.append(pair[0], pair[1]);
|
||||||
}
|
}
|
||||||
console.log(fileFormData);
|
console.log(fileFormData);
|
||||||
|
|
||||||
fetch(url, {
|
try {
|
||||||
|
let response = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: fileFormData
|
body: fileFormData
|
||||||
}).then(function(response) {
|
});
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
throw new Error('Received null response for file ' + i);
|
throw new Error('Received null response for file ' + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Error submitting request for file ${i}: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentDisposition = response.headers.get('content-disposition');
|
||||||
|
let fileName = "file.pdf"
|
||||||
|
if (!contentDisposition) {
|
||||||
|
//throw new Error('Content-Disposition header not found for file ' + i);
|
||||||
|
} else {
|
||||||
|
fileName = contentDisposition.split('filename=')[1].replace(/"/g, '');
|
||||||
|
}
|
||||||
console.log('Received response for file ' + i + ': ' + response);
|
console.log('Received response for file ' + i + ': ' + response);
|
||||||
|
|
||||||
var contentDisposition = response.headers.get('content-disposition');
|
|
||||||
var fileName = contentDisposition.split('filename=')[1].replace(/"/g, '');
|
|
||||||
|
|
||||||
response.blob().then(function (blob) {
|
|
||||||
|
let blob = await response.blob();
|
||||||
if (zipFiles) {
|
if (zipFiles) {
|
||||||
// Add the file to the ZIP archive
|
// Add the file to the ZIP archive
|
||||||
jszip.file(fileName, blob);
|
jszip.file(fileName, blob);
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
// Download the file directly
|
// Download the file directly
|
||||||
var url = window.URL.createObjectURL(blob);
|
let url = window.URL.createObjectURL(blob);
|
||||||
var a = document.createElement('a');
|
let a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.download = fileName;
|
a.download = fileName;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
@@ -257,29 +282,25 @@ function toggleDarkMode() {
|
|||||||
a.remove();
|
a.remove();
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
});
|
} catch (error) {
|
||||||
|
|
||||||
}).catch(function(error) {
|
|
||||||
console.error('Error submitting request for file ' + i + ': ' + error);
|
console.error('Error submitting request for file ' + i + ': ' + error);
|
||||||
|
|
||||||
// Set default values or fallbacks for error properties
|
// Set default values or fallbacks for error properties
|
||||||
var status = error && error.status || 500;
|
let status = error && error.status || 500;
|
||||||
var statusText = error && error.statusText || 'Internal Server Error';
|
let statusText = error && error.statusText || 'Internal Server Error';
|
||||||
var message = error && error.message || 'An error occurred while processing your request.';
|
let message = error && error.message || 'An error occurred while processing your request.';
|
||||||
|
|
||||||
// Reject the Promise to signal that the request has failed
|
// Reject the Promise to signal that the request has failed
|
||||||
reject();
|
reject();
|
||||||
// Redirect to error page with Spring Boot error parameters
|
// Redirect to error page with Spring Boot error parameters
|
||||||
var url = '/error?status=' + status + '&error=' + encodeURIComponent(statusText) + '&message=' + encodeURIComponent(message);
|
let url = '/error?status=' + status + '&error=' + encodeURIComponent(statusText) + '&message=' + encodeURIComponent(message);
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the progress bar as each request finishes
|
// Update the progress bar as each request finishes
|
||||||
promise.then(function() {
|
promise.then(function() {
|
||||||
var progress = ((progressBar.attr('aria-valuenow') / files.length) * 100) + (100 / files.length);
|
updateProgressBar(progressBar, files);
|
||||||
progressBar.css('width', progress + '%');
|
|
||||||
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
promises.push(promise);
|
promises.push(promise);
|
||||||
@@ -298,17 +319,26 @@ function toggleDarkMode() {
|
|||||||
|
|
||||||
// After all requests are finished, download the ZIP file if needed
|
// After all requests are finished, download the ZIP file if needed
|
||||||
if (zipFiles) {
|
if (zipFiles) {
|
||||||
jszip.generateAsync({ type: "blob" }).then(function (content) {
|
try {
|
||||||
var url = window.URL.createObjectURL(content);
|
let content = await jszip.generateAsync({ type: "blob" });
|
||||||
var a = document.createElement('a');
|
let url = window.URL.createObjectURL(content);
|
||||||
|
let a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.download = "files.zip";
|
a.download = "files.zip";
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
a.remove();
|
a.remove();
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error('Error generating ZIP file: ' + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
function updateProgressBar(progressBar, files) {
|
||||||
|
let progress = ((progressBar.attr('aria-valuenow') / files.length) * 100) + (100 / files.length);
|
||||||
|
progressBar.css('width', progress + '%');
|
||||||
|
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -355,6 +385,7 @@ function toggleDarkMode() {
|
|||||||
fileNames.forEach(fileName => {
|
fileNames.forEach(fileName => {
|
||||||
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
||||||
});
|
});
|
||||||
|
console.log("fileNames.length=" + fileNames.length)
|
||||||
if (fileNames.length === 1) {
|
if (fileNames.length === 1) {
|
||||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
||||||
} else if (fileNames.length > 1) {
|
} else if (fileNames.length > 1) {
|
||||||
|
|||||||
@@ -3,5 +3,6 @@
|
|||||||
<a href="https://github.com/Frooodle/Stirling-PDF" target="_blank" class="mx-1"><img src="images/github.svg"></img></a>
|
<a href="https://github.com/Frooodle/Stirling-PDF" target="_blank" class="mx-1"><img src="images/github.svg"></img></a>
|
||||||
<a href="https://hub.docker.com/r/frooodle/s-pdf" target="_blank" class="mx-1"><img src="images/docker.svg"></img></a>
|
<a href="https://hub.docker.com/r/frooodle/s-pdf" target="_blank" class="mx-1"><img src="images/docker.svg"></img></a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" target="_blank" class="mx-1"><img src="images/discord.svg"></img></a>
|
<a href="https://discord.gg/Cn8pWhQRxZ" target="_blank" class="mx-1"><img src="images/discord.svg"></img></a>
|
||||||
|
<div th:if="${@appName} != 'Stirling PDF'" class="mt-2" style="color: grey;">Powered by Stirling PDF</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,63 +1,32 @@
|
|||||||
<div th:fragment="navbar" class="mx-auto">
|
<div th:fragment="navbar" class="mx-auto">
|
||||||
<script>
|
<script>
|
||||||
document
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
.addEventListener(
|
const defaultLocale = document.documentElement.lang || 'en_GB';
|
||||||
'DOMContentLoaded',
|
const storedLocale = localStorage.getItem('languageCode') || defaultLocale;
|
||||||
function() {
|
const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
|
||||||
// Get the dropdown items
|
|
||||||
var dropdownItems = document
|
|
||||||
.querySelectorAll('.lang_dropdown-item');
|
|
||||||
|
|
||||||
// Loop through the dropdown items
|
for (let i = 0; i < dropdownItems.length; i++) {
|
||||||
for (var i = 0; i < dropdownItems.length; i++) {
|
const item = dropdownItems[i];
|
||||||
dropdownItems[i].classList
|
item.classList.remove('active');
|
||||||
.remove('active');
|
if (item.dataset.languageCode === storedLocale) {
|
||||||
if (dropdownItems[i].dataset.languageCode === localStorage
|
item.classList.add('active');
|
||||||
.getItem('languageCode')) {
|
|
||||||
dropdownItems[i].classList
|
|
||||||
.add('active');
|
|
||||||
}
|
}
|
||||||
|
item.addEventListener('click', handleDropdownItemClick);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add a click event listener to each dropdown item
|
function handleDropdownItemClick(event) {
|
||||||
dropdownItems[i]
|
event.preventDefault();
|
||||||
.addEventListener(
|
const languageCode = this.dataset.languageCode;
|
||||||
'click',
|
localStorage.setItem('languageCode', languageCode);
|
||||||
function(event) {
|
|
||||||
|
|
||||||
// Prevent the default link behavior
|
const currentUrl = window.location.href;
|
||||||
event
|
if (currentUrl.indexOf('?lang=') === -1) {
|
||||||
.preventDefault();
|
window.location.href = currentUrl + '?lang=' + languageCode;
|
||||||
|
|
||||||
// Get the language code
|
|
||||||
var languageCode = this.dataset.languageCode;
|
|
||||||
|
|
||||||
// Save the language code to local storage
|
|
||||||
localStorage
|
|
||||||
.setItem(
|
|
||||||
'languageCode',
|
|
||||||
languageCode);
|
|
||||||
|
|
||||||
// Get the current URL
|
|
||||||
var currentUrl = window.location.href;
|
|
||||||
|
|
||||||
// Check if the URL already contains a "?lang" query parameter
|
|
||||||
if (currentUrl
|
|
||||||
.indexOf('?lang=') === -1) {
|
|
||||||
// Update the URL with the "?lang" query parameter
|
|
||||||
window.location.href = currentUrl
|
|
||||||
+ '?lang='
|
|
||||||
+ languageCode;
|
|
||||||
} else {
|
} else {
|
||||||
// Replace the "?lang" query parameter with the new value
|
window.location.href = currentUrl.replace(/\?lang=\w{2,}/, '?lang=' + languageCode);
|
||||||
window.location.href = currentUrl
|
|
||||||
.replace(
|
|
||||||
/\?lang=\w{2,}/,
|
|
||||||
'?lang='
|
|
||||||
+ languageCode);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
@@ -109,7 +78,7 @@ function compareVersions(version1, version2) {
|
|||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<div class="container ">
|
<div class="container ">
|
||||||
|
|
||||||
<a class="navbar-brand" href="#" th:href="@{/}">Stirling PDF</a>
|
<a class="navbar-brand" href="#" th:href="@{/}" th:text="${@navBarText}"></a>
|
||||||
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
@@ -127,16 +96,24 @@ function compareVersions(version1, version2) {
|
|||||||
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#" th:href="@{rotate-pdf}" th:classappend="${currentPage}=='rotate-pdf' ? 'active' : ''" th:text="#{home.rotate.title}"></a></li>
|
<li class="nav-item"><a class="nav-link" href="#" th:href="@{rotate-pdf}" th:classappend="${currentPage}=='rotate-pdf' ? 'active' : ''" th:text="#{home.rotate.title}"></a></li>
|
||||||
|
|
||||||
<li class="nav-item dropdown" th:classappend="${currentPage}=='pdf-to-img' OR ${currentPage}=='img-to-pdf' OR ${currentPage}=='file-to-pdf' OR ${currentPage}=='xlsx-to-pdf' ? 'active' : ''"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
|
<li class="nav-item dropdown" th:classappend="${currentPage}=='pdf-to-img' OR ${currentPage}=='img-to-pdf' OR ${currentPage}=='pdf-to-pdfa' OR ${currentPage}=='file-to-pdf' OR ${currentPage}=='xlsx-to-pdf' OR ${currentPage}=='pdf-to-word' OR ${currentPage}=='pdf-to-presentation' OR ${currentPage}=='pdf-to-text' OR ${currentPage}=='pdf-to-html' OR ${currentPage}=='pdf-to-xml' ? 'active' : ''"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
|
||||||
aria-haspopup="true" aria-expanded="false" th:text="#{navbar.convert}"></a>
|
aria-haspopup="true" aria-expanded="false" th:text="#{navbar.convert}"></a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
|
<!-- Existing menu items -->
|
||||||
<a class="dropdown-item" href="#" th:href="@{pdf-to-img}" th:classappend="${currentPage}=='pdf-to-img' ? 'active' : ''" th:text="#{home.pdfToImage.title}"></a>
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-img}" th:classappend="${currentPage}=='pdf-to-img' ? 'active' : ''" th:text="#{home.pdfToImage.title}"></a>
|
||||||
<a class="dropdown-item" href="#" th:href="@{img-to-pdf}" th:classappend="${currentPage}=='img-to-pdf' ? 'active' : ''" th:text="#{home.imageToPdf.title}"></a>
|
<a class="dropdown-item" href="#" th:href="@{img-to-pdf}" th:classappend="${currentPage}=='img-to-pdf' ? 'active' : ''" th:text="#{home.imageToPdf.title}"></a>
|
||||||
<a class="dropdown-item" href="#" th:href="@{file-to-pdf}" th:classappend="${currentPage}=='file-to-pdf' ? 'active' : ''" th:text="#{home.fileToPDF.title}"></a>
|
<a class="dropdown-item" href="#" th:href="@{file-to-pdf}" th:classappend="${currentPage}=='file-to-pdf' ? 'active' : ''" th:text="#{home.fileToPDF.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-pdfa}" th:classappend="${currentPage}=='pdf-to-pdfa' ? 'active' : ''" th:text="#{home.pdfToPDFA.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-word}" th:classappend="${currentPage}=='pdf-to-word' ? 'active' : ''" th:text="#{home.PDFToWord.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-presentation}" th:classappend="${currentPage}=='pdf-to-presentation' ? 'active' : ''" th:text="#{home.PDFToPresentation.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-text}" th:classappend="${currentPage}=='pdf-to-text' ? 'active' : ''" th:text="#{home.PDFToText.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-html}" th:classappend="${currentPage}=='pdf-to-html' ? 'active' : ''" th:text="#{home.PDFToHTML.title}"></a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{pdf-to-xml}" th:classappend="${currentPage}=='pdf-to-xml' ? 'active' : ''" th:text="#{home.PDFToXML.title}"></a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<li class="nav-item dropdown" th:classappend="${currentPage}=='add-password' OR ${currentPage}=='remove-password' OR ${currentPage}=='change-permissions' OR ${currentPage}=='add-watermark' OR ${currentPage}=='remove-watermark' ? 'active' : ''">
|
<li class="nav-item dropdown" th:classappend="${currentPage}=='add-password' OR ${currentPage}=='remove-password' OR ${currentPage}=='change-permissions' OR ${currentPage}=='add-watermark' OR ${currentPage}=='remove-watermark' ? 'active' : ''">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" th:text="#{navbar.security}"></a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" th:text="#{navbar.security}"></a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
@@ -172,11 +149,11 @@ function compareVersions(version1, version2) {
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="languageDropdown">
|
<div class="dropdown-menu" aria-labelledby="languageDropdown">
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="en_US">English (US)</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="en_GB" >English</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="en_GB">English (UK)</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="ar_AR" >العربية</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="ar_AR">العربية</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="de_DE" >Deutsch</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="de_DE">Deutsch</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="fr_FR" >Français</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="fr_FR">Français</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="es_ES" >Spanish</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -206,25 +183,24 @@ function compareVersions(version1, version2) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
<p class="mb-0" th:text="#{settings.appVersion} + ' ' + ${@appVersion}"></p>
|
<p class="mb-0" th:utext="#{settings.appVersion} + ' ' + ${@appVersion}"></p>
|
||||||
<a href="https://github.com/Frooodle/Stirling-PDF/releases" target="_blank">
|
<a href="https://github.com/Frooodle/Stirling-PDF/releases" target="_blank">
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary" id="update-btn" th:text="#{settings.update}"></button>
|
<button type="button" class="btn btn-sm btn-outline-primary" id="update-btn" th:utext="#{settings.update}"></button>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="downloadOption" th:text="#{settings.downloadOption.title}"></label>
|
<label for="downloadOption" th:utext="#{settings.downloadOption.title}"></label>
|
||||||
<select class="form-control" id="downloadOption">
|
<select class="form-control" id="downloadOption">
|
||||||
<option value="sameWindow" th:text="#{settings.downloadOption.1}"></option>
|
<option value="sameWindow" th:utext="#{settings.downloadOption.1}"></option>
|
||||||
<option value="newWindow" th:text="#{settings.downloadOption.2}"></option>
|
<option value="newWindow" th:utext="#{settings.downloadOption.2}"></option>
|
||||||
<option value="downloadFile" th:text="#{settings.downloadOption.3}"></option>
|
<option value="downloadFile" th:utext="#{settings.downloadOption.3}"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="custom-control custom-checkbox">
|
<label for="zipThreshold" th:utext="#{settings.zipThreshold}"></label>
|
||||||
<input type="checkbox" class="custom-control-input" id="zipParallelFiles">
|
<input type="range" class="custom-range" min="0" max="9" step="1" id="zipThreshold" value="4">
|
||||||
<label class="custom-control-label" for="zipParallelFiles" th:text="#{settings.zip}"></label>
|
<span id="zipThresholdValue" class="ml-2"></span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -253,17 +229,20 @@ function compareVersions(version1, version2) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Get the zipParallelFiles flag from local storage, or set it to false if it doesn't exist
|
// Get the zipThreshold value from local storage, or set it to 0 if it doesn't exist
|
||||||
var zipParallelFiles = localStorage.getItem('zipParallelFiles') === 'true';
|
var zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||||
|
|
||||||
// Set the checked state of the checkbox
|
// Set the value of the slider and the display span
|
||||||
document.getElementById('zipParallelFiles').checked = zipParallelFiles;
|
document.getElementById('zipThreshold').value = zipThreshold;
|
||||||
|
document.getElementById('zipThresholdValue').textContent = zipThreshold;
|
||||||
|
|
||||||
// Save the checked state of the checkbox to local storage when it changes
|
// Save the selected value to local storage when the slider value changes
|
||||||
document.getElementById('zipParallelFiles').addEventListener('change', function () {
|
document.getElementById('zipThreshold').addEventListener('input', function () {
|
||||||
zipParallelFiles = this.checked;
|
zipThreshold = this.value;
|
||||||
localStorage.setItem('zipParallelFiles', zipParallelFiles);
|
document.getElementById('zipThresholdValue').textContent = zipThreshold;
|
||||||
|
localStorage.setItem('zipThreshold', zipThreshold);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
|
||||||
@@ -12,17 +12,41 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.feature-card {
|
.feature-card {
|
||||||
border: 1px solid rgba(0, 0, 0, .125);
|
border: 2px solid rgba(0, 0, 0, .25);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
background: rgba(13, 110, 253, 0.05);
|
||||||
|
transition: transform 0.3s, border 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-card .card-text {
|
.feature-card .card-text {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feature-card:hover {
|
||||||
|
border: 2px solid rgba(0, 0, 0, .5);
|
||||||
|
cursor: pointer;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card:hover .card-title {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.card-title.text-primary {
|
||||||
|
color: #013275; /* Replace with your desired shade of blue */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -33,14 +57,16 @@
|
|||||||
<!-- Jumbotron -->
|
<!-- Jumbotron -->
|
||||||
<div class="jumbotron jumbotron-fluid" id="jumbotron">
|
<div class="jumbotron jumbotron-fluid" id="jumbotron">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="display-4">Stirling PDF</h1>
|
<h1 class="display-4" th:text="${@appName}"></h1>
|
||||||
<p class="lead" th:text="#{home.desc}"></p>
|
<p class="lead" th:text="${@homeText != 'null' and @homeText != null and @homeText != ''} ? ${@homeText} : #{home.desc}"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Features -->
|
<!-- Features -->
|
||||||
<div class="features-container container">
|
<div class="features-container container">
|
||||||
|
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs')}"></div>
|
||||||
|
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.split.title}, cardText=#{home.split.desc}, cardLink='split-pdfs')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.split.title}, cardText=#{home.split.desc}, cardLink='split-pdfs')}"></div>
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.rotate.title}, cardText=#{home.rotate.desc}, cardLink='rotate-pdf')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.rotate.title}, cardText=#{home.rotate.desc}, cardLink='rotate-pdf')}"></div>
|
||||||
|
|
||||||
@@ -62,6 +88,16 @@
|
|||||||
|
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.ocr.title}, cardText=#{home.ocr.desc}, cardLink='ocr-pdf')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.ocr.title}, cardText=#{home.ocr.desc}, cardLink='ocr-pdf')}"></div>
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.extractImages.title}, cardText=#{home.extractImages.desc}, cardLink='extract-images')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.extractImages.title}, cardText=#{home.extractImages.desc}, cardLink='extract-images')}"></div>
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.pdfToPDFA.title}, cardText=#{home.pdfToPDFA.desc}, cardLink='pdf-to-pdfa')}"></div>
|
||||||
|
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.PDFToWord.title}, cardText=#{home.PDFToWord.desc}, cardLink='pdf-to-word')}"></div>
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.PDFToPresentation.title}, cardText=#{home.PDFToPresentation.desc}, cardLink='pdf-to-presentation')}"></div>
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.PDFToText.title}, cardText=#{home.PDFToText.desc}, cardLink='pdf-to-text')}"></div>
|
||||||
|
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.PDFToHTML.title}, cardText=#{home.PDFToHTML.desc}, cardLink='pdf-to-html')}"></div>
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.PDFToXML.title}, cardText=#{home.PDFToXML.desc}, cardLink='pdf-to-xml')}"></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{merge.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{merge.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,16 +16,14 @@
|
|||||||
<form action="merge-pdfs" method="post" enctype="multipart/form-data">
|
<form action="merge-pdfs" method="post" enctype="multipart/form-data">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{multiPdfDropPrompt}"></label>
|
<label th:text="#{multiPdfDropPrompt}"></label>
|
||||||
<div class="custom-file">
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true, accept='application/pdf')}"></div>
|
||||||
<input type="file" class="custom-file-input" id="fileInput" name="fileInput" multiple required>
|
|
||||||
<label class="custom-file-label" th:text="#{pdfPrompt}"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<ul id="selectedFiles" class="list-group"></ul>
|
<ul id="selectedFiles" class="list-group"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{merge.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{merge.submit}"></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<style>
|
<style>
|
||||||
@@ -61,7 +59,7 @@
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("fileInput").addEventListener("change", function() {
|
document.getElementById("fileInput-input").addEventListener("change", function() {
|
||||||
var files = this.files;
|
var files = this.files;
|
||||||
var list = document.getElementById("selectedFiles");
|
var list = document.getElementById("selectedFiles");
|
||||||
list.innerHTML = "";
|
list.innerHTML = "";
|
||||||
@@ -121,7 +119,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.getElementById("fileInput").files = dataTransfer.files;
|
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{ocr.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{ocr.title})}"></th:block>
|
||||||
@@ -16,21 +16,46 @@
|
|||||||
<h2 th:text="#{ocr.header}"></h2>
|
<h2 th:text="#{ocr.header}"></h2>
|
||||||
|
|
||||||
<form action="#" th:action="@{/ocr-pdf}" method="post" enctype="multipart/form-data" class="mb-3">
|
<form action="#" th:action="@{/ocr-pdf}" method="post" enctype="multipart/form-data" class="mb-3">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="languages" class="form-label" th:text="#{ocr.selectText.1}"></label>
|
<label for="languages" class="form-label" th:text="#{ocr.selectText.1}"></label>
|
||||||
|
<hr>
|
||||||
<div id="languages">
|
<div id="languages">
|
||||||
<div th:each="language: ${languages}">
|
<div th:each="language, iterStat : ${languages}" >
|
||||||
<input type="checkbox" class="form-check-input" th:name="languages" th:value="${language}" th:id="${'language-' + language}" />
|
<input type="checkbox" class="form-check-input" th:name="languages" th:value="${language}" th:id="${'language-' + language}" />
|
||||||
<label class="form-check-label" th:for="${'language-' + language}" th:text="${language}"></label>
|
<label class="form-check-label" th:for="${'language-' + language}" th:text=" ${language}"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="form-group">
|
<div class="form-group">
|
||||||
|
<label th:text="#{ocr.selectText.10}"></label>
|
||||||
|
<select class="form-control" name="ocrType">
|
||||||
|
<option value="skip-text" th:text="#{ocr.selectText.6}"></option>
|
||||||
|
<option value="force-ocr" th:text="#{ocr.selectText.7}"></option>
|
||||||
|
<option value="Normal" th:text="#{ocr.selectText.8}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<label for="languages" class="form-label" th:text="#{ocr.selectText.9}"></label>
|
||||||
|
<div class="form-check">
|
||||||
<input type="checkbox" class="form-check-input" name="sidecar" id="sidecar" />
|
<input type="checkbox" class="form-check-input" name="sidecar" id="sidecar" />
|
||||||
<label class="form-check-label" for="sidecar" th:text="#{ocr.selectText.2}"></label>
|
<label class="form-check-label" for="sidecar" th:text="#{ocr.selectText.2}"></label>
|
||||||
</div> -->
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{ocr.submit}"></button>
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" name="deskew" id="deskew" />
|
||||||
|
<label class="form-check-label" for="deskew" th:text="#{ocr.selectText.3}"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" name="clean" id="clean" />
|
||||||
|
<label class="form-check-label" for="clean" th:text="#{ocr.selectText.4}"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" name="clean-final" id="clean-final" />
|
||||||
|
<label class="form-check-label" for="clean-final" th:text="#{ocr.selectText.5}"></label>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{ocr.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
<p th:text="#{ocr.credit}"></p>
|
<p th:text="#{ocr.credit}"></p>
|
||||||
<p th:text="#{ocr.help}"></p>
|
<p th:text="#{ocr.help}"></p>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{pdfOrganiser.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{pdfOrganiser.title})}"></th:block>
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
<h2 th:text="#{pdfOrganiser.header}"></h2>
|
<h2 th:text="#{pdfOrganiser.header}"></h2>
|
||||||
|
|
||||||
<form th:action="@{rearrange-pages}" method="post" enctype="multipart/form-data">
|
<form th:action="@{rearrange-pages}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label>
|
<label for="pageOrder" th:text="#{pageOrderPrompt}"></label>
|
||||||
<input type="text" class="form-control" id="fileInput" name="pageOrder" placeholder="(e.g. 1,3,2 or 4-8,2,10-12)" required>
|
<input type="text" class="form-control" id="fileInput" name="pageOrder" placeholder="(e.g. 1,3,2 or 4-8,2,10-12)" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfOrganiser.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{pageRemover.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{pageRemover.title})}"></th:block>
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
<h2 th:text="#{pageRemover.header}"></h2>
|
<h2 th:text="#{pageRemover.header}"></h2>
|
||||||
|
|
||||||
<form th:action="@{remove-pages}" method="post" enctype="multipart/form-data">
|
<form th:action="@{remove-pages}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pagesToDelete" th:text="#{pageRemover.pagesToDelete}"></label>
|
<label for="pagesToDelete" th:text="#{pageRemover.pagesToDelete}"></label>
|
||||||
<input type="text" class="form-control" id="fileInput" name="pagesToDelete" placeholder="(e.g. 1,2,6 or 1-10,15-30)" required>
|
<input type="text" class="form-control" id="fileInput" name="pagesToDelete" placeholder="(e.g. 1,2,6 or 1-10,15-30)" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{pageRemover.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pageRemover.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{rotate.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{rotate.title})}"></th:block>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<h2 th:text="#{rotate.header}"></h2>
|
<h2 th:text="#{rotate.header}"></h2>
|
||||||
|
|
||||||
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<input type="hidden" id="angleInput" name="angle" value="0">
|
<input type="hidden" id="angleInput" name="angle" value="0">
|
||||||
|
|
||||||
<div id="editSection" style="display: none">
|
<div id="editSection" style="display: none">
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{rotate.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{rotate.submit}"></button>
|
||||||
<button type="button" class="btn btn-secondary" onclick="rotate(90)">
|
<button type="button" class="btn btn-secondary" onclick="rotate(90)">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{addPassword.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{addPassword.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<form action="add-password" method="post" enctype="multipart/form-data">
|
<form action="add-password" method="post" enctype="multipart/form-data">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{addPassword.selectText.1}"></label>
|
<label th:text="#{addPassword.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{addPassword.selectText.2}"></label> <input type="password" class="form-control" id="password" name="password" required>
|
<label th:text="#{addPassword.selectText.2}"></label> <input type="password" class="form-control" id="password" name="password" required>
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{addPassword.submit}"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{watermark.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{watermark.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<form method="post" enctype="multipart/form-data" action="add-watermark">
|
<form method="post" enctype="multipart/form-data" action="add-watermark">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{watermark.selectText.1}"></label>
|
<label th:text="#{watermark.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
||||||
@@ -26,6 +26,45 @@
|
|||||||
<label for="fontSize" th:text="#{watermark.selectText.3}"></label>
|
<label for="fontSize" th:text="#{watermark.selectText.3}"></label>
|
||||||
<input type="text" id="fontSize" name="fontSize" class="form-control" value="30" />
|
<input type="text" id="fontSize" name="fontSize" class="form-control" value="30" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="opacity" th:text="#{watermark.selectText.7}"></label>
|
||||||
|
<input type="text" id="opacity" name="opacityText" class="form-control" value="50" onblur="updateopacityValue()" />
|
||||||
|
<input type="hidden" id="opacityReal" name="opacity" value="0.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const opacityInput = document.getElementById('opacity');
|
||||||
|
const opacityRealInput = document.getElementById('opacityReal');
|
||||||
|
|
||||||
|
const updateopacityValue = () => {
|
||||||
|
let percentageValue = parseFloat(opacityInput.value.replace('%', ''));
|
||||||
|
if (isNaN(percentageValue)) {
|
||||||
|
percentageValue = 0;
|
||||||
|
}
|
||||||
|
percentageValue = Math.min(Math.max(percentageValue, 0), 100);
|
||||||
|
opacityInput.value = `${percentageValue}`;
|
||||||
|
opacityRealInput.value = (percentageValue / 100).toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
const appendPercentageSymbol = () => {
|
||||||
|
if (!opacityInput.value.endsWith('%')) {
|
||||||
|
opacityInput.value += '%';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
opacityInput.addEventListener('focus', () => {
|
||||||
|
opacityInput.value = opacityInput.value.replace('%', '');
|
||||||
|
});
|
||||||
|
opacityInput.addEventListener('blur', () => {
|
||||||
|
updateopacityValue();
|
||||||
|
appendPercentageSymbol();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set initial values
|
||||||
|
updateopacityValue();
|
||||||
|
appendPercentageSymbol();
|
||||||
|
</script>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="rotation" th:text="#{watermark.selectText.4}"></label>
|
<label for="rotation" th:text="#{watermark.selectText.4}"></label>
|
||||||
<input type="text" id="rotation" name="rotation" class="form-control" value="45" />
|
<input type="text" id="rotation" name="rotation" class="form-control" value="45" />
|
||||||
@@ -39,7 +78,7 @@
|
|||||||
<input type="text" id="heightSpacer" name="heightSpacer" class="form-control" value="50" />
|
<input type="text" id="heightSpacer" name="heightSpacer" class="form-control" value="50" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<input type="submit" th:value="#{watermark.submit}" class="btn btn-primary" />
|
<input type="submit" id="submitBtn" th:value="#{watermark.submit}" class="btn btn-primary" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{changeMetadata.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{changeMetadata.title})}"></th:block>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<h2 th:text="#{changeMetadata.header}"></h2>
|
<h2 th:text="#{changeMetadata.header}"></h2>
|
||||||
|
|
||||||
<form method="post" id="form1" enctype="multipart/form-data" th:action="@{/update-metadata}">
|
<form method="post" id="form1" enctype="multipart/form-data" th:action="@{/update-metadata}">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<p class="text-muted" th:text="#{changeMetadata.selectText.1}"></p>
|
<p class="text-muted" th:text="#{changeMetadata.selectText.1}"></p>
|
||||||
|
|
||||||
<div class="form-group-inline form-check">
|
<div class="form-group-inline form-check">
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
<button type="button" class="btn btn-secondary" id="addMetadataBtn" th:text="#{changeMetadata.selectText.5}"></button>
|
<button type="button" class="btn btn-secondary" id="addMetadataBtn" th:text="#{changeMetadata.selectText.5}"></button>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<button class="btn btn-primary" type="submit" th:text="#{changeMetadata.submit}"></button>
|
<button class="btn btn-primary" type="submit" id="submitBtn" th:text="#{changeMetadata.submit}"></button>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const deleteAllCheckbox = document.querySelector("#deleteAll");
|
const deleteAllCheckbox = document.querySelector("#deleteAll");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{permissions.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{permissions.title})}"></th:block>
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<form action="add-password" method="post" enctype="multipart/form-data">
|
<form action="add-password" method="post" enctype="multipart/form-data">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{permissions.selectText.1}"></label>
|
<label th:text="#{permissions.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{permissions.selectText.2}"></label>
|
<label th:text="#{permissions.selectText.2}"></label>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{permissions.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{permissions.submit}"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{removePassword.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{removePassword.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<form action="remove-password" method="post" enctype="multipart/form-data">
|
<form action="remove-password" method="post" enctype="multipart/form-data">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{removePassword.selectText.1}"></label>
|
<label th:text="#{removePassword.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{removePassword.selectText.2}"></label>
|
<label th:text="#{removePassword.selectText.2}"></label>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removePassword.submit}"></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{remove-watermark.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{remove-watermark.title})}"></th:block>
|
||||||
|
|
||||||
@@ -16,14 +16,14 @@
|
|||||||
<form method="post" enctype="multipart/form-data" action="remove-watermark">
|
<form method="post" enctype="multipart/form-data" action="remove-watermark">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label th:text="#{remove-watermark.selectText.1}"></label>
|
<label th:text="#{remove-watermark.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="watermarkText" th:text="#{remove-watermark.selectText.2}"></label>
|
<label for="watermarkText" th:text="#{remove-watermark.selectText.2}"></label>
|
||||||
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
|
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<input type="submit" th:value="#{remove-watermark.submit}" class="btn btn-primary" />
|
<input type="submit" id="submitBtn" th:value="#{remove-watermark.submit}" class="btn btn-primary" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
<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.title})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{split.title})}"></th:block>
|
||||||
|
|
||||||
@@ -24,14 +24,14 @@
|
|||||||
<p th:text="#{split.desc.8}"></p>
|
<p th:text="#{split.desc.8}"></p>
|
||||||
|
|
||||||
<form th:action="@{split-pages}" method="post" enctype="multipart/form-data">
|
<form th:action="@{split-pages}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false)}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pages" th:text="#{split.splitPages}"></label>
|
<label for="pages" th:text="#{split.splitPages}"></label>
|
||||||
<input type="text" class="form-control" id="pages" name="pages" placeholder="1,3,5-10" required>
|
<input type="text" class="form-control" id="pages" name="pages" placeholder="1,3,5-10" required>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{split.submit}"></button>
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{split.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user