Merge Multiple PDF Files on Android

PSPDFKit for Android lets you merge or combine multiple documents using the Processor API or the Document Editor API. With this functionality, you can create a single document from multiple documents by taking only the specific pages you require.

Merging Documents with PDF Processor

With PSPDFKit, you can add pages from one document to another using PdfProcessor, which will allow merging multiple documents. To achieve this, load all the documents you wish to merge, add them to a list, and create a PdfProcessorTask in which to add the pages from each document. Finally, PdfProcessor can be used to process the added pages into the resulting document:

// Load a list of documents to merge.
val documents = listOf("document1.pdf", "document1.pdf", "document1.pdf")
    .map { assetName ->
        PdfDocumentLoader.openDocument(
            context,
            DocumentSource(AssetDataProvider(assetName))
        )
    }
val task = PdfProcessorTask.empty()
var totalPageCount = 0
for (document in documents) {
    for (i in 0 until document.pageCount) {
        // Increment the `totalPageCount` each time to add each new page
        // to the end of the document.
        // However, the pages can be inserted at any index you'd like.
        task.addNewPage(
            NewPage.fromPage(document, i).build(),
            totalPageCount++
        )
    }
}

// Finally, create the resulting document.
val outputFile = File(context.filesDir, "merged-documents.pdf")
PdfProcessor.processDocument(task, outputFile)
// Load a list of documents to merge.
final List<PdfDocument> documents = new ArrayList<>();
documents.add(PdfDocumentLoader.openDocument(context, new DocumentSource(
    new AssetDataProvider("document1.pdf"))));
documents.add(PdfDocumentLoader.openDocument(context, new DocumentSource(
    new AssetDataProvider("document2.pdf"))));
documents.add(PdfDocumentLoader.openDocument(context, new DocumentSource(
    new AssetDataProvider("document3.pdf"))));

final PdfProcessorTask task = PdfProcessorTask.empty();
int totalPageCount = 0;
for (PdfDocument document : documents) {
    for (int i = 0; i < document.getPageCount(); i++) {
        // Increment the `totalPageCount` each time to add each new page
        // to the end of the document.
        // However, the pages can be inserted at any index you'd like.
        task.addNewPage(NewPage.fromPage(document, i).build(), totalPageCount++);
    }
}

// Finally, create the resulting document.
final File outputFile = new File(context.getFilesDir(), "merged-documents.pdf");
PdfProcessor.processDocument(task, outputFile);

Merging Documents with Document Editor

PSPDFKit for Android’s PdfDocumentEditor won’t directly manipulate the returned document instance but will keep track of all editing steps internally, so they can be saved once editing is complete. In addition, the editing steps can be collected in a container, allowing you to undo and redo the editing steps. The document editing operations work with ReactiveX objects, returning io.reactivex.Single observable instances containing a list of EditingChanges

PSPDFKit allows you to merge documents using the PdfDocumentEditor.importDocument operation.

See the following code for how to achieve merging documents with the Document Editor and ReactiveX:

// Use the `PdfDocumentEditorFactory` to create a `PdfDocumentEditor`.
val documentEditor = PdfDocumentEditorFactory.createForDocument(document)

// Set up the output file location.
val outputFile: File = File(filesDir, "merged-documents.pdf")

// Make sure `disposable` is managed by the activity and destroyed correctly
// when the activity is destroyed.
val disposable = documentEditor.importDocument(context, DocumentSource(AssetDataProvider("documentToImport.pdf")), 0)
    .flatMapCompletable { documentEditor.saveDocument(context, outputFile.outputStream(), null) }
    // Use `subscribeOn` to put `saveDocument` on a background thread, as it can be slow.
    .subscribeOn(Schedulers.io())
    // Make sure the resulting document rendering goes back on the main thread.
    .observeOn(AndroidSchedulers.mainThread())
    // You can display the saved document in a new activity with the following action on `subscribe`.
    .subscribe { PdfActivity.showDocument(context, Uri.fromFile(outputFile), null) }
// Use the `PdfDocumentEditorFactory` to create a `PdfDocumentEditor`.
final PdfDocumentEditor documentEditor =
    PdfDocumentEditorFactory.createForDocument(document);

// Set up the output file location.
final File outputFile = new File(getFilesDir(), "merged-documents.pdf");

// Make sure `disposable` is managed by the activity and destroyed correctly
// when the activity is destroyed.
final Disposable disposable = documentEditor.importDocument(context,
    new DocumentSource(new AssetDataProvider("documentToImport.pdf")), 0)
        .flatMapCompletable(saved -> documentEditor.saveDocument(context, new FileOutputStream(outputFile), null))
        // Use `subscribeOn` to put `saveDocument` on a background thread, as it can be slow.
        .subscribeOn(Schedulers.io())
        // Make sure the resulting document rendering goes back on the main thread.
        .observeOn(AndroidSchedulers.mainThread())
        // You can display the saved document in a new activity with the following action on `subscribe`.
        .subscribe( () -> { PdfActivity.showDocument(context,
            Uri.fromFile(outputFile), null);
        });

Using the Built-In UI

PSPDFKit for Android comes with a prebuilt user interface for document editing that includes an option to import documents. To learn more, check out the Document Editor UI overview.