OpenPDF
| Language | Java 21+ (OpenPDF 2.1 and later; 2.0.x needs Java 17) |
|---|---|
| License | LGPL-2.1-or-later or MPL-2.0 |
| Repository | github.com/LibrePDF/OpenPDF |
| Documentation | README and wiki, examples in the openpdf-core tests |
| Depends on | optional Bouncy Castle (encryption, signatures), ICU4J |
| Read / write | yes / yes: create with paragraphs, tables, images; merge, stamp, fill forms, encrypt, basic text extraction |
OpenPDF continues iText 4, the last iText version under LGPL/MPL, so it has iText’s document model: Document, Paragraph, PdfPTable, Image, plus PdfReader, PdfStamper and PdfCopy to change existing files. It’s a good choice for generating reports and invoices in Java with a license that doesn’t force you to publish your code, and an easy migration from old iText 2/4 or iText 5 code.
OpenPDF 3.0 renamed the packages from com.lowagie.text to org.openpdf.text; older versions use the old names. Text extraction exists but is basic; for serious extraction use PDFBox. Two companion modules extend it: openpdf-html (HTML and CSS to PDF, a fork of Flying Saucer) and openpdf-renderer (renders pages to images).
Installation#
Maven:
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>3.0.5</version>
</dependency>
Gradle:
implementation("com.github.librepdf:openpdf:3.0.5")
Basic usage: create a PDF with text and a table#
import java.io.FileOutputStream;
import org.openpdf.text.Document;
import org.openpdf.text.Font;
import org.openpdf.text.FontFactory;
import org.openpdf.text.PageSize;
import org.openpdf.text.Paragraph;
import org.openpdf.text.pdf.PdfPTable;
import org.openpdf.text.pdf.PdfWriter;
public class Hello {
public static void main(String[] args) throws Exception {
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
try (FileOutputStream out = new FileOutputStream("hello.pdf")) {
PdfWriter.getInstance(document, out);
document.addTitle("Hello");
document.open();
Font title = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 24);
document.add(new Paragraph("Hello, PDF!", title));
document.add(new Paragraph("Created with OpenPDF."));
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
table.addCell("Item");
table.addCell("Price");
table.addCell("Widget");
table.addCell("9.99");
document.add(table);
document.close();
}
}
}
How to merge PDF files#
import java.io.FileOutputStream;
import org.openpdf.text.Document;
import org.openpdf.text.pdf.PdfCopy;
import org.openpdf.text.pdf.PdfReader;
Document document = new Document();
try (FileOutputStream out = new FileOutputStream("merged.pdf")) {
PdfCopy copy = new PdfCopy(document, out);
document.open();
for (String path : new String[] {"a.pdf", "b.pdf"}) {
PdfReader reader = new PdfReader(path);
for (int i = 1; i <= reader.getNumberOfPages(); i++)
copy.addPage(copy.getImportedPage(reader, i));
copy.freeReader(reader);
reader.close();
}
document.close();
}
How to extract text from a PDF#
import org.openpdf.text.pdf.PdfReader;
import org.openpdf.text.pdf.parser.PdfTextExtractor;
PdfReader reader = new PdfReader("in.pdf");
PdfTextExtractor extractor = new PdfTextExtractor(reader);
for (int i = 1; i <= reader.getNumberOfPages(); i++)
System.out.println(extractor.getTextFromPage(i));
reader.close();
How to fill a PDF form#
import java.io.FileOutputStream;
import org.openpdf.text.pdf.AcroFields;
import org.openpdf.text.pdf.PdfReader;
import org.openpdf.text.pdf.PdfStamper;
PdfReader reader = new PdfReader("form.pdf");
try (FileOutputStream out = new FileOutputStream("filled.pdf")) {
PdfStamper stamper = new PdfStamper(reader, out);
AcroFields fields = stamper.getAcroFields();
fields.getAllFields().keySet().forEach(System.out::println);
fields.setField("name", "Jane Doe");
stamper.setFormFlattening(true); // optional
stamper.close();
}
reader.close();
How to rotate pages, read metadata and encrypt#
import java.nio.charset.StandardCharsets;
import org.openpdf.text.pdf.PdfName;
import org.openpdf.text.pdf.PdfNumber;
import org.openpdf.text.pdf.PdfWriter;
PdfReader reader = new PdfReader("in.pdf");
System.out.println("Title: " + reader.getInfo().get("Title"));
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
int rotation = reader.getPageRotation(i);
reader.getPageN(i).put(PdfName.ROTATE, new PdfNumber((rotation + 90) % 360));
}
try (FileOutputStream out = new FileOutputStream("out.pdf")) {
PdfStamper stamper = new PdfStamper(reader, out);
stamper.setEncryption(
"user".getBytes(StandardCharsets.UTF_8),
"owner".getBytes(StandardCharsets.UTF_8),
PdfWriter.ALLOW_PRINTING,
PdfWriter.ENCRYPTION_AES_256_V3);
stamper.close();
}
reader.close();
Encryption needs Bouncy Castle (org.bouncycastle:bcprov-jdk18on) on the classpath. Open an encrypted file with new PdfReader("in.pdf", "owner".getBytes()).
Tips#
- Fonts:
FontFactory.register("DejaVuSans.ttf")andBaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED)embed TrueType fonts for Unicode text. PdfStamper.getOverContent(page)returns a canvas to draw watermarks or stamps on existing pages.- Add
com.github.librepdf:openpdf-htmlto convert HTML and CSS to PDF, orcom.github.librepdf:openpdf-rendererto render pages to images.