Generare PDF dinamici con Java e Spring Boot

In Java, uno dei modi più diffusi per generare PDF dinamici è utilizzare iText PDF. Integrando iText in un'applicazione Spring Boot, possiamo creare endpoint REST che generano documenti PDF in memoria e li restituiscono al client. In questo articolo vedremo un esempio pratico per realizzare un PDF con header, logo e testo formattato.

Prerequisiti

Aggiungi la dipendenza di iText nel file pom.xml del tuo progetto Spring Boot:

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

Struttura dell'applicazione

L'applicazione prevede:

  • Un controller REST con endpoint POST.
  • Generazione PDF in memoria tramite ByteArrayOutputStream.
  • Inclusione di header, logo e testo formattato.

Codice di esempio

package com.example.pdfdemo;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.time.LocalDate;
import java.util.List;

@RestController
public class PDFController {

    @PostMapping("/generate-pdf")
    public ResponseEntity<byte[]> generatePDF(@RequestBody PDFRequest request) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Document document = new Document();
            PdfWriter.getInstance(document, baos);
            document.open();

            // Logo
            try {
                Image logo = Image.getInstance("logo.png");
                logo.scaleToFit(50, 50);
                logo.setAbsolutePosition(50, 750);
                document.add(logo);
            } catch (Exception e) {
                // Ignora se il logo non è disponibile
            }

            // Titolo
            Paragraph title = new Paragraph(request.getTitle(), new Font(Font.FontFamily.HELVETICA, 20, Font.BOLD));
            title.setSpacingBefore(10);
            title.setIndentationLeft(110);
            document.add(title);

            // Data
            Paragraph date = new Paragraph(LocalDate.now().toString(), new Font(Font.FontFamily.HELVETICA, 12));
            date.setAlignment(Element.ALIGN_RIGHT);
            document.add(date);

            document.add(new Paragraph(" "));
            document.add(new LineSeparator());

            // Contenuto
            for (String paragraph : request.getContent()) {
                Paragraph p = new Paragraph(paragraph, new Font(Font.FontFamily.HELVETICA, 12));
                p.setSpacingBefore(10);
                document.add(p);
            }

            document.close();

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=custom-report.pdf")
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(baos.toByteArray());

        } catch (Exception e) {
            return ResponseEntity.status(500).build();
        }
    }
}

class PDFRequest {
    private String title;
    private List<String> content;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public List<String> getContent() {
        return content;
    }
    public void setContent(List<String> content) {
        this.content = content;
    }
}

Test dell'endpoint

Puoi testare il servizio con un comando curl, salvando il PDF generato:

curl -X POST http://localhost:8080/generate-pdf \
-H "Content-Type: application/json" \
-d '{
  "title": "Report Mensile",
  "content": [
    "Benvenuto al nostro report mensile.",
    "Le vendite sono aumentate del 15% rispetto al mese scorso.",
    "Grazie per l’attenzione."
  ]
}' --output report.pdf

Considerazioni finali

Con Spring Boot e iText è possibile generare PDF professionali in memoria, includendo elementi grafici e testo formattato. Questo approccio consente di creare documenti personalizzati senza l'uso di file temporanei. Per layout HTML complessi, si possono valutare librerie come flying-saucer o l'integrazione con OpenHTMLtoPDF.

Torna su