Merging Files with Java

Below is an example of how multiple PDF documents, containing a varying number of pages, can be merged together into one file, with all page ones together, followed by all page twos and so on. For this to work the dependencies iText and Apache Commons must be used.

Firstly, the file path is set and a check is made to see if it exists. This is followed by another check to verify that there are files to merge. The files are then processed one by one to find the number of pages that each PDF contains and this information is stored in a map along with the corresponding file name. All files without a ‘.pdf’ extension are ignored. Whilst doing this, a record is made of the maximum number of pages in an individual file. The map of file name and page information, along with the maximum number of pages figure, is then used to access pages in each file and check that the desired page actually exists in a particular file, which allows for PDFs of varying sizes to be merged. Finally, a confirmation message is displayed stating how many files have been merged.

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import java.io.File;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.io.FilenameUtils;

public class MergingFiles {

    public static void main(String[] args) {

        // File path.
        File path = new File("c:/demo");

        // Check to see if the file path exists.
        if (path.isDirectory()) {

            // Check if there are any files at the path.
            File [] files = path.listFiles();
            String fileExtension;

            if (files.length == 0) {

                System.out.println("There are no files to merge.");

            } else {

                // Source PDF.
                PdfDocument pdfFile;

                // Maximum number of pages.
                int maxPages = 0;

                // Files to process with number of pages.
                Map<File, Integer> filesToProcess = new TreeMap<File, Integer>();

                // Process the files at the path.
                for (File file : files) {

                    // Check if the item is a file.
                    if (file.isFile()) {

                        // Extract the file extension from the name.
                        fileExtension = FilenameUtils.getExtension(file.getName());

                        // Check if the file is a PDF file.
                        if (fileExtension.contains("pdf")) {

                            try {

                                // Assign the current PDF.
                                pdfFile = new PdfDocument(new PdfReader(file));

                                // Assign the number of pages to the maximum if greater
                                // than current value.
                                if (pdfFile.getNumberOfPages() > maxPages) {

                                    maxPages = pdfFile.getNumberOfPages();

                                }

                                // Add the file information to the map.
                                filesToProcess.put(file, pdfFile.getNumberOfPages());

                                // Close the PDF.
                                pdfFile.close();

                            } catch(Exception e) {

                                // If error, state the file could not be merged.
                                System.out.printf("The file \"%s\" cannot be merged.\n",
                                        file.getName());

                            }

                        }

                    }

                }

                // If there are PDFs to merge, process them.
                if (maxPages > 0 && filesToProcess.size() > 1) {

                    try {

                        // Current document.
                        PdfDocument currentDoc;

                        // New combined PDF objects.
                        PdfWriter writerCombined = new PdfWriter(path
                                + "\\combined.pdf");
                        PdfDocument pdfCombined = new PdfDocument(writerCombined);
                        Document documentCombined = new Document(pdfCombined);

                        // Combine PDFs into one file using the file information map.
                        for (int i = 1; i <= maxPages; i++) {

                            // Process the files to be merged.
                            for (File key: filesToProcess.keySet()) {

                                // Check if the current file has the desired page to merge.
                                if (i <= filesToProcess.get(key)) {

                                    // Assign the current PDF to a reader object.
                                    currentDoc = new PdfDocument(new PdfReader(path
                                            + "\\" + key.getName()));
                                    currentDoc.copyPagesTo(i, i, pdfCombined);

                                    // Close the current PDF.
                                    currentDoc.close();

                                }

                            }

                        }

                        // Close new combined PDF.
                        documentCombined.close();

                        // Feedback that file merge has been successful.
                        System.out.printf("%s files merged successfully.\n",
                                filesToProcess.size());

                    } catch(Exception e) {

                        // If error, state the file merge was unsuccessful.
                        System.out.println("The file merge was unsuccessful.\n");

                    }


                } else {

                    System.out.println("There are no files to merge.");

                }

            }

        } else {

            // Display a message stating file path does not exist.
            System.out.println("File path does not exist.");

        }

    }

}