2023-04-28 23:18:10 +01:00
package stirling.software.SPDF.controller.api ;
import java.io.IOException ;
2023-08-17 22:03:36 +01:00
import java.io.InputStream ;
import java.nio.file.Files ;
import java.nio.file.Paths ;
import java.nio.file.attribute.BasicFileAttributes ;
2023-04-28 23:18:10 +01:00
import java.util.ArrayList ;
2023-08-17 22:03:36 +01:00
import java.util.Arrays ;
import java.util.Comparator ;
2023-04-28 23:18:10 +01:00
import java.util.List ;
import org.apache.pdfbox.pdmodel.PDDocument ;
import org.apache.pdfbox.pdmodel.PDPage ;
import org.apache.pdfbox.pdmodel.PDPageTree ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import org.springframework.http.ResponseEntity ;
import org.springframework.web.bind.annotation.PostMapping ;
2023-08-17 22:03:36 +01:00
import org.springframework.web.bind.annotation.RequestParam ;
2023-04-28 23:18:10 +01:00
import org.springframework.web.bind.annotation.RequestPart ;
import org.springframework.web.bind.annotation.RestController ;
import org.springframework.web.multipart.MultipartFile ;
2023-08-17 22:03:36 +01:00
import io.swagger.v3.oas.annotations.media.Schema ;
2023-05-13 10:32:47 +01:00
import io.swagger.v3.oas.annotations.Operation ;
import io.swagger.v3.oas.annotations.Parameter ;
2023-06-25 09:16:32 +01:00
import io.swagger.v3.oas.annotations.tags.Tag ;
2023-05-31 20:15:48 +01:00
import stirling.software.SPDF.utils.WebResponseUtils ;
2023-04-28 23:18:10 +01:00
@RestController
2023-06-25 09:16:32 +01:00
@Tag ( name = " General " , description = " General APIs " )
2023-04-28 23:18:10 +01:00
public class MergeController {
private static final Logger logger = LoggerFactory . getLogger ( MergeController . class ) ;
2023-08-17 22:03:36 +01:00
private PDDocument mergeDocuments ( List < PDDocument > documents ) throws IOException {
PDDocument mergedDoc = new PDDocument ( ) ;
for ( PDDocument doc : documents ) {
for ( PDPage page : doc . getPages ( ) ) {
mergedDoc . addPage ( page ) ;
2023-04-28 23:18:10 +01:00
}
2023-08-17 22:03:36 +01:00
}
return mergedDoc ;
}
2023-04-28 23:18:10 +01:00
2023-08-17 22:03:36 +01:00
private Comparator < MultipartFile > getSortComparator ( String sortType ) {
switch ( sortType ) {
case " byFileName " :
return Comparator . comparing ( MultipartFile : : getOriginalFilename ) ;
case " byDateModified " :
return ( file1 , file2 ) - > {
try {
BasicFileAttributes attr1 = Files . readAttributes ( Paths . get ( file1 . getOriginalFilename ( ) ) , BasicFileAttributes . class ) ;
BasicFileAttributes attr2 = Files . readAttributes ( Paths . get ( file2 . getOriginalFilename ( ) ) , BasicFileAttributes . class ) ;
return attr1 . lastModifiedTime ( ) . compareTo ( attr2 . lastModifiedTime ( ) ) ;
} catch ( IOException e ) {
return 0 ; // If there's an error, treat them as equal
}
} ;
case " byDateCreated " :
return ( file1 , file2 ) - > {
try {
BasicFileAttributes attr1 = Files . readAttributes ( Paths . get ( file1 . getOriginalFilename ( ) ) , BasicFileAttributes . class ) ;
BasicFileAttributes attr2 = Files . readAttributes ( Paths . get ( file2 . getOriginalFilename ( ) ) , BasicFileAttributes . class ) ;
return attr1 . creationTime ( ) . compareTo ( attr2 . creationTime ( ) ) ;
} catch ( IOException e ) {
return 0 ; // If there's an error, treat them as equal
}
} ;
case " byPDFTitle " :
return ( file1 , file2 ) - > {
try ( PDDocument doc1 = PDDocument . load ( file1 . getInputStream ( ) ) ;
PDDocument doc2 = PDDocument . load ( file2 . getInputStream ( ) ) ) {
String title1 = doc1 . getDocumentInformation ( ) . getTitle ( ) ;
String title2 = doc2 . getDocumentInformation ( ) . getTitle ( ) ;
return title1 . compareTo ( title2 ) ;
} catch ( IOException e ) {
return 0 ;
}
} ;
case " orderProvided " :
default :
return ( file1 , file2 ) - > 0 ; // Default is the order provided
2023-04-28 23:18:10 +01:00
}
2023-08-17 22:03:36 +01:00
}
2023-04-28 23:18:10 +01:00
2023-08-17 22:03:36 +01:00
@PostMapping ( consumes = " multipart/form-data " , value = " /merge-pdfs " )
@Operation ( summary = " Merge multiple PDF files into one " ,
description = " This endpoint merges multiple PDF files into a single PDF file. The merged file will contain all pages from the input files in the order they were provided. Input:PDF Output:PDF Type:MISO " )
public ResponseEntity < byte [ ] > mergePdfs (
@RequestPart ( required = true , value = " fileInput " ) MultipartFile [ ] files ,
@RequestParam ( value = " sortType " , defaultValue = " orderProvided " )
@Parameter ( schema = @Schema ( description = " The type of sorting to be applied on the input files before merging. " ,
allowableValues = {
" orderProvided " ,
" byFileName " ,
" byDateModified " ,
" byDateCreated " ,
" byPDFTitle "
} ) )
String sortType ) throws IOException {
2023-04-28 23:18:10 +01:00
2023-08-17 22:03:36 +01:00
Arrays . sort ( files , getSortComparator ( sortType ) ) ;
2023-04-28 23:18:10 +01:00
2023-08-17 22:03:36 +01:00
List < PDDocument > documents = new ArrayList < > ( ) ;
for ( MultipartFile file : files ) {
try ( InputStream is = file . getInputStream ( ) ) {
documents . add ( PDDocument . load ( is ) ) ;
}
}
2023-04-28 23:18:10 +01:00
2023-08-17 22:03:36 +01:00
try ( PDDocument mergedDoc = mergeDocuments ( documents ) ) {
2023-05-31 20:15:48 +01:00
ResponseEntity < byte [ ] > response = WebResponseUtils . pdfDocToWebResponse ( mergedDoc , files [ 0 ] . getOriginalFilename ( ) . replaceFirst ( " [.][^.]+$ " , " " ) + " _merged.pdf " ) ;
2023-04-28 23:45:54 +01:00
return response ;
2023-08-17 22:03:36 +01:00
} finally {
for ( PDDocument doc : documents ) {
if ( doc ! = null ) {
doc . close ( ) ;
}
}
2023-04-28 23:18:10 +01:00
}
2023-08-17 22:03:36 +01:00
}
2023-04-28 23:18:10 +01:00
2023-02-03 20:26:35 +00:00
}