Backend Development 14 min read

Generating and Merging PDFs with iTextPdf in a Java SpringBoot Application

This article demonstrates how to use the iTextPdf library in a Java SpringBoot project to create PDF templates, dynamically fill fixed and tabular invoice data, generate separate PDFs, and merge them into a single document, providing complete code examples and configuration details.

Top Architect
Top Architect
Top Architect
Generating and Merging PDFs with iTextPdf in a Java SpringBoot Application

Background

The original project used FanRuan reports, but a new requirement demanded a lightweight PDF solution without deploying an additional reporting server. The author decided to replace the old Jasper solution with iTextPdf, which can generate PDFs directly from Java.

Solution Overview

The invoice PDF consists of two parts: fixed information (buyer, seller) and dynamic product rows. The plan is to create two PDFs—one for each part—and then concatenate them into a single document.

Specific Implementation

1. Add iTextPdf dependencies

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.2</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

2. Design a PDF template

Use Adobe Acrobat (or any PDF form designer) to create a fillable form. Place text fields for the fixed sections and give each field a unique name; these names will be used as keys when filling the form with iTextPdf.

3. Write the Java program

The program is a simple main method for demonstration; in production it can be exposed as a SpringBoot service.

3.1 Read the template

PdfReader reader = new PdfReader("C:\\Users\\User\\Desktop\\开票预览模板.pdf");
// In production you may read from a byte[] stream instead of a file path

3.2 Fill the fixed‑information template

ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, bos1);
AcroFields form = stamper.getAcroFields();
form.setGenerateAppearances(true);
form.setField("purName", "购买方对应公司");
// Fill other fields similarly
stamper.close();

3.3 Generate the dynamic product table

Document doc = new Document(reader.getPageSize(1));
PdfWriter writer = PdfWriter.getInstance(doc, bos2);
doc.open();
PdfPTable table = new PdfPTable(2);
table.addCell("Name");
table.addCell("Age");
table.addCell("Alice");
table.addCell("25");
// Add rows from a List
>
doc.add(table);
doc.close();

3.4 Merge the two PDFs

public static byte[] merge(List
files) throws DocumentException, IOException {
    Document document = new Document();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    PdfCopy copy = new PdfCopy(document, bos);
    document.open();
    for (byte[] f : files) {
        PdfReader r = new PdfReader(f);
        int n = r.getNumberOfPages();
        for (int i = 1; i <= n; i++) {
            copy.addPage(copy.getImportedPage(r, i));
        }
        r.close();
    }
    document.close();
    return bos.toByteArray();
}

After generating the two byte streams ( bos1 and bos2 ), they are added to a list and passed to the merge method. The resulting byte array can be written to a file or uploaded to S3.

Post‑implementation Summary

The tutorial shows the complete workflow: add iTextPdf to the Maven project, create a fillable PDF template, programmatically populate fixed fields, build a dynamic table for product lines, and finally concatenate the PDFs. This approach eliminates the need for a separate reporting server and keeps the solution lightweight.

backendJavaSpringBootiTextPDFPDF generation
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.