Generare PDF dinamici con Python e Flask

In Python, una delle soluzioni più semplici per generare PDF dinamici con Flask è utilizzare la libreria reportlab, che permette di creare documenti PDF direttamente da codice. In questo articolo vedremo come costruire un endpoint REST che produce PDF con un header, un logo e testo personalizzato, senza scrivere file su disco.

Prerequisiti

Installa Flask e ReportLab nel tuo ambiente Python:

pip install flask reportlab

Struttura dell'applicazione

L'applicazione prevede:

  • Un endpoint POST per ricevere i dati JSON.
  • Generazione di un PDF in memoria.
  • Streaming del PDF direttamente nella risposta HTTP.

Codice di esempio

from flask import Flask, request, send_file
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from io import BytesIO
import datetime

app = Flask(__name__)

def generate_pdf(title, content):
    buffer = BytesIO()
    c = canvas.Canvas(buffer, pagesize=A4)
    width, height = A4

    # Logo
    try:
        c.drawImage("logo.png", 40, height - 80, width=50, height=50)
    except:
        pass

    # Titolo
    c.setFont("Helvetica-Bold", 20)
    c.drawString(100, height - 50, title)

    # Data
    c.setFont("Helvetica", 12)
    c.drawRightString(width - 40, height - 50, datetime.date.today().strftime("%d/%m/%Y"))

    # Linea
    c.line(40, height - 90, width - 40, height - 90)

    # Contenuto
    y = height - 120
    c.setFont("Helvetica", 12)
    for paragraph in content:
        text = c.beginText(40, y)
        text.setFont("Helvetica", 12)
        text.textLines(paragraph)
        c.drawText(text)
        y -= 40

    c.showPage()
    c.save()
    buffer.seek(0)
    return buffer

@app.route("/generate-pdf", methods=["POST"])
def generate_pdf_endpoint():
    data = request.get_json()
    title = data.get("title", "Documento")
    content = data.get("content", [])

    pdf_buffer = generate_pdf(title, content)

    return send_file(pdf_buffer, as_attachment=False,
                     mimetype="application/pdf",
                     download_name="custom-report.pdf")

if __name__ == "__main__":
    app.run(port=5000, debug=True)

Test dell'endpoint

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

curl -X POST http://localhost:5000/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 Flask e ReportLab è possibile generare PDF direttamente in memoria, includendo elementi grafici come loghi e linee di separazione, oltre a testo formattato. Questo approccio è veloce e non richiede file temporanei. Per layout più complessi o HTML-to-PDF, è possibile integrare librerie come WeasyPrint o xhtml2pdf.

Torna su