This commit is contained in:
Anthony Stirling 2023-02-09 22:20:38 +00:00
parent 6021efb4ef
commit e09abb8bb4
14 changed files with 607 additions and 632 deletions

View File

@ -6,8 +6,8 @@ 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);
} }
} }

View File

@ -13,23 +13,23 @@ import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@Configuration @Configuration
public class Beans implements WebMvcConfigurer { 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); slr.setDefaultLocale(Locale.US);
return slr; return slr;
} }
@Bean @Bean
public LocaleChangeInterceptor localeChangeInterceptor() { public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang"); lci.setParamName("lang");
return lci; return lci;
} }
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor()); registry.addInterceptor(localeChangeInterceptor());
} }
} }

View File

@ -24,45 +24,45 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class CompressController { public class CompressController {
private static final Logger logger = LoggerFactory.getLogger(CompressController.class); private static final Logger logger = LoggerFactory.getLogger(CompressController.class);
@GetMapping("/compress-pdf") @GetMapping("/compress-pdf")
public String compressPdfForm(Model model) { public String compressPdfForm(Model model) {
model.addAttribute("currentPage", "compress-pdf"); model.addAttribute("currentPage", "compress-pdf");
return "compress-pdf"; return "compress-pdf";
} }
@PostMapping("/compress-pdf") @PostMapping("/compress-pdf")
public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("imageCompressionLevel") String imageCompressionLevel)
@RequestParam("imageCompressionLevel") String imageCompressionLevel) throws IOException { throws IOException {
// Load a sample PDF document // Load a sample PDF document
PdfDocument document = new PdfDocument(); PdfDocument document = new PdfDocument();
document.loadFromBytes(pdfFile.getBytes()); document.loadFromBytes(pdfFile.getBytes());
// Compress PDF // Compress PDF
document.getFileInfo().setIncrementalUpdate(false); document.getFileInfo().setIncrementalUpdate(false);
document.setCompressionLevel(PdfCompressionLevel.Best); document.setCompressionLevel(PdfCompressionLevel.Best);
// compress PDF Images // compress PDF Images
for (int i = 0; i < document.getPages().getCount(); i++) { for (int i = 0; i < document.getPages().getCount(); i++) {
PdfPageBase page = document.getPages().get(i); PdfPageBase page = document.getPages().get(i);
PdfImageInfo[] images = page.getImagesInfo(); PdfImageInfo[] images = page.getImagesInfo();
if (images != null && images.length > 0) if (images != null && images.length > 0)
for (int j = 0; j < images.length; j++) { for (int j = 0; j < images.length; j++) {
PdfImageInfo image = images[j]; PdfImageInfo image = images[j];
PdfBitmap bp = new PdfBitmap(image.getImage()); PdfBitmap bp = new PdfBitmap(image.getImage());
// bp.setPngDirectToJpeg(true); // bp.setPngDirectToJpeg(true);
bp.setQuality(Integer.valueOf(imageCompressionLevel)); bp.setQuality(Integer.valueOf(imageCompressionLevel));
page.replaceImage(j, bp); page.replaceImage(j, bp);
} }
} }
return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_compressed.pdf"); return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_compressed.pdf");
} }
} }

View File

@ -24,54 +24,52 @@ import org.springframework.web.multipart.MultipartFile;
@Controller @Controller
public class MergeController { public class MergeController {
private static final Logger logger = LoggerFactory.getLogger(MergeController.class); private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
@GetMapping("/merge-pdfs") @GetMapping("/merge-pdfs")
public String hello(Model model) { public String hello(Model model) {
model.addAttribute("currentPage", "merge-pdfs"); model.addAttribute("currentPage", "merge-pdfs");
return "merge-pdfs"; return "merge-pdfs";
} }
@PostMapping("/merge-pdfs") @PostMapping("/merge-pdfs")
public ResponseEntity<InputStreamResource> mergePdfs(@RequestParam("fileInput") MultipartFile[] files) public ResponseEntity<InputStreamResource> mergePdfs(@RequestParam("fileInput") MultipartFile[] files) throws IOException {
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<>();
// Loop through the files array and read each file into a PDDocument // Loop through the files array and read each file into a PDDocument
for (MultipartFile file : files) { for (MultipartFile file : files) {
documents.add(PDDocument.load(file.getInputStream())); documents.add(PDDocument.load(file.getInputStream()));
} }
PDDocument mergedDoc = mergeDocuments(documents); PDDocument mergedDoc = mergeDocuments(documents);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergedDoc.save(byteArrayOutputStream); mergedDoc.save(byteArrayOutputStream);
mergedDoc.close(); mergedDoc.close();
// Create an InputStreamResource from the merged PDF // Create an InputStreamResource from the merged PDF
InputStreamResource resource = new InputStreamResource( InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
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 ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF).body(resource);
} }
private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException { private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
// Create a new empty document // Create a new empty document
PDDocument mergedDoc = new PDDocument(); PDDocument mergedDoc = new PDDocument();
// Iterate over the list of documents and add their pages to the merged document // Iterate over the list of documents and add their pages to the merged document
for (PDDocument doc : documents) { for (PDDocument doc : documents) {
// Get all pages from the current document // Get all pages from the current document
PDPageTree pages = doc.getPages(); PDPageTree pages = doc.getPages();
// Iterate over the pages and add them to the merged document // Iterate over the pages and add them to the merged document
for (PDPage page : pages) { for (PDPage page : pages) {
mergedDoc.addPage(page); mergedDoc.addPage(page);
} }
} }
// Return the merged document // Return the merged document
return mergedDoc; return mergedDoc;
} }
} }

View File

@ -18,27 +18,26 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class OverlayImageController { public class OverlayImageController {
private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class); private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class);
@GetMapping("/add-image") @GetMapping("/add-image")
public String overlayImage(Model model) { public String overlayImage(Model model) {
model.addAttribute("currentPage", "add-image"); model.addAttribute("currentPage", "add-image");
return "add-image"; return "add-image";
} }
@PostMapping("/add-image") @PostMapping("/add-image")
public ResponseEntity<byte[]> overlayImage(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> overlayImage(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("fileInput2") MultipartFile imageFile, @RequestParam("x") float x,
@RequestParam("fileInput2") MultipartFile imageFile, @RequestParam("x") float x, @RequestParam("y") float y) {
@RequestParam("y") float y) { 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);
return PdfUtils.bytesToWebResponse(result, pdfFile.getName() + "_overlayed.pdf"); return PdfUtils.bytesToWebResponse(result, pdfFile.getName() + "_overlayed.pdf");
} catch (IOException e) { } catch (IOException e) {
logger.error("Failed to add image to PDF", e); logger.error("Failed to add image to PDF", e);
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} }
} }
} }

View File

@ -9,17 +9,17 @@ import org.springframework.web.bind.annotation.GetMapping;
@Controller @Controller
public class PdfController { public class PdfController {
private static final Logger logger = LoggerFactory.getLogger(PdfController.class); private static final Logger logger = LoggerFactory.getLogger(PdfController.class);
@GetMapping("/home") @GetMapping("/home")
public String root(Model model) { public String root(Model model) {
return "redirect:/"; return "redirect:/";
} }
@GetMapping("/") @GetMapping("/")
public String home(Model model) { public String home(Model model) {
model.addAttribute("currentPage", "home"); model.addAttribute("currentPage", "home");
return "home"; return "home";
} }
} }

View File

@ -21,104 +21,102 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class RearrangePagesPDFController { public class RearrangePagesPDFController {
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class); private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
@GetMapping("/pdf-organizer") @GetMapping("/pdf-organizer")
public String pageOrganizer(Model model) { public String pageOrganizer(Model model) {
model.addAttribute("currentPage", "pdf-organizer"); model.addAttribute("currentPage", "pdf-organizer");
return "pdf-organizer"; return "pdf-organizer";
} }
@GetMapping("/remove-pages") @GetMapping("/remove-pages")
public String pageDeleter(Model model) { public String pageDeleter(Model model) {
model.addAttribute("currentPage", "remove-pages"); model.addAttribute("currentPage", "remove-pages");
return "remove-pages"; return "remove-pages";
} }
@PostMapping("/remove-pages") @PostMapping("/remove-pages")
public ResponseEntity<byte[]> deletePages(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> deletePages(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("pagesToDelete") String pagesToDelete) throws IOException {
@RequestParam("pagesToDelete") String pagesToDelete) throws IOException {
PDDocument document = PDDocument.load(pdfFile.getBytes()); PDDocument document = PDDocument.load(pdfFile.getBytes());
// Split the page order string into an array of page numbers or range of numbers // Split the page order string into an array of page numbers or range of numbers
String[] pageOrderArr = pagesToDelete.split(","); String[] pageOrderArr = pagesToDelete.split(",");
List<Integer> pagesToRemove = pageOrderToString(pageOrderArr, document.getNumberOfPages()); List<Integer> pagesToRemove = pageOrderToString(pageOrderArr, document.getNumberOfPages());
for (int i = pagesToRemove.size() - 1; i >= 0; i--) { for (int i = pagesToRemove.size() - 1; i >= 0; i--) {
int pageIndex = pagesToRemove.get(i); int pageIndex = pagesToRemove.get(i);
document.removePage(pageIndex); document.removePage(pageIndex);
} }
return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_removed_pages.pdf"); return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_removed_pages.pdf");
} }
private List<Integer> pageOrderToString(String[] pageOrderArr, int totalPages) { private List<Integer> pageOrderToString(String[] pageOrderArr, int totalPages) {
List<Integer> newPageOrder = new ArrayList<>(); List<Integer> newPageOrder = new ArrayList<>();
// loop through the page order array // loop through the page order array
for (String element : pageOrderArr) { for (String element : pageOrderArr) {
// check if the element contains a range of pages // check if the element contains a range of pages
if (element.contains("-")) { if (element.contains("-")) {
// split the range into start and end page // split the range into start and end page
String[] range = element.split("-"); String[] range = element.split("-");
int start = Integer.parseInt(range[0]); int start = Integer.parseInt(range[0]);
int end = Integer.parseInt(range[1]); int end = Integer.parseInt(range[1]);
// check if the end page is greater than total pages // check if the end page is greater than total pages
if (end > totalPages) { if (end > totalPages) {
end = totalPages; end = totalPages;
} }
// loop through the range of pages // loop through the range of pages
for (int j = start; j <= end; j++) { for (int j = start; j <= end; j++) {
// print the current index // print the current index
newPageOrder.add(j - 1); newPageOrder.add(j - 1);
} }
} else { } else {
// if the element is a single page // if the element is a single page
newPageOrder.add(Integer.parseInt(element) - 1); newPageOrder.add(Integer.parseInt(element) - 1);
} }
} }
return newPageOrder; return newPageOrder;
} }
@PostMapping("/rearrange-pages") @PostMapping("/rearrange-pages")
public ResponseEntity<byte[]> rearrangePages(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> rearrangePages(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("pageOrder") String pageOrder) {
@RequestParam("pageOrder") String pageOrder) { try {
try { // Load the input PDF
// Load the input PDF PDDocument document = PDDocument.load(pdfFile.getInputStream());
PDDocument document = PDDocument.load(pdfFile.getInputStream());
// Split the page order string into an array of page numbers or range of numbers // Split the page order string into an array of page numbers or range of numbers
String[] pageOrderArr = pageOrder.split(","); String[] pageOrderArr = pageOrder.split(",");
// int[] newPageOrder = new int[pageOrderArr.length]; // int[] newPageOrder = new int[pageOrderArr.length];
int totalPages = document.getNumberOfPages(); int totalPages = document.getNumberOfPages();
List<Integer> newPageOrder = pageOrderToString(pageOrderArr, totalPages); List<Integer> newPageOrder = pageOrderToString(pageOrderArr, totalPages);
// Create a new list to hold the pages in the new order // Create a new list to hold the pages in the new order
List<PDPage> newPages = new ArrayList<>(); List<PDPage> newPages = new ArrayList<>();
for (int i = 0; i < newPageOrder.size(); i++) { for (int i = 0; i < newPageOrder.size(); i++) {
newPages.add(document.getPage(newPageOrder.get(i))); newPages.add(document.getPage(newPageOrder.get(i)));
} }
// Remove all the pages from the original document // Remove all the pages from the original document
for (int i = document.getNumberOfPages() - 1; i >= 0; i--) { for (int i = document.getNumberOfPages() - 1; i >= 0; i--) {
document.removePage(i); document.removePage(i);
} }
// Add the pages in the new order // Add the pages in the new order
for (PDPage page : newPages) { for (PDPage page : newPages) {
document.addPage(page); document.addPage(page);
} }
return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_rearranged.pdf"); return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_rearranged.pdf");
} catch (IOException e) { } catch (IOException e) {
logger.error("Failed rearranging documents", e); logger.error("Failed rearranging documents", e);
return null; return null;
} }
} }
} }

View File

@ -20,30 +20,29 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class RotationController { public class RotationController {
private static final Logger logger = LoggerFactory.getLogger(RotationController.class); private static final Logger logger = LoggerFactory.getLogger(RotationController.class);
@GetMapping("/rotate-pdf") @GetMapping("/rotate-pdf")
public String rotatePdfForm(Model model) { public String rotatePdfForm(Model model) {
model.addAttribute("currentPage", "rotate-pdf"); model.addAttribute("currentPage", "rotate-pdf");
return "rotate-pdf"; return "rotate-pdf";
} }
@PostMapping("/rotate-pdf") @PostMapping("/rotate-pdf")
public ResponseEntity<byte[]> rotatePDF(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> rotatePDF(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("angle") Integer angle) throws IOException {
@RequestParam("angle") Integer angle) throws IOException {
// Load the PDF document // Load the PDF document
PDDocument document = PDDocument.load(pdfFile.getBytes()); PDDocument document = PDDocument.load(pdfFile.getBytes());
// Get the list of pages in the document // Get the list of pages in the document
PDPageTree pages = document.getPages(); PDPageTree pages = document.getPages();
for (PDPage page : pages) { for (PDPage page : pages) {
page.setRotation(page.getRotation() + angle); page.setRotation(page.getRotation() + angle);
} }
return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_rotated.pdf"); return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_rotated.pdf");
} }
} }

View File

@ -37,106 +37,104 @@ import org.springframework.web.multipart.MultipartFile;
@Controller @Controller
public class SplitPDFController { public class SplitPDFController {
private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class); private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class);
@GetMapping("/split-pdfs") @GetMapping("/split-pdfs")
public String splitPdfForm(Model model) { public String splitPdfForm(Model model) {
model.addAttribute("currentPage", "split-pdfs"); model.addAttribute("currentPage", "split-pdfs");
return "split-pdfs"; return "split-pdfs";
} }
@PostMapping("/split-pages") @PostMapping("/split-pages")
public ResponseEntity<Resource> splitPdf(@RequestParam("fileInput") MultipartFile file, public ResponseEntity<Resource> splitPdf(@RequestParam("fileInput") MultipartFile file, @RequestParam("pages") String pages) throws IOException {
@RequestParam("pages") String pages) throws IOException { // parse user input
// parse user input
// open the pdf document // open the pdf document
InputStream inputStream = file.getInputStream(); InputStream inputStream = file.getInputStream();
PDDocument document = PDDocument.load(inputStream); PDDocument document = PDDocument.load(inputStream);
List<Integer> pageNumbers = new ArrayList<>(); List<Integer> pageNumbers = new ArrayList<>();
pages = pages.replaceAll("\\s+", ""); // remove whitespaces pages = pages.replaceAll("\\s+", ""); // remove whitespaces
if (pages.toLowerCase().equals("all")) { if (pages.toLowerCase().equals("all")) {
for (int i = 0; i < document.getNumberOfPages(); i++) { for (int i = 0; i < document.getNumberOfPages(); i++) {
pageNumbers.add(i); pageNumbers.add(i);
} }
} else { } else {
List<String> pageNumbersStr = new ArrayList<>(Arrays.asList(pages.split(","))); List<String> pageNumbersStr = new ArrayList<>(Arrays.asList(pages.split(",")));
if (!pageNumbersStr.contains(String.valueOf(document.getNumberOfPages()))) { if (!pageNumbersStr.contains(String.valueOf(document.getNumberOfPages()))) {
String lastpage = String.valueOf(document.getNumberOfPages()); String lastpage = String.valueOf(document.getNumberOfPages());
pageNumbersStr.add(lastpage); pageNumbersStr.add(lastpage);
} }
for (String page : pageNumbersStr) { for (String page : pageNumbersStr) {
if (page.contains("-")) { if (page.contains("-")) {
String[] range = page.split("-"); String[] range = page.split("-");
int start = Integer.parseInt(range[0]); int start = Integer.parseInt(range[0]);
int end = Integer.parseInt(range[1]); int end = Integer.parseInt(range[1]);
for (int i = start; i <= end; i++) { for (int i = start; i <= end; i++) {
pageNumbers.add(i); pageNumbers.add(i);
} }
} else { } else {
pageNumbers.add(Integer.parseInt(page)); pageNumbers.add(Integer.parseInt(page));
} }
} }
} }
logger.info("Splitting PDF into pages: {}", logger.info("Splitting PDF into pages: {}", pageNumbers.stream().map(String::valueOf).collect(Collectors.joining(",")));
pageNumbers.stream().map(String::valueOf).collect(Collectors.joining(",")));
// split the document // split the document
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>(); List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
int currentPage = 0; int currentPage = 0;
for (int pageNumber : pageNumbers) { for (int pageNumber : pageNumbers) {
try (PDDocument splitDocument = new PDDocument()) { try (PDDocument splitDocument = new PDDocument()) {
for (int i = currentPage; i < pageNumber; i++) { for (int i = currentPage; i < pageNumber; i++) {
PDPage page = document.getPage(i); PDPage page = document.getPage(i);
splitDocument.addPage(page); splitDocument.addPage(page);
logger.debug("Adding page {} to split document", i); logger.debug("Adding page {} to split document", i);
} }
currentPage = pageNumber; currentPage = pageNumber;
logger.debug("Setting current page to {}", currentPage); logger.debug("Setting current page to {}", currentPage);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDocument.save(baos); splitDocument.save(baos);
splitDocumentsBoas.add(baos); splitDocumentsBoas.add(baos);
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed splitting documents and saving them", e); logger.error("Failed splitting documents and saving them", e);
throw e; throw e;
} }
} }
// closing the original document // closing the original document
document.close(); document.close();
// create the zip file // create the zip file
Path zipFile = Paths.get("split_documents.zip"); Path zipFile = Paths.get("split_documents.zip");
URI uri = URI.create("jar:file:" + zipFile.toUri().getPath()); URI uri = URI.create("jar:file:" + zipFile.toUri().getPath());
Map<String, String> env = new HashMap<>(); Map<String, String> env = new HashMap<>();
env.put("create", "true"); env.put("create", "true");
FileSystem zipfs = FileSystems.newFileSystem(uri, env); FileSystem zipfs = FileSystems.newFileSystem(uri, env);
// 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); Path pathInZipfile = zipfs.getPath(fileName);
try (OutputStream os = Files.newOutputStream(pathInZipfile)) { try (OutputStream os = Files.newOutputStream(pathInZipfile)) {
os.write(pdf); os.write(pdf);
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(); 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(); new File("split_documents.zip").delete();
// return the Resource in the response // return the Resource in the response
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=split_documents.zip") return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=split_documents.zip").contentType(MediaType.APPLICATION_OCTET_STREAM)
.contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(resource.contentLength()).body(resource); .contentLength(resource.contentLength()).body(resource);
} }
} }

View File

@ -23,83 +23,78 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class ConvertImgPDFController { public class ConvertImgPDFController {
private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class); private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class);
@GetMapping("/img-to-pdf") @GetMapping("/img-to-pdf")
public String convertToPdfForm(Model model) { public String convertToPdfForm(Model model) {
model.addAttribute("currentPage", "img-to-pdf"); model.addAttribute("currentPage", "img-to-pdf");
return "convert/img-to-pdf"; return "convert/img-to-pdf";
} }
@GetMapping("/pdf-to-img") @GetMapping("/pdf-to-img")
public String pdfToimgForm(Model model) { public String pdfToimgForm(Model model) {
model.addAttribute("currentPage", "pdf-to-img"); model.addAttribute("currentPage", "pdf-to-img");
return "convert/pdf-to-img"; return "convert/pdf-to-img";
} }
@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) 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()); byte[] bytes = PdfUtils.convertToPdf(file.getInputStream());
logger.info("File {} successfully converted to pdf", file.getOriginalFilename()); logger.info("File {} successfully converted to pdf", file.getOriginalFilename());
return PdfUtils.bytesToWebResponse(bytes, file.getName() + "_coverted.pdf"); return PdfUtils.bytesToWebResponse(bytes, file.getName() + "_coverted.pdf");
} }
@PostMapping("/pdf-to-img") @PostMapping("/pdf-to-img")
public ResponseEntity<Resource> convertToImage(@RequestParam("fileInput") MultipartFile file, public ResponseEntity<Resource> convertToImage(@RequestParam("fileInput") MultipartFile file, @RequestParam("imageFormat") String imageFormat,
@RequestParam("imageFormat") String imageFormat, @RequestParam("singleOrMultiple") String singleOrMultiple, @RequestParam("singleOrMultiple") String singleOrMultiple, @RequestParam("colorType") String colorType, @RequestParam("dpi") String dpi,
@RequestParam("colorType") String colorType, @RequestParam("dpi") String dpi, @RequestParam("contrast") String contrast, @RequestParam("brightness") String brightness) throws IOException {
@RequestParam("contrast") String contrast, @RequestParam("brightness") String brightness)
throws IOException {
byte[] pdfBytes = file.getBytes(); byte[] pdfBytes = file.getBytes();
ImageType colorTypeResult = ImageType.RGB; ImageType colorTypeResult = ImageType.RGB;
if ("greyscale".equals(colorType)) { if ("greyscale".equals(colorType)) {
colorTypeResult = ImageType.GRAY; colorTypeResult = ImageType.GRAY;
} else if ("blackwhite".equals(colorType)) { } else if ("blackwhite".equals(colorType)) {
colorTypeResult = ImageType.BINARY; colorTypeResult = ImageType.BINARY;
} }
// returns bytes for image // returns bytes for image
boolean singleImage = singleOrMultiple.equals("single"); boolean singleImage = singleOrMultiple.equals("single");
byte[] result = null; byte[] result = null;
try { try {
result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase(), colorTypeResult, singleImage, result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase(), colorTypeResult, singleImage, Integer.valueOf(dpi), Integer.valueOf(contrast),
Integer.valueOf(dpi), Integer.valueOf(contrast), Integer.valueOf(brightness)); // DPI, contrast, Integer.valueOf(brightness)); // DPI, contrast,
// brightness // brightness
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
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"); headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<Resource> response = new ResponseEntity<>(new ByteArrayResource(result), headers, ResponseEntity<Resource> response = new ResponseEntity<>(new ByteArrayResource(result), headers, HttpStatus.OK);
HttpStatus.OK); return response;
return response; } else {
} else { ByteArrayResource resource = new ByteArrayResource(result);
ByteArrayResource resource = new ByteArrayResource(result); // return the Resource in the response
// return the Resource in the response return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=converted_documents.zip").contentType(MediaType.APPLICATION_OCTET_STREAM)
return ResponseEntity.ok() .contentLength(resource.contentLength()).body(resource);
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=converted_documents.zip") }
.contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(resource.contentLength()) }
.body(resource);
}
}
private String getMediaType(String imageFormat) { private String getMediaType(String imageFormat) {
if (imageFormat.equalsIgnoreCase("PNG")) if (imageFormat.equalsIgnoreCase("PNG"))
return "image/png"; return "image/png";
else if (imageFormat.equalsIgnoreCase("JPEG") || imageFormat.equalsIgnoreCase("JPG")) else if (imageFormat.equalsIgnoreCase("JPEG") || imageFormat.equalsIgnoreCase("JPG"))
return "image/jpeg"; return "image/jpeg";
else if (imageFormat.equalsIgnoreCase("GIF")) else if (imageFormat.equalsIgnoreCase("GIF"))
return "image/gif"; return "image/gif";
else else
return "application/octet-stream"; return "application/octet-stream";
} }
} }

View File

@ -14,21 +14,21 @@ import org.springframework.web.bind.annotation.RequestParam;
@Controller @Controller
public class MetadataController { public class MetadataController {
@GetMapping("/change-metadata") @GetMapping("/change-metadata")
public String addWatermarkForm(Model model) { public String addWatermarkForm(Model model) {
model.addAttribute("currentPage", "change-metadata"); model.addAttribute("currentPage", "change-metadata");
return "security/change-metadata"; return "security/change-metadata";
} }
@PostMapping("/update-metadata") @PostMapping("/update-metadata")
public ResponseEntity<byte[]> metadata(@RequestParam Map<String, String> allRequestParams) throws IOException { public ResponseEntity<byte[]> metadata(@RequestParam Map<String, String> allRequestParams) throws IOException {
System.out.println("1 allRequestParams.size() = " + allRequestParams.size()); System.out.println("1 allRequestParams.size() = " + allRequestParams.size());
for (Entry entry : allRequestParams.entrySet()) { for (Entry entry : allRequestParams.entrySet()) {
System.out.println("1 key=" + entry.getKey() + ", value=" + entry.getValue()); System.out.println("1 key=" + entry.getKey() + ", value=" + entry.getValue());
} }
return null; return null;
} }
// @PostMapping("/update-metadata") // @PostMapping("/update-metadata")
// public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, // public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile,

View File

@ -20,67 +20,62 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class PasswordController { public class PasswordController {
private static final Logger logger = LoggerFactory.getLogger(PasswordController.class); private static final Logger logger = LoggerFactory.getLogger(PasswordController.class);
@GetMapping("/add-password") @GetMapping("/add-password")
public String addPasswordForm(Model model) { public String addPasswordForm(Model model) {
model.addAttribute("currentPage", "add-password"); model.addAttribute("currentPage", "add-password");
return "security/add-password"; return "security/add-password";
} }
@GetMapping("/remove-password") @GetMapping("/remove-password")
public String removePasswordForm(Model model) { public String removePasswordForm(Model model) {
model.addAttribute("currentPage", "remove-password"); model.addAttribute("currentPage", "remove-password");
return "security/remove-password"; return "security/remove-password";
} }
@GetMapping("/change-permissions") @GetMapping("/change-permissions")
public String permissionsForm(Model model) { public String permissionsForm(Model model) {
model.addAttribute("currentPage", "change-permissions"); model.addAttribute("currentPage", "change-permissions");
return "security/change-permissions"; return "security/change-permissions";
} }
@PostMapping("/remove-password") @PostMapping("/remove-password")
public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile fileInput, public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile fileInput, @RequestParam(name = "password") String password) throws IOException {
@RequestParam(name = "password") String password) throws IOException { PDDocument document = PDDocument.load(fileInput.getBytes(), password);
PDDocument document = PDDocument.load(fileInput.getBytes(), password); document.setAllSecurityToBeRemoved(true);
document.setAllSecurityToBeRemoved(true); return PdfUtils.pdfDocToWebResponse(document, fileInput.getName() + "_password_removed.pdf");
return PdfUtils.pdfDocToWebResponse(document, fileInput.getName() + "_password_removed.pdf"); }
}
@PostMapping("/add-password") @PostMapping("/add-password")
public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile fileInput, public ResponseEntity<byte[]> compressPDF(@RequestParam("fileInput") MultipartFile fileInput, @RequestParam(defaultValue = "", name = "password") String password,
@RequestParam(defaultValue = "", name = "password") String password, @RequestParam(defaultValue = "128", name = "keyLength") int keyLength, @RequestParam(defaultValue = "false", name = "canAssembleDocument") boolean canAssembleDocument,
@RequestParam(defaultValue = "128", name = "keyLength") int keyLength, @RequestParam(defaultValue = "false", name = "canExtractContent") boolean canExtractContent,
@RequestParam(defaultValue = "false", name = "canAssembleDocument") boolean canAssembleDocument, @RequestParam(defaultValue = "false", name = "canExtractForAccessibility") boolean canExtractForAccessibility,
@RequestParam(defaultValue = "false", name = "canExtractContent") boolean canExtractContent, @RequestParam(defaultValue = "false", name = "canFillInForm") boolean canFillInForm, @RequestParam(defaultValue = "false", name = "canModify") boolean canModify,
@RequestParam(defaultValue = "false", name = "canExtractForAccessibility") boolean canExtractForAccessibility, @RequestParam(defaultValue = "false", name = "canModifyAnnotations") boolean canModifyAnnotations,
@RequestParam(defaultValue = "false", name = "canFillInForm") boolean canFillInForm, @RequestParam(defaultValue = "false", name = "canPrint") boolean canPrint, @RequestParam(defaultValue = "false", name = "canPrintFaithful") boolean canPrintFaithful)
@RequestParam(defaultValue = "false", name = "canModify") boolean canModify, throws IOException {
@RequestParam(defaultValue = "false", name = "canModifyAnnotations") boolean canModifyAnnotations,
@RequestParam(defaultValue = "false", name = "canPrint") boolean canPrint,
@RequestParam(defaultValue = "false", name = "canPrintFaithful") boolean canPrintFaithful)
throws IOException {
PDDocument document = PDDocument.load(fileInput.getBytes()); PDDocument document = PDDocument.load(fileInput.getBytes());
AccessPermission ap = new AccessPermission(); AccessPermission ap = new AccessPermission();
ap.setCanAssembleDocument(!canAssembleDocument); ap.setCanAssembleDocument(!canAssembleDocument);
ap.setCanExtractContent(!canExtractContent); ap.setCanExtractContent(!canExtractContent);
ap.setCanExtractForAccessibility(!canExtractForAccessibility); ap.setCanExtractForAccessibility(!canExtractForAccessibility);
ap.setCanFillInForm(!canFillInForm); ap.setCanFillInForm(!canFillInForm);
ap.setCanModify(!canModify); ap.setCanModify(!canModify);
ap.setCanModifyAnnotations(!canModifyAnnotations); ap.setCanModifyAnnotations(!canModifyAnnotations);
ap.setCanPrint(!canPrint); ap.setCanPrint(!canPrint);
ap.setCanPrintFaithful(!canPrintFaithful); ap.setCanPrintFaithful(!canPrintFaithful);
StandardProtectionPolicy spp = new StandardProtectionPolicy(password, password, ap); StandardProtectionPolicy spp = new StandardProtectionPolicy(password, password, ap);
spp.setEncryptionKeyLength(keyLength); spp.setEncryptionKeyLength(keyLength);
spp.setPermissions(ap); spp.setPermissions(ap);
document.protect(spp); document.protect(spp);
return PdfUtils.pdfDocToWebResponse(document, fileInput.getName() + "_passworded.pdf"); return PdfUtils.pdfDocToWebResponse(document, fileInput.getName() + "_passworded.pdf");
} }
} }

View File

@ -22,57 +22,53 @@ import stirling.software.SPDF.utils.PdfUtils;
@Controller @Controller
public class WatermarkController { public class WatermarkController {
@GetMapping("/add-watermark") @GetMapping("/add-watermark")
public String addWatermarkForm(Model model) { public String addWatermarkForm(Model model) {
model.addAttribute("currentPage", "add-watermark"); model.addAttribute("currentPage", "add-watermark");
return "security/add-watermark"; return "security/add-watermark";
} }
@PostMapping("/add-watermark") @PostMapping("/add-watermark")
public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, public ResponseEntity<byte[]> addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, @RequestParam("watermarkText") String watermarkText,
@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 = "50", name = "widthSpacer") int widthSpacer, @RequestParam(defaultValue = "50", name = "heightSpacer") int heightSpacer)
@RequestParam(defaultValue = "0", name = "rotation") float rotation, throws IOException {
@RequestParam(defaultValue = "50", name = "widthSpacer") int widthSpacer,
@RequestParam(defaultValue = "50", name = "heightSpacer") int heightSpacer) throws IOException {
// Load the input PDF // Load the input PDF
PDDocument document = PDDocument.load(pdfFile.getInputStream()); PDDocument document = PDDocument.load(pdfFile.getInputStream());
// 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 contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
PDPageContentStream.AppendMode.APPEND, true);
// Set font of watermark // Set font of watermark
PDFont font = PDType1Font.HELVETICA_BOLD; PDFont font = PDType1Font.HELVETICA_BOLD;
contentStream.beginText(); contentStream.beginText();
contentStream.setFont(font, fontSize); contentStream.setFont(font, fontSize);
contentStream.setNonStrokingColor(Color.LIGHT_GRAY); contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
// Set size and location of watermark // Set size and location of watermark
float pageWidth = page.getMediaBox().getWidth(); float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight(); float pageHeight = page.getMediaBox().getHeight();
float watermarkWidth = widthSpacer + font.getStringWidth(watermarkText) * fontSize / 1000; float watermarkWidth = widthSpacer + font.getStringWidth(watermarkText) * fontSize / 1000;
float watermarkHeight = heightSpacer + fontSize; float watermarkHeight = heightSpacer + fontSize;
int watermarkRows = (int) (pageHeight / watermarkHeight + 1); int watermarkRows = (int) (pageHeight / watermarkHeight + 1);
int watermarkCols = (int) (pageWidth / watermarkWidth + 1); int watermarkCols = (int) (pageWidth / watermarkWidth + 1);
// Add the watermark text // Add the watermark text
for (int i = 0; i < watermarkRows; i++) { for (int i = 0; i < watermarkRows; i++) {
for (int j = 0; j < watermarkCols; j++) { for (int j = 0; j < watermarkCols; j++) {
contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation), contentStream.setTextMatrix(Matrix.getRotateInstance((float) Math.toRadians(rotation), j * watermarkWidth, i * watermarkHeight));
j * watermarkWidth, i * watermarkHeight)); contentStream.showTextWithPositioning(new Object[] { watermarkText });
contentStream.showTextWithPositioning(new Object[] { watermarkText }); }
} }
}
contentStream.endText(); contentStream.endText();
// Close the content stream // Close the content stream
contentStream.close(); contentStream.close();
} }
return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_watermarked.pdf"); return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_watermarked.pdf");
} }
} }

View File

@ -34,172 +34,169 @@ import com.spire.pdf.PdfDocument;
public class PdfUtils { 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[] convertToPdf(InputStream imageStream) throws IOException {
// Create a File object for the image // Create a File object for the image
File imageFile = new File("image.jpg"); File imageFile = new File("image.jpg");
try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = imageStream) { 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
while ((len = input.read(buffer)) != -1) { while ((len = input.read(buffer)) != -1) {
fos.write(buffer, 0, len); fos.write(buffer, 0, len);
} }
logger.info("Image successfully written to file: {}", imageFile.getAbsolutePath()); logger.info("Image successfully written to file: {}", imageFile.getAbsolutePath());
} catch (IOException e) { } catch (IOException e) {
logger.error("Error writing image to file: {}", imageFile.getAbsolutePath(), e); logger.error("Error writing image to file: {}", imageFile.getAbsolutePath(), e);
throw e; throw e;
} }
try (PDDocument doc = new PDDocument()) { 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);
// 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);
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
// Draw the image onto the page // Draw the image onto the page
contentStream.drawImage(image, 0, 0); contentStream.drawImage(image, 0, 0);
logger.info("Image successfully added to PDF"); logger.info("Image successfully added to PDF");
} 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;
} }
// 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, public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI, int contrast, int brightness)
int DPI, int contrast, int brightness) throws IOException, Exception { throws IOException, Exception {
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) { try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) {
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
int pageCount = document.getNumberOfPages(); int pageCount = document.getNumberOfPages();
List<BufferedImage> images = new ArrayList<>(); List<BufferedImage> images = new ArrayList<>();
// Create images of all pages // Create images of all pages
for (int i = 0; i < pageCount; i++) { for (int i = 0; i < pageCount; i++) {
BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, colorType); BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, colorType);
float scale = contrast + 1f; float scale = contrast + 1f;
float offset = brightness; float offset = brightness;
RescaleOp rescaleOp = new RescaleOp(scale, offset, null); RescaleOp rescaleOp = new RescaleOp(scale, offset, null);
BufferedImage dest = rescaleOp.filter(image, null); BufferedImage dest = rescaleOp.filter(image, null);
images.add(dest); images.add(dest);
} }
if (singleImage) { if (singleImage) {
// Combine all images into a single big image // Combine all images into a single big image
BufferedImage combined = new BufferedImage(images.get(0).getWidth(), BufferedImage combined = new BufferedImage(images.get(0).getWidth(), images.get(0).getHeight() * pageCount, BufferedImage.TYPE_INT_RGB);
images.get(0).getHeight() * pageCount, BufferedImage.TYPE_INT_RGB); Graphics g = combined.getGraphics();
Graphics g = combined.getGraphics(); for (int i = 0; i < images.size(); i++) {
for (int i = 0; i < images.size(); i++) { g.drawImage(images.get(i), 0, i * images.get(0).getHeight(), null);
g.drawImage(images.get(i), 0, i * images.get(0).getHeight(), null); }
} images = Arrays.asList(combined);
images = Arrays.asList(combined); }
}
// Create a ByteArrayOutputStream to save the image(s) to // Create a ByteArrayOutputStream to save the image(s) to
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (singleImage) { if (singleImage) {
// Write the image to the output stream // Write the image to the output stream
ImageIO.write(images.get(0), "PNG", baos); ImageIO.write(images.get(0), "PNG", baos);
// Log that the image was successfully written to the byte array // Log that the image was successfully written to the byte array
logger.info("Image successfully written to byte array"); logger.info("Image successfully written to byte array");
} else { } else {
// Zip the images and return as byte array // Zip the images and return as byte array
try (ZipOutputStream zos = new ZipOutputStream(baos)) { try (ZipOutputStream zos = new ZipOutputStream(baos)) {
for (int i = 0; i < images.size(); i++) { for (int i = 0; i < images.size(); i++) {
BufferedImage image = images.get(i); BufferedImage image = images.get(i);
try (ByteArrayOutputStream baosImage = new ByteArrayOutputStream()) { try (ByteArrayOutputStream baosImage = new ByteArrayOutputStream()) {
ImageIO.write(image, "PNG", baosImage); ImageIO.write(image, "PNG", baosImage);
// Add the image to the zip file // Add the image to the zip file
zos.putNextEntry(new ZipEntry(String.format("page_%d.%s", i + 1, "png"))); zos.putNextEntry(new ZipEntry(String.format("page_%d.%s", i + 1, "png")));
zos.write(baosImage.toByteArray()); zos.write(baosImage.toByteArray());
} }
} }
// Log that the images were successfully written to the byte array // Log that the images were successfully written to the byte array
logger.info("Images successfully written to byte array as a zip"); logger.info("Images successfully written to byte array as a zip");
} }
} }
return baos.toByteArray(); return baos.toByteArray();
} catch (IOException e) { } catch (IOException e) {
// Log an error message if there is an issue converting the PDF to an image // Log an error message if there is an issue converting the PDF to an image
logger.error("Error converting PDF to image", e); logger.error("Error converting PDF to image", e);
throw e; throw e;
} }
} }
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) throws IOException {
try (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); PDPage page = document.getPage(0);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true)) {
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"); }
} // 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) {
} catch (IOException e) { // Log an error message if there is an issue overlaying the image onto the PDF
// Log an error message if there is an issue overlaying the image onto the PDF logger.error("Error overlaying image onto PDF", e);
logger.error("Error overlaying image onto PDF", e); throw e;
throw e; }
} }
}
public static ResponseEntity<byte[]> pdfDocToWebResponse(PdfDocument document, String docName) throws IOException { public static ResponseEntity<byte[]> pdfDocToWebResponse(PdfDocument document, String docName) throws IOException {
// Open Byte Array and save document to it // Open Byte Array and save document to it
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.saveToStream(baos); document.saveToStream(baos);
// Close the document // Close the document
document.close(); document.close();
return PdfUtils.boasToWebResponse(baos, docName); return PdfUtils.boasToWebResponse(baos, docName);
} }
public static ResponseEntity<byte[]> pdfDocToWebResponse(PDDocument document, String docName) throws IOException { public static ResponseEntity<byte[]> pdfDocToWebResponse(PDDocument document, String docName) throws IOException {
// Open Byte Array and save document to it // Open Byte Array and save document to it
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos); document.save(baos);
// Close the document // Close the document
document.close(); document.close();
return PdfUtils.boasToWebResponse(baos, docName); return PdfUtils.boasToWebResponse(baos, docName);
} }
public static ResponseEntity<byte[]> boasToWebResponse(ByteArrayOutputStream baos, String docName) public static ResponseEntity<byte[]> boasToWebResponse(ByteArrayOutputStream baos, String docName) throws IOException {
throws IOException { return PdfUtils.bytesToWebResponse(baos.toByteArray(), docName);
return PdfUtils.bytesToWebResponse(baos.toByteArray(), docName);
} }
public static ResponseEntity<byte[]> bytesToWebResponse(byte[] bytes, String docName) throws IOException { public static ResponseEntity<byte[]> bytesToWebResponse(byte[] bytes, String docName) throws IOException {
// Return the PDF as a response // Return the PDF as a response
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF); headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentLength(bytes.length); headers.setContentLength(bytes.length);
headers.setContentDispositionFormData("attachment", docName); headers.setContentDispositionFormData("attachment", docName);
return new ResponseEntity<>(bytes, headers, HttpStatus.OK); return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
} }
} }