reapir
This commit is contained in:
parent
3c47f21337
commit
5dfe8a83cd
7 changed files with 104 additions and 1 deletions
|
@ -0,0 +1,59 @@
|
||||||
|
package stirling.software.SPDF.controller.api.other;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class RepairController {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(RepairController.class);
|
||||||
|
|
||||||
|
@PostMapping(consumes = "multipart/form-data", value = "/repair")
|
||||||
|
public ResponseEntity<byte[]> repairPdf(@RequestPart(required = true, value = "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");
|
||||||
|
|
||||||
|
List<String> command = new ArrayList<>();
|
||||||
|
command.add("gs");
|
||||||
|
command.add("-o");
|
||||||
|
command.add(tempOutputFile.toString());
|
||||||
|
command.add("-sDEVICE=pdfwrite");
|
||||||
|
command.add(tempInputFile.toString());
|
||||||
|
|
||||||
|
|
||||||
|
int returnCode = ProcessExecutor.getInstance(ProcessExecutor.Processes.GHOSTSCRIPT).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("[.][^.]+$", "") + "_repaired.pdf";
|
||||||
|
return PdfUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -88,5 +88,11 @@ public class OtherWebController {
|
||||||
return "other/adjust-contrast";
|
return "other/adjust-contrast";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/repair")
|
||||||
|
@Hidden
|
||||||
|
public String repairForm(Model model) {
|
||||||
|
model.addAttribute("currentPage", "repair");
|
||||||
|
return "other/repair";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,8 @@ home.sign.desc=Adds signature to PDF by drawing, text or image
|
||||||
home.flatten.title=Flatten
|
home.flatten.title=Flatten
|
||||||
home.flatten.desc=Remove all interactive elements and forms from a PDF
|
home.flatten.desc=Remove all interactive elements and forms from a PDF
|
||||||
|
|
||||||
|
home.repair.title=Repair
|
||||||
|
home.repair.desc=Tries to repair a corrupt/broken PDF
|
||||||
|
|
||||||
ScannerImageSplit.selectText.1=Angle Threshold:
|
ScannerImageSplit.selectText.1=Angle Threshold:
|
||||||
ScannerImageSplit.selectText.2=Sets the minimum absolute angle required for the image to be rotated (default: 10).
|
ScannerImageSplit.selectText.2=Sets the minimum absolute angle required for the image to be rotated (default: 10).
|
||||||
|
|
3
src/main/resources/static/images/wrench.svg
Normal file
3
src/main/resources/static/images/wrench.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-wrench" viewBox="0 0 16 16">
|
||||||
|
<path d="M.102 2.223A3.004 3.004 0 0 0 3.78 5.897l6.341 6.252A3.003 3.003 0 0 0 13 16a3 3 0 1 0-.851-5.878L5.897 3.781A3.004 3.004 0 0 0 2.223.1l2.141 2.142L4 4l-1.757.364L.102 2.223zm13.37 9.019.528.026.287.445.445.287.026.529L15 13l-.242.471-.026.529-.445.287-.287.445-.529.026L13 15l-.471-.242-.529-.026-.287-.445-.445-.287-.026-.529L11 13l.242-.471.026-.529.445-.287.287-.445.529-.026L13 11l.471.242z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 541 B |
|
@ -290,6 +290,9 @@ function compareVersions(version1, version2) {
|
||||||
<a class="dropdown-item" href="#" th:href="@{flatten}" th:classappend="${currentPage}=='flatten' ? 'active' : ''" th:title="#{home.flatten.desc}">
|
<a class="dropdown-item" href="#" th:href="@{flatten}" th:classappend="${currentPage}=='flatten' ? 'active' : ''" th:title="#{home.flatten.desc}">
|
||||||
<img class="icon" src="images/flatten.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> <span class="icon-text" th:text="#{home.flatten.title}"></span>
|
<img class="icon" src="images/flatten.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> <span class="icon-text" th:text="#{home.flatten.title}"></span>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="dropdown-item" href="#" th:href="@{repair}" th:classappend="${currentPage}=='repair' ? 'active' : ''" th:title="#{home.repair.desc}">
|
||||||
|
<img class="icon" src="images/wrench.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> <span class="icon-text" th:text="#{home.repair.title}"></span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,7 @@ filter: invert(0.2) sepia(2) saturate(50) hue-rotate(190deg);
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.sign.title}, cardText=#{home.sign.desc}, cardLink='sign', svgPath='images/sign.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.sign.title}, cardText=#{home.sign.desc}, cardLink='sign', svgPath='images/sign.svg')}"></div>
|
||||||
<div th:replace="~{fragments/card :: card(cardTitle=#{home.flatten.title}, cardText=#{home.flatten.desc}, cardLink='flatten', svgPath='images/flatten.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.flatten.title}, cardText=#{home.flatten.desc}, cardLink='flatten', svgPath='images/flatten.svg')}"></div>
|
||||||
|
|
||||||
|
<div th:replace="~{fragments/card :: card(cardTitle=#{home.repair.title}, cardText=#{home.repair.desc}, cardLink='repair', svgPath='images/wrench.svg')}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
|
29
src/main/resources/templates/other/repair.html
Normal file
29
src/main/resources/templates/other/repair.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!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=#{repair.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="#{repair.header}"></h2>
|
||||||
|
<form id="multiPdfForm" th:action="@{repair}" method="post" enctype="multipart/form-data">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{repair.submit}"></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue