iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To merge complete PDF files in Java, use Apache PDFBox’s PDFMergerUtility. To include only selected pages, create a destination PDDocument and call importPage for each page you want. For PDFs supplied as InputStreams, the right loading code depends on whether your project uses PDFBox 2.x or 3.x: PDFBox 3 uses Loader and RandomAccessReadBuffer.
The examples below are explicitly for PDFBox 3 unless a section says otherwise. They cover whole-document concatenation, page selection, and stream-backed input, plus the version and resource-handling decisions that commonly cause problems.
How do I merge complete PDF files in Java?
For straightforward concatenation, create a PDFMergerUtility, add each source file in the order you want it to appear, set a destination, and call mergeDocuments. This PDFBox 3 example keeps the inputs and output separate:
import java.nio.file.Path;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource(Path.of("part-1.pdf").toFile());
merger.addSource(Path.of("part-2.pdf").toFile());
merger.setDestinationFileName("combined.pdf");
merger.mergeDocuments(null);
addSource calls establish the document order: in this example, the pages from part-1.pdf come before the pages from part-2.pdf. Add further sources in their intended order. The destination should be a different file from every input; writing over an input can corrupt it.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
The utility is intended to merge a list of PDF documents into a new document. It supports file sources as well as RandomAccessRead sources, and can write to a destination filename or an OutputStream. If your application needs to control output handling, set an output stream rather than a destination filename, and manage that stream’s lifecycle in your code.
What does mergeDocuments(null) mean?
In the PDFBox 3 API, mergeDocuments accepts a stream-cache factory. The example passes null, as in the documented practical pattern, rather than selecting an explicit cache strategy. For large or memory-sensitive jobs, choose and pass a cache factory deliberately instead of assuming that unlimited in-memory processing is appropriate. The available evidence does not establish a maximum safe file size or a memory threshold, so do not treat any particular file size as a universal cutoff.
When should I use the merger utility?
Use it when the requirement is to concatenate entire PDFs in a defined order. It keeps the application code concise and avoids manually creating a destination and importing every page. If you need to omit, reorder, or repeat individual pages, use the page-level approach instead.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsHow do I merge only certain pages?
Load a source document, create a new destination document, and import only the pages you want. The page indexes in the loop are zero-based: page index 0 is the first page, 2 is the third, and 5 is the sixth.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
import org.apache.pdfbox.pdmodel.PDDocument;
try (PDDocument source = Loader.loadPDF(
new RandomAccessReadBufferedFile("input.pdf"));
PDDocument destination = new PDDocument()) {
int[] wanted = {0, 2, 5};
for (int index : wanted) {
destination.importPage(source.getPage(index));
}
destination.save("selected-pages.pdf");
}
This creates a new PDF containing the selected pages in the order listed in wanted. Change the array to select different pages; for example, {5, 2, 0} imports those pages in reverse order. To import all pages from a source, iterate through source.getPages() and import each page.
What does importPage copy?
importPage copies page contents into the destination and creates a new page object. Its deep copy means the imported page’s resources remain available when the source document is closed. This makes it suitable for building a separate output document from chosen pages rather than leaving the output dependent on the source remaining open.
What can happen to annotations and page references?
Annotations may link to pages outside the set you import. Those references can make the destination unexpectedly large, and an annotation’s target may not be part of the selected-page output. Review such references when working with annotated or linked PDFs; remove irrelevant references if the output should not retain them. Do not assume that choosing a small number of visible pages guarantees a proportionally small output file.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →How do I merge PDFs from InputStreams?
In PDFBox 3, wrap an InputStream in RandomAccessReadBuffer and pass it to Loader.loadPDF. You can then import pages into a destination document as usual. This example reads a source from a file stream and writes the selected complete document to another path:
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
Path inputPath = Path.of("input.pdf");
Path outputPath = Path.of("output.pdf");
try (InputStream in = Files.newInputStream(inputPath);
PDDocument source = Loader.loadPDF(new RandomAccessReadBuffer(in));
PDDocument destination = new PDDocument()) {
for (PDPage page : source.getPages()) {
destination.importPage(page);
}
destination.save(outputPath.toFile());
}
RandomAccessReadBuffer stores the stream’s data in memory. That is convenient when an input arrives as a stream rather than a file path, but it is a real resource trade-off: the input bytes are held in memory. For larger jobs, consider how your application manages buffering and caching, and avoid assuming the stream-backed path has negligible memory cost.
How can I concatenate multiple streams?
For a page-level workflow, load each stream as a PDFBox 3 source, import the required pages into one destination document, then save the destination once. The source documents and streams should be managed with try-with-resources, and each source must remain available while its pages are being imported.
For whole-document concatenation, PDFBox 2.x offers PDFMergerUtility.addSource(InputStream) and addSources(List<InputStream>). Do not copy those overloads into a PDFBox 3 project: PDFBox 3 uses RandomAccessRead sources and the Loader loading API. If a stream must be reused or retained elsewhere, check the ownership and closing behavior of the APIs used in your version and ensure the application closes all resources it owns.
Free tools Windows power users keep installed
One-click scans. No signup required.
What is different between PDFBox 2.x and 3.x?
The key migration difference is how documents are loaded and how stream-backed sources are represented. Code that compiles against one major version may not compile against the other, so verify the version declared by your project before choosing an example.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
| Task | PDFBox 2.x | PDFBox 3.x |
|---|---|---|
| Load a PDF | The older PDDocument.load(...) family is used. |
Use Loader.loadPDF(...); PDFBox 3 removed the old PDDocument.load(...) family. |
| Whole-document merge from files | PDFMergerUtility is available; use signatures that match the 2.x dependency in the project. |
PDFMergerUtility accepts file sources; the example above uses addSource(File). |
| Whole-document merge from streams | addSource(InputStream) and addSources(List<InputStream>) are available. |
Adapt stream-backed input to RandomAccessRead; do not use the 2.x stream overload as though it were the 3.x API. |
| Stream-backed document loading | Use the 2.x loading APIs and types applicable to that version. | Wrap the stream in RandomAccessReadBuffer and load it with Loader. |
| Java requirement | Not stated here. | PDFBox 3 requires Java 8 or later. |
The table intentionally does not give a complete PDFBox 2.x code sample: loading and merge method signatures depend on the 2.x API, and mixing them with PDFBox 3 examples is a common source of compile errors. Keep each project’s imports, method calls, and dependency on the same major version. For migration work, consult the official PDFBox 3 migration guide and the API documentation for the exact version in use.
How should I choose between whole-document merge and page import?
The choice depends on whether you need to preserve a complete set of source documents or construct a new document from selected pages. These approaches solve different jobs rather than offering interchangeable syntax.
| Need | Best fit | Important trade-off |
|---|---|---|
| Append every page of each input in order | PDFMergerUtility |
Less page-by-page code; choose the merge mode and caching behavior deliberately. |
| Keep only chosen pages | Destination PDDocument plus importPage |
Requires explicit indexes and ordering; page-linked annotations may refer to omitted pages. |
Work with an InputStream in PDFBox 3 |
RandomAccessReadBuffer plus Loader, then import or merge as appropriate |
The buffer stores input data in memory. |
| Use legacy PDF structure behavior | PDFBox merger in legacy mode when required for the structure-tree case | Source documents remain open during the merge. |
| Release source documents earlier where applicable | PDFBox merger optimized-resources mode | Optimized mode does not merge every document element. |
PDFBox’s merger exposes PDFBOX_LEGACY_MODE and OPTIMIZE_RESOURCES_MODE. Optimized mode can release source documents earlier, but it does not merge every document element; legacy mode keeps files open and is required for some structure-tree cases. Do not choose a mode solely because its name sounds faster or more complete. Check whether your PDFs contain structures your application must retain, and verify output behavior with representative documents.
Recommended Free Tools
How do I avoid resource, concurrency, and output-file problems?
PDF merging involves file handles, document objects, and potentially substantial buffered data. Handle these explicitly to prevent leaks, corruption, and unsafe concurrent access.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
- Close every document. Put each
PDDocumentin try-with-resources. The PDFBox FAQ requires closing allPDDocumentobjects. - Do not write over an input. Use a destination path that differs from every source path; saving over an input may corrupt it.
- Do not access one document from multiple threads at once. The PDFBox FAQ states, “Only one thread may access a single document at a time.” Parallelize independent jobs only when each job has its own document objects.
- Choose caching for the workload. Pass an explicit stream-cache factory for large jobs when appropriate; no benchmark or universal safe memory limit is established here.
- Account for stream buffering. PDFBox 3’s
RandomAccessReadBufferholds the InputStream data in memory. - Validate page indexes. An index outside the source document’s page range cannot identify a page to import. Check the source page count before processing untrusted or variable input.
- Consider document features, not only visible pages. Annotations with references to pages outside the selected set can affect the output.
How can I check the expected merge behavior?
PDFBox 3 also provides a command-line merge equivalent, useful for checking that the intended result is simple concatenation before integrating the same operation into application code. The documented command pattern is java -jar pdfbox-app-3.y.z.jar merge -o=outfile -i=infile -i=infile. Replace the illustrative jar name and file names with the actual PDFBox app jar and paths for your installation; the command does not itself prove that a complex document’s forms, annotations, or structure are preserved as your application requires.
If the command-line output differs from your Java output, first confirm that both runs use the same PDFBox major version, input order, and source files. For page selection, compare the exact zero-based indexes and their order. For errors involving streams, confirm that the code uses the API family for the project’s PDFBox version.
Which approach should I use?
Use PDFMergerUtility for uncomplicated concatenation of complete PDFs. Use a destination PDDocument with importPage when the result must include only particular pages or must reorder them. In PDFBox 3, load stream-backed inputs through RandomAccessReadBuffer and Loader; keep every document closed safely, write to a separate output file, and select merge behavior with awareness of document structures and memory use.
Frequently Asked Questions
Can I merge encrypted PDFs with PDFBox?
The examples here do not establish password handling or the conditions for merging encrypted inputs. Check the PDFBox API documentation for the exact version and the permissions and credentials associated with each source before designing that workflow.
Does merging PDFs preserve bookmarks, forms, and document metadata?
Do not assume every document-level feature is preserved identically by every merge mode. In particular, PDFBox documents limits for optimized-resources mode and special structure-tree cases for legacy mode; test the features your output must retain.
Can I merge PDFs without creating a temporary output file?
The merger utility can target an OutputStream, so a filesystem destination is not the only output option. Your application remains responsible for managing that stream and for deciding where the resulting bytes should go.
Is PDFBox thread-safe for parallel PDF merging?
The PDFBox FAQ’s restriction is per document: only one thread may access a single document at a time. This does not by itself establish that every shared object or surrounding application component is safe to use concurrently.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

