PDF to PDF in Java
Overview
Merge, split and modify PDF documents with the PDFCrowd Java client. The client handles communication with the API, while processing runs on PDFCrowd's servers.
Installation
Add the Java client to the <dependencies> section of your
pom.xml, or see
other installation options.
<dependency> <groupId>com.pdfcrowd</groupId> <artifactId>pdfcrowd</artifactId> <version>6.7.0</version> </dependency>
Quick Start
The examples below use your API credentials. The examples use demo credentials, so you can try the API before getting your own API key. Update the input URLs and filenames as needed.
Merge PDFs
Merge a cover, proposal, price list and contact page in that order, then save the PDF locally as offer.pdf:
import com.pdfcrowd.Pdfcrowd; class Example { public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); client.addPdfFile("cover.pdf"); client.addPdfFile("proposal.pdf"); client.addPdfFile("price.pdf"); client.addPdfFile("contact.pdf"); client.convertToFile("offer.pdf"); } }
The client throws Pdfcrowd.Error on conversion or validation errors.
See Handle Errors.
Add a Watermark
Place the first page of watermark.pdf over every page of proposal.pdf and save the PDF locally as company_offer.pdf:
import com.pdfcrowd.Pdfcrowd; class Example { public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); client.setPageWatermark("watermark.pdf"); client.addPdfFile("proposal.pdf"); client.convertToFile("company_offer.pdf"); } }
Extract Pages
Extract page 3 and pages 7 through the end of a PDF, then save them locally as output.pdf:
import com.pdfcrowd.Pdfcrowd; class Example { public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); client.setAction("extract"); client.setPageRange("3,7-"); client.addPdfFile("13_pages.pdf"); client.convertToFile("output.pdf"); } }
Configure a Conversion
Authentication
Pass your PDFCrowd username and API key to
PdfToPdfClient.
Find your credentials on the API Keys page.
Add Input PDFs
Add each PDF before calling a conversion method. The default action joins the documents in the order they were added.
| Input | Method |
|---|---|
| Local PDF file | addPdfFile() |
| PDF bytes in memory | addPdfRawData() |
For encrypted input PDFs, set the document password with setInputPdfPassword() before conversion.
This is separate from your API key and the passwords used to protect the output PDF.
Send PDF Bytes
Read two local PDFs as bytes, merge them in order, and save the result locally as merged.pdf:
import com.pdfcrowd.Pdfcrowd; import java.nio.file.Files; import java.nio.file.Path; class Example { public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); client.addPdfRawData(Files.readAllBytes(Path.of("cover.pdf"))); client.addPdfRawData(Files.readAllBytes(Path.of("proposal.pdf"))); client.convertToFile("merged.pdf"); } }
Add Conversion Settings
Set conversion options on the client before calling a conversion method.
For example, client.setLinearize(true); optimizes the output PDF for progressive loading.
Common settings are listed below. See the method reference for all available options or browse Java examples.
| Purpose | Methods |
|---|---|
| Join, interleave, extract or delete pages | setAction(), setPageRange() |
| Watermark and background | setPageWatermark(), setPageBackground(), setMultipageWatermark(), setMultipageBackground() |
| Optimize for progressive loading | setLinearize() |
| Output protection | setEncrypt(), setUserPassword(), setOwnerPassword(), setNoCopy(), setNoPrint() |
| Metadata and attachments | setTitle(), setAuthor(), setUseMetadataFrom(), addAttachment() |
Use "extract" with a page range to keep selected pages, or "delete" to remove them.
The "shuffle" action interleaves pages from the input PDFs.
Handle the Result
Choose an Output
After adding the inputs and settings, choose how to receive the PDF:
| Output | Method |
|---|---|
| Local file | convertToFile() |
| Byte array | convert() |
OutputStream | convertToStream() |
File-output methods overwrite an existing destination file.
This example merges two PDFs, receives the result as a
byte[] and saves it as merged.pdf:
import com.pdfcrowd.Pdfcrowd; import java.nio.file.Files; import java.nio.file.Path; class Example { public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); client.addPdfFile("cover.pdf"); client.addPdfFile("proposal.pdf"); byte[] result = client.convert(); Files.write(Path.of("merged.pdf"), result); } }
When serving the result from a web application, use Content-Type: application/pdf.
Handle Errors
The client throws a Pdfcrowd.Error
exception on conversion or validation errors.
This example merges two PDFs and logs any PDFCrowd error, including its
HTTP status and reason code:
import com.pdfcrowd.Pdfcrowd; import java.util.logging.Level; import java.util.logging.Logger; class Example { private static final Logger logger = Logger.getLogger(Example.class.getName()); public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); try { client.addPdfFile("cover.pdf"); client.addPdfFile("proposal.pdf"); client.convertToFile("merged.pdf"); } catch (Pdfcrowd.Error error) { logger.log(Level.SEVERE, "PDFCrowd conversion failed (status " + error.getStatusCode() + ", reason " + error.getReasonCode() + ")", error); throw error; } } }
Local Java errors, such as a failure to read an input file or write the output, may need separate handling.
Pdfcrowd.Error provides these methods:
| Method | Returns |
|---|---|
getStatusCode() | The HTTP status code, when available. |
getReasonCode() | The reason code identifying the specific error, or -1 if unavailable. |
getMessage() | The error message. |
getDocumentationLink() | A link to relevant documentation, when available. |
Common Status Codes
| Status | What it means | What to do |
|---|---|---|
400 | Invalid input, settings, or conversion failure | Read the reason code and correct the input or settings. |
401 | Missing credentials or an inactive license | Check your username, API key, and license status. |
403 | Suspended service or no credits remaining | Check your account and available credits. |
413 | Upload exceeds the 300 MB limit | Reduce the upload size. |
429 | Request rate limit reached | Wait and reduce the rate of new requests. |
430 | Concurrent request limit reached | Allow active requests to finish before starting more. |
503 | Temporary network issue | Check your retry policy before submitting another request. |
See all status and reason codes for specific explanations and Limits and Retries for retry behavior.
Read Conversion Information
This information is available after a conversion and describes the client's last conversion.
| Method | Use |
|---|---|
getJobId() | Identify the conversion in logs and support requests. |
getDebugLogUrl() | The URL of the conversion debug log when logging is enabled. |
getPageCount() | Read the number of pages in the PDF. |
getOutputSize() | Read the PDF size in bytes. |
getConsumedCreditCount() | Read the credits consumed by the conversion. |
getRemainingCreditCount() | Read the remaining credit count reported with the conversion. |
Limits and Retries
Request rate and concurrency limits depend on your license. Control how quickly
your application submits conversions and how many it runs at once. A
429 response concerns request rate; a 430 response
concerns requests already in progress. The maximum upload size is 300 MB.
The Java client automatically retries a request once when it receives HTTP
502 or 503. Use
setRetryCount()
to change that count, or set it to 0 to disable automatic retries.
Account for these retries when adding an application-level retry policy.
Troubleshooting
Inspect a Conversion
This example merges two PDFs with debug logging enabled and logs the debug log URL when available. Use the input and settings from the conversion you are investigating.
import com.pdfcrowd.Pdfcrowd; import java.util.logging.Level; import java.util.logging.Logger; class Example { private static final Logger logger = Logger.getLogger(Example.class.getName()); public static void main(String[] args) throws Exception { Pdfcrowd.PdfToPdfClient client = new Pdfcrowd.PdfToPdfClient("demo", "demo"); try { client.addPdfFile("cover.pdf"); client.addPdfFile("proposal.pdf"); client.setDebugLog(true); client.convertToFile("merged.pdf"); } catch (Pdfcrowd.Error error) { logger.log(Level.SEVERE, "PDFCrowd conversion failed (status " + error.getStatusCode() + ", reason " + error.getReasonCode() + ")", error); throw error; } finally { String debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl != null && !debugLogUrl.isEmpty()) { logger.info("Debug log: " + debugLogUrl); } } } }
The debug log contains conversion settings and processing details. You can also find logs in your conversion history. A local or connection failure may occur before a conversion log is available.
Common Problems
| Problem | Check |
|---|---|
| The PDF cannot be read | Check file paths, read permissions and whether each input is a valid PDF. For encrypted inputs, use setInputPdfPassword(). |
| Pages are missing or in the wrong order | Check the order of added PDFs, the selected action and the page range. Use the default join action to append documents, or "shuffle" to interleave their pages. |
| The watermark hides the document | A watermark is placed over the page. Use a transparent watermark or setPageBackground() to place content behind the page. |
For help, contact support and include any available diagnostics, the client version, and enough detail to reproduce the problem.