Building PDF documents with Apache PDFBox in NetBeans
Generating PDF files is a useful capability for Java applications that produce invoices, reports, certificates, shipping records or customer statements. Apache PDFBox provides an open-source API for creating, editing and reading PDF documents without requiring a desktop PDF editor. Learn more about Building Grails Service Layer With Transactional Methods.
NetBeans makes the workflow straightforward: create a Maven project, declare the PDFBox dependency, write a small service class and run the application with the IDE’s built-in tools. The same approach works on Windows, macOS and Linux, including development environments used by teams in Sydney, Melbourne and Brisbane.
Set up the NetBeans project
Create a Java application using Maven and select a current JDK, preferably Java 17 or later. Open pom.xml and add the PDFBox library. Version 3.x uses the Loader class for opening documents and includes the core classes required for common PDF generation tasks.
| Approach | Strengths | Suitable use |
|---|---|---|
| Apache PDFBox | Open source, flexible Java API, no external PDF application | Reports, invoices and document services |
| iText | Broad feature set and mature documentation | Advanced commercial or licensed workflows |
| HTML-to-PDF tools | Familiar layout with HTML and CSS | Branded templates and web-based reports |
PDFBox is a practical choice when licensing, deployment size and direct control over PDF objects matter. For an Australian business, it can generate A4 invoices containing an ABN, GST details and local currency formatting without sending customer data to a third-party conversion service.
Create a basic PDF file
Add this dependency inside the <dependencies> element of the Maven file:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.3</version>
</dependency>
Create a PdfReportService class and use PDDocument, PDPage and PDPageContentStream. A simple document can contain an A4 page, a title and several lines of text. Use try-with-resources so the document and content stream are closed reliably, even when saving fails.
try (PDDocument document = new PDDocument()) {
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
try (PDPageContentStream stream =
new PDPageContentStream(document, page)) {
stream.beginText();
stream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 16);
stream.newLineAtOffset(72, 750);
stream.showText("Customer statement");
stream.endText();
}
document.save("statement.pdf");
}
Add readable business content
PDFBox positions text using coordinates measured from the lower-left corner. This differs from HTML and many word processors, so define constants for margins, line height and page width rather than scattering numbers throughout the code. A4 is commonly used in Australia, while North American Letter sizing can cause unwanted line wrapping or clipped content.
For invoices sold in the Australian market, format amounts with NumberFormat.getCurrencyInstance(Locale.forLanguageTag("en-AU")). A document can include the supplier name, ABN, invoice date, payment terms and GST amount. Use PDType0Font with an embedded TrueType font when customers may have names containing characters unsupported by the standard PDF fonts.
Read and modify existing files
PDFBox can load an existing file with Loader.loadPDF(new File("input.pdf")). After loading, iterate through document.getPages() to inspect or add pages. You can also extract text with PDFTextStripper, which is useful for simple validation, searchable records and automated checks in a Java back end.
Some PDFs are scans, forms or files with unusual encoding, so extracted text may not match what appears visually. If a workflow includes product photographs or scanned receipts, a separate image-processing step may be appropriate; a batch image script can prepare oversized images before they are placed into a PDF.
Connect PDF generation to application services
Keep PDF creation in a dedicated service instead of placing layout code inside a controller or user-interface event. The service can accept a data transfer object containing customer, line-item and payment information, then return a byte[], write to a stream or save to a controlled storage location.
This separation fits Java enterprise applications using session beans. A stateful session bean can preserve a user’s report-building state, while a stateless service can generate the final file from complete data. Transaction boundaries should cover database reads and status updates, not lengthy PDF manipulation when it can be performed after the required data has been retrieved.
Handle pages, images and long reports
A report with many rows needs page-break logic. Track the current vertical position, and when it reaches the bottom margin, close the current content stream, create another PDPage, and continue writing. Repeat the header on each page so a printed page remains understandable when separated from the rest of the report.
Images can be inserted with PDImageXObject.createFromFile and drawn using drawImage. Resize large source files before embedding them because high-resolution product photos can make a PDF unnecessarily large. For a document service that processes many files, stream output where possible and avoid retaining several complete PDDocument instances in memory.
Test and troubleshoot in NetBeans
Run the Maven project from NetBeans and inspect the generated file in a desktop viewer. Test empty customer names, long addresses, negative adjustments, large item lists and Unicode characters. A Melbourne address may fit on one line while a long regional Queensland address wraps to several lines, so fixed-width assumptions should be tested with realistic data.
NetBeans can also keep Java source tidy through its import features; the guide on automatic import optimisation is useful when PDFBox classes and enterprise dependencies produce crowded imports. Unit tests should verify that the file exists, has a non-zero size, contains the expected page count and includes key extracted text.
Package the application for deployment
Before deployment, confirm that Maven includes PDFBox and its required dependencies in the application’s runtime classpath. A containerised service should write generated files to a configured temporary or object-storage location rather than relying on the project directory, which may be read-only on a production server.
Review PDFBox releases, Java compatibility and security notices before upgrading. The NetBeans archive provides additional background on IDE configuration and Java development practices that can help maintain the surrounding application. With clear service boundaries, sensible page layout and realistic Australian document data, PDF generation becomes a maintainable part of a larger Java system.