# PD4ML PDF Merge

PD4ML PDF Merge combines pages from one or more existing PDF files into a single new PDF. For each source you choose which pages to take and in which order, with a short page-range string such as `"2-5,8,10-12"` or `"1+,odd"`. The tool works on finished PDF files, not on HTML: use it to assemble documents from parts, cut a document down to the pages you need, or write an unencrypted copy of a protected PDF you have the password for. It is available as a Java API, `com.pd4ml.pdf.merge`, and as a command-line tool, `pd4mergecli`.

{% hint style="version" %}
Available from **PD4ML v4.1.1**. Part of `pd4ml.jar` and built on PD4ML's own PDF object layer, [PD4ML PDF COS](pd4ml-pdf-cos); no other PDF library is used.
{% endhint %}

## What you can do with it

- **Select page ranges per source**: single pages (`N`), ranges (`N-M`, also descending, e.g. `5-2`), open ranges to the last page (`N+`), and `odd`/`even` as filters over the other tokens. A page selected twice appears once, at its first position.
- **Merge any number of sources**: pages appear in the order the sources were added, and within a source in the order its range string lists them.
- **Read encrypted sources**: pass the user or owner password with the source; an empty password is tried as well.
- **Encrypt the output**: AES-256 with a user and an owner password, or a choice of `RC4_128`, `AES_128` or `AES_256` together with raw `/P` permission bits.
- **Filter, reorder or decrypt a single PDF**: with exactly one source, the page selection is optional; without it the output holds all pages of the source, decrypted unless output encryption is set.
- **Keep tagging where it exists**: the structure trees of tagged sources are merged into one `/StructTreeRoot`; structure elements that span excluded pages are pruned.
- **Write compact output**: objects that several pages of one source share, such as fonts, are copied once, and the merged pages are grouped in a page tree of at most 10 kids per node.

## Quick start

Take the odd pages of pages 2-5 of `A.pdf`, followed by pages 1, 3 and 6 to the last page of the password-protected `B.pdf`:

```java
import com.pd4ml.pdf.merge.PdfMergeException;
import com.pd4ml.pdf.merge.PdfMerger;

import java.io.File;

public class MergeQuickStart {
    public static void main(String[] args) throws PdfMergeException {
        PdfMerger merger = new PdfMerger();
        merger.addSource(new File("A.pdf")).selectPages("2-5,odd");
        merger.addSource(new File("B.pdf"), "secret").selectPages("1,3,6+");
        merger.merge(new File("merged.pdf"));
    }
}
```

Every failure (a wrong password, a page out of range, a malformed source) is reported as a `PdfMergeException`. To get the result as a `byte[]` instead of a file, call `mergeToBytes()`; to encrypt it, call `encryptOutput("openPassword", "ownerPassword")` before merging.

The same merge from the command line:

```bash
java -cp pd4ml.jar com.pd4ml.pdf.merge.cli.Pd4MergeCli \
     --in=A.pdf --pages=2-5,odd \
     --in=B.pdf --password=secret --pages=1,3,6+ \
     --out=merged.pdf
```

## When to use it

| You want to... | Use |
|---|---|
| combine or select pages of existing PDFs | PD4ML PDF Merge |
| make an existing PDF smaller | [PD4ML PDF Optimizer](pd4ml-pdf-optimizer) |
| sign a PDF digitally | [PD4ML PDF Signing](pd4ml-pdf-signing) |
| export or import annotations and form field values as XFDF | [PD4ML PDF XFDF](pd4ml-pdf-xfdf) |
| read, inspect or edit individual PDF objects | [PD4ML PDF COS](pd4ml-pdf-cos) |

PD4ML's main API also combines documents: `PdfDocument.append(...)` and `PdfDocument.mergePDFs(...)` join two whole documents, and `PD4ML.merge(...)` puts one page range of an existing PDF before or after a conversion result. Both use `PdfMerger` internally. Use PD4ML PDF Merge directly when you need more than two sources, a page selection per source, `odd`/`even` filters or reordering, or encrypted sources and output.

## In this section

- [PD4ML PDF Merge API - Programmer's Manual](pd4ml-pdf-merge/pd4ml-merge-manual): how a merge works, the `PdfMerger` and `PdfMergeSource` methods, the full page-range grammar, encryption, tagging reconciliation, error messages and limitations.
- [Examples](pd4ml-pdf-merge/pd4ml-merge-examples): eight runnable example classes from the `pd4ml-examples` repository, from a basic two-source merge to error handling.
- [pd4mergecli Reference](pd4ml-pdf-merge/pd4mergecli-reference): invocation, flags, exit codes, examples and troubleshooting for the command-line tool.
- [Javadoc](https://pd4ml.com/javadoc/com/pd4ml/pdf/merge/package-summary.html): API reference of the `com.pd4ml.pdf.merge` package.
