DEV Community

Pilalo
Pilalo

Posted on

Generating PDF Files in Java: A Practical Guide

PDF generation is a common requirement in enterprise applications, whether you're producing invoices, reports, contracts, or digital receipts. While Java doesn't include native PDF creation capabilities in its standard library, several third-party libraries fill this gap effectively. In this article, I'll walk through how to generate PDF files programmatically using Spire.PDF for Java, covering several practical scenarios developers frequently encounter.

Why Generate PDFs Programmatically?

Before diving into code, it's worth understanding the scenarios where dynamic PDF generation adds value:

  • Invoice and Receipt Generation: E-commerce platforms automatically generating order confirmations
  • Financial Reporting: Banks and investment firms producing account statements
  • Document Automation: Legal and insurance firms creating contracts from templates
  • Certificate Creation: Educational platforms issuing completion certificates
  • Data Export: Converting database query results into formatted PDF reports

Programmatic generation ensures consistency, reduces manual work, and integrates seamlessly into automated workflows.

Setting Up the Library

To use Spire.PDF for Java, add the following dependency to your Maven pom.xml:

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>11.12.16</version>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

If you're using Gradle or managing JARs manually, you can obtain the artifact from the vendor's repository or distribution source.

Creating a Simple PDF Document

Let's start with a basic example: generating a PDF that contains a title, a paragraph of text, and a simple list. This demonstrates the fundamental pattern of creating a document, adding a page, and drawing content.

import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.*;

public class SimplePdfGenerator {
    public static void main(String[] args) {
        // Create a PdfDocument instance
        PdfDocument doc = new PdfDocument();

        // Configure page settings
        doc.getPageSettings().setSize(PdfPageSize.A4);
        doc.getPageSettings().setMargins(40f);

        // Add a page
        PdfPageBase page = doc.getPages().add();

        // Create fonts and brushes
        PdfFont titleFont = new PdfFont(PdfFontFamily.Helvetica, 18f, PdfFontStyle.Bold);
        PdfFont bodyFont = new PdfFont(PdfFontFamily.Helvetica, 12f);
        PdfSolidBrush brush = new PdfSolidBrush(new PdfRGBColor(Color.BLACK));

        // Draw title
        page.getCanvas().drawString("Monthly Report", titleFont, brush, 0, 0);

        // Draw paragraph
        String paragraph = "This report summarizes the key metrics for the current " +
                "month. All figures are preliminary and subject to final review.";
        page.getCanvas().drawString(paragraph, bodyFont, brush, 0, 40);

        // Draw a simple list
        String[] items = {"Revenue: $125,000", "Expenses: $78,000", "Net Profit: $47,000"};
        float y = 80;
        for (String item : items) {
            page.getCanvas().drawString("• " + item, bodyFont, brush, 10, y);
            y += 20;
        }

        // Save the document
        doc.saveToFile("SimpleReport.pdf");
        doc.close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points about this code:

  • PdfDocument is the root object representing the entire PDF file
  • PdfPageBase represents a single page; you can add multiple pages as needed
  • Content is drawn using drawString() with coordinates specifying the position
  • Fonts and colors are defined using PdfFont and PdfSolidBrush classes

Creating a PDF with Tables

Tables are essential for presenting structured data. Here's how to create a PDF containing a formatted table, which is useful for invoices, financial statements, or any tabular data:

import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import com.spire.pdf.tables.*;
import java.awt.*;

public class TablePdfGenerator {
    public static void main(String[] args) {
        PdfDocument doc = new PdfDocument();
        PdfPageBase page = doc.getPages().add();

        // Define table data
        String[][] data = {
            {"Product", "Quantity", "Unit Price", "Total"},
            {"Laptop", "2", "$899.00", "$1,798.00"},
            {"Monitor", "3", "$249.00", "$747.00"},
            {"Keyboard", "5", "$49.00", "$245.00"},
            {"Mouse", "5", "$25.00", "$125.00"}
        };

        // Create and configure table
        PdfTable table = new PdfTable();
        table.getStyle().setCellPadding(5f);
        table.getStyle().setBorderPen(new PdfPen(PdfBrushes.getBlack(), 1f));
        table.getStyle().setHeaderRowCount(1);

        // Populate table
        for (String[] row : data) {
            PdfRow pdfRow = table.getRows().add();
            for (String cell : row) {
                pdfRow.getCells().add(cell);
            }
        }

        // Apply header styling
        PdfRow headerRow = table.getRows().get(0);
        headerRow.getStyle().setBackgroundBrush(PdfBrushes.getLightGray());
        headerRow.getStyle().setFont(new PdfFont(PdfFontFamily.Helvetica, 12f, PdfFontStyle.Bold));

        // Draw table on page
        table.draw(page, 0, 30);

        doc.saveToFile("TableReport.pdf");
        doc.close();
    }
}
Enter fullscreen mode Exit fullscreen mode

The PdfTable class provides methods for styling borders, cell padding, and header formatting. Tables automatically calculate column widths based on content unless explicitly specified.

Creating a PDF with Images

Adding images to PDFs is straightforward. This example demonstrates how to embed an image at a specific location:

import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.geom.Rectangle2D;

public class ImagePdfGenerator {
    public static void main(String[] args) {
        PdfDocument doc = new PdfDocument();
        PdfPageBase page = doc.getPages().add();

        // Load image from file
        PdfImage image = PdfImage.fromFile("logo.png");

        // Define position and size
        float x = 50;
        float y = 50;
        float width = 200;
        float height = 100;

        // Draw image on page
        page.getCanvas().drawImage(image, new Rectangle2D.Float(x, y, width, height));

        // Draw caption below image
        PdfFont captionFont = new PdfFont(PdfFontFamily.Helvetica, 10f, PdfFontStyle.Italic);
        page.getCanvas().drawString("Figure 1: Company Logo", captionFont, 
                PdfBrushes.getDarkGray(), x, y + height + 5);

        doc.saveToFile("ImageDocument.pdf");
        doc.close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Images can be loaded from files, streams, or byte arrays. The drawImage() method accepts a Rectangle2D that defines both position and dimensions, allowing you to scale images as needed.

Generating PDF from HTML Content

Sometimes it's more practical to design document layouts using HTML and CSS rather than positioning elements programmatically. The library supports converting HTML strings, files, or URLs directly to PDF :

import com.spire.pdf.graphics.PdfMargins;
import com.spire.pdf.htmlconverter.LoadHtmlType;
import com.spire.pdf.htmlconverter.qt.HtmlConverter;
import com.spire.pdf.htmlconverter.qt.Size;

public class HtmlToPdfGenerator {
    public static void main(String[] args) {
        // HTML content as string
        String htmlContent = "<html>" +
                "<head><style>body { font-family: Arial; } h1 { color: #2c3e50; }</style></head>" +
                "<body>" +
                "<h1>Invoice #INV-2024-001</h1>" +
                "<p>Dear Customer,</p>" +
                "<p>Thank you for your business. Please find your invoice details below.</p>" +
                "<table border='1' style='border-collapse: collapse;'>" +
                "<tr><th>Item</th><th>Price</th></tr>" +
                "<tr><td>Consulting Services</td><td>$1,500.00</td></tr>" +
                "<tr><td>Software License</td><td>$299.00</td></tr>" +
                "</table>" +
                "</body></html>";

        // Specify output file
        String outputFile = "InvoiceFromHtml.pdf";

        // Convert HTML string to PDF
        HtmlConverter.convert(htmlContent, outputFile, 
                true,                    // enable JavaScript
                100000,                  // timeout in milliseconds
                new Size(700, 900),      // page size
                new PdfMargins(0),       // margins
                LoadHtmlType.Source_Code // input type
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

This approach is particularly useful when you already have HTML templates for emails or web pages and want to repurpose them for PDF generation.

Creating PDF from Plain Text

If you have plain text content that needs to be formatted as a PDF document, this can also be accomplished with the library. This is useful for converting log files, configuration data, or any textual output :

import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TextToPdfGenerator {
    public static void main(String[] args) throws IOException {
        // Read text from file
        String text = readTextFromFile("sample.txt");

        PdfDocument pdf = new PdfDocument();
        PdfPageBase page = pdf.getPages().add();

        // Create font and layout settings
        PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, 11));
        PdfTextLayout textLayout = new PdfTextLayout();
        textLayout.setBreak(PdfLayoutBreakType.Fit_Page);
        textLayout.setLayout(PdfLayoutType.Paginate);

        // Create text widget and draw
        PdfTextWidget textWidget = new PdfTextWidget(text, font, PdfBrushes.getBlack());
        Rectangle2D.Float bounds = new Rectangle2D.Float();
        bounds.setRect(0, 25, page.getCanvas().getClientSize().getWidth(), 
                page.getCanvas().getClientSize().getHeight());
        textWidget.draw(page, bounds, textLayout);

        pdf.saveToFile("TextConverted.pdf", FileFormat.PDF);
        pdf.close();
    }

    private static String readTextFromFile(String fileName) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }
        }
        return sb.toString();
    }
}
Enter fullscreen mode Exit fullscreen mode

The PdfTextWidget class handles text pagination automatically, flowing content across multiple pages when necessary.

Important Implementation Considerations

Font Availability: When using specific fonts, ensure they are available on the system or embed them in the PDF. The PdfTrueTypeFont class allows loading custom font files.

Memory Management: Generating large PDFs with many pages or high-resolution images can consume significant memory. Process documents sequentially and close resources promptly after saving.

Coordinate System: PDF coordinates originate at the top-left corner of the page. Plan your layout accordingly to avoid overlapping elements.

Licensing: The library requires a valid license for production use. Without a license, generated documents will contain an evaluation watermark. For development and testing, this is expected behavior.

Alternative Approaches

Several other libraries in the Java ecosystem offer PDF generation capabilities:

  • Apache PDFBox: Open-source library providing low-level PDF manipulation. Good for basic generation but requires more code for complex layouts.
  • iText: Widely used library with both open-source (AGPL) and commercial licensing options. Extensive features for advanced PDF workflows.
  • Apache FOP: XML-based formatting using XSL-FO templates. Well-suited for batch document generation from structured data.
  • JasperReports: Reporting library that can export to PDF along with other formats. Ideal for report-centric applications.

Each library has different strengths in terms of learning curve, feature set, and licensing terms.

Wrapping Up

Generating PDF files programmatically in Java is straightforward with the right tooling. Whether you need simple text documents, complex tables, embedded images, or HTML-to-PDF conversion, the API provides consistent methods to achieve your goals.

The examples in this guide cover common scenarios, but the library offers additional capabilities, including form field creation, digital signatures, encryption, and document merging—features that may be valuable as your application's PDF requirements grow.

Have you implemented PDF generation in your Java projects? What approaches have worked well for your use cases? I'd be interested in hearing about your experiences.

Top comments (0)