How to Merge Two or More PDFs in Java (or Kotlin)

Many companies hold reams of documents about customers, employees, inventory, etc. And in some cases, it can be useful to collate these documents together in order to redistribute them. But how do you do that? In today’s post, I’m going to show you how you can merge multiple documents into one using Java and Kotlin, thereby solving the redistribution problem!

Java

Java has a long history and is used in many different environments. Today, it’s most likely known for being used with Android or on backend server work. Because it’s been around for such a long time and is still popular, we can be sure it won’t go away anytime soon.

Kotlin

Compared to Java, Kotlin is the new kid on the block. The great thing is that it works in most places Java does, so if you want the benefits of a new and interesting language but with the environment of Java, Kotlin is the way to go. If you’re looking for an expressive language with the possibility of native JavaScript and Java interoperability, it could be worth checking out the Kotlin guides.

Merging Example

In our hypothetical situation, we’re going to have two documents, each consisting of one page. We’re going to merge these two pages together to create a document with one page.

Copy
1
2
3
4
5
6
7
8
9
10
11
12
// Get two documents and merge them together. 0 denotes the page index of where to insert the document.
DocumentEditor documentEditor = new DocumentEditor();

// Import the two documents.
File dogDocument = new File("Assets/dog.pdf");
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, new FileDataProvider(dogDocument));
File catDocument = new File("Assets/cat.pdf");
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, new FileDataProvider(catDocument));

// Write out to a new file.
File outputFile = File.createTempFile("dogCatPair", ".pdf");
documentEditor.saveDocument(new FileDataProvider(outputFile));
Copy
1
2
3
4
5
6
7
8
9
10
11
12
// Get two documents and merge them together. 0 denotes the page index of where to insert the document.
val documentEditor = DocumentEditor()

// Import the two documents.
val dogDocument = File("Assets/dog.pdf")
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, FileDataProvider(dogDocument))
val catDocument = File("Assets/cat.pdf")
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, FileDataProvider(catDocument))

// Write out to a new file.
val outputFile = File.createTempFile("dogCatPair", ".pdf")
documentEditor.saveDocument(FileDataProvider(outputFile))

With just a few lines of code and the PSPDFKit Document Editor, we’ve managed to merge our documents into one.

Each document is added by calling the importDocument method, with 0 denoting index 0 and DocumentEditor.IndexPosition.BeforeIndex instructing the editor to place the pages before the given index (this is necessary for the first document, as there are no other indices to reference yet). Then we instruct the Document Editor where to find the document to import. In the code example above, we take a simple file path, but it’s also possible to pass a custom data provider that extends DataProvider to provide data from any source required, such as memory, network data, or even a cryptographic solution.

We can keep repeating these steps to merge as many documents as we desire. One factor to be aware of is the size of the PDFs in memory. Opening and appending PDFs can be a memory-intensive process, so if you are importing large documents, keep this in mind.

Extra Operations

We’ve completed our task and merged two documents together. So now let’s look into the many features of the Document Editor.

With the two documents combined into one, we now have a front page that does not reflect the data it holds.

So, how about we remove that page?

Copy
1
2
3
4
5
6
7
8
9
10
11
...
File projectDocument = new File("Assets/projectPlan.pdf");
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, new FileDataProvider(projectDocument));
File tpsDocument = new File("Assets/tpsReport.pdf");
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, new FileDataProvider(tpsDocument));

// Now remove the first page.
Set<Integer> pages = new HashSet<>();
pages.add(0);
documentEditor.removePages(pages);
...
Copy
1
2
3
4
5
6
7
8
9
...
val projectDocument = File("Assets/projectPlan.pdf")
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, FileDataProvider(projectDocument))
val tpsDocument = File("Assets/tpsReport.pdf")
documentEditor.importDocument(0, DocumentEditor.IndexPosition.BeforeIndex, FileDataProvider(tpsDocument))

// Now remove the first page.
documentEditor.removePages(setOf(0))
...

Again we’ve added the two documents, and for the final operation, we’ve instructed the Document Editor to remove the first page. We can continue to stage instructions like this to our heart’s desire — including but not limited to addPage, removePages, rotatepages, and setPageLabel — in order to create the final PDF needed.

Conclusion

This blog post has given a quick overview of the document editing possibilities of the PSPDFKit Java Library, and there is much more to explore. Feel free to jump into the guides and API documentation for more examples and other important features of the SDK.

PSPDFKit Library for Java/.NET

Download the free 60-day trial and integrate it with your web app today.

The data you submit is treated confidentially and will never be disclosed to third parties.
We may occasionally send you product news and important announcements.