All formats

Apache PDFBox

LanguageJava 8+
LicenseApache-2.0
Repositorygithub.com/apache/pdfbox
Documentationpdfbox.apache.org, migration guide to 3.0
Depends oncommons-logging; optional Bouncy Castle (signatures, certificate encryption), JAI codecs for JPEG 2000 and JBIG2
Read / writeyes / yes: text extraction, rendering, merge, split, forms, annotations, encryption, signatures, page creation

PDFBox is the Apache Software Foundation’s PDF library. It parses PDFs (also many broken ones), extracts text with PDFTextStripper, renders pages to BufferedImage with Java2D, merges and splits documents, fills and flattens AcroForms, encrypts and decrypts, and signs documents. Apache Tika uses it for PDF text extraction. A pdfbox-app jar provides command-line tools (export:text, render, merge, split, encrypt, decrypt).

Creating new documents works at the content-stream level: you set fonts and positions yourself, with no line wrapping or tables. Version 3.0 changed the API: files are loaded with Loader.loadPDF, and standard fonts are created with new PDType1Font(Standard14Fonts.FontName.HELVETICA).

Installation#

Maven:

XML
<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>3.0.8</version>
</dependency>

Gradle:

implementation("org.apache.pdfbox:pdfbox:3.0.8")

Basic usage: extract text from a PDF#

Java
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

public class ExtractText {
    public static void main(String[] args) throws IOException {
        try (PDDocument doc = Loader.loadPDF(new File("in.pdf"))) {
            System.out.println(doc.getNumberOfPages() + " pages");
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(true);  // reading order by position, helps with columns
            stripper.setStartPage(1);
            stripper.setEndPage(doc.getNumberOfPages());
            System.out.println(stripper.getText(doc));
        }
    }
}

How to render a PDF page to an image#

Java
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

try (PDDocument doc = Loader.loadPDF(new File("in.pdf"))) {
    PDFRenderer renderer = new PDFRenderer(doc);
    for (int i = 0; i < doc.getNumberOfPages(); i++) {
        BufferedImage image = renderer.renderImageWithDPI(i, 150, ImageType.RGB);
        ImageIO.write(image, "png", new File("page-" + (i + 1) + ".png"));
    }
}

How to merge PDF files#

Java
import java.io.File;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.multipdf.PDFMergerUtility;

PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource(new File("a.pdf"));
merger.addSource(new File("b.pdf"));
merger.setDestinationFileName("merged.pdf");
merger.mergeDocuments(IOUtils.createMemoryOnlyStreamCache());

How to split a PDF into pages#

Java
import java.util.List;
import org.apache.pdfbox.multipdf.Splitter;

try (PDDocument doc = Loader.loadPDF(new File("in.pdf"))) {
    Splitter splitter = new Splitter();
    splitter.setSplitAtPage(1);  // one page per document
    List<PDDocument> parts = splitter.split(doc);
    for (int i = 0; i < parts.size(); i++) {
        try (PDDocument part = parts.get(i)) {
            part.save("page-" + (i + 1) + ".pdf");
        }
    }
}

How to create a PDF with text#

Java
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;

try (PDDocument doc = new PDDocument()) {
    PDPage page = new PDPage(PDRectangle.A4);
    doc.addPage(page);
    PDType1Font font = new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD);
    try (PDPageContentStream cs = new PDPageContentStream(doc, page)) {
        cs.beginText();
        cs.setFont(font, 24);
        cs.newLineAtOffset(72, 770);  // origin is bottom-left
        cs.showText("Hello, PDF!");
        cs.endText();
    }
    doc.getDocumentInformation().setTitle("Hello");
    doc.save("hello.pdf");
}

Standard 14 fonts only cover WinAnsi characters; for other text load a TrueType font with PDType0Font.load(doc, new File("DejaVuSans.ttf")).

How to fill a PDF form#

Java
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;

try (PDDocument doc = Loader.loadPDF(new File("form.pdf"))) {
    PDAcroForm form = doc.getDocumentCatalog().getAcroForm();
    for (PDField field : form.getFieldTree())
        System.out.println(field.getFullyQualifiedName() + " = " + field.getValueAsString());
    form.getField("name").setValue("Jane Doe");
    form.flatten();  // optional
    doc.save("filled.pdf");
}

How to rotate pages, read metadata and encrypt#

Java
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;

try (PDDocument doc = Loader.loadPDF(new File("in.pdf"))) {
    PDDocumentInformation info = doc.getDocumentInformation();
    System.out.println("Title: " + info.getTitle() + ", Author: " + info.getAuthor()
        + ", PDF " + doc.getVersion());

    for (PDPage page : doc.getPages())
        page.setRotation((page.getRotation() + 90) % 360);

    AccessPermission ap = new AccessPermission();
    ap.setCanModify(false);
    StandardProtectionPolicy policy = new StandardProtectionPolicy("owner", "user", ap);
    policy.setEncryptionKeyLength(256);  // AES-256
    doc.protect(policy);
    doc.save("out.pdf");
}

// decrypt: open with the password and remove security
try (PDDocument doc = Loader.loadPDF(new File("out.pdf"), "owner")) {
    doc.setAllSecurityToBeRemoved(true);
    doc.save("decrypted.pdf");
}

Tips#