Generar un PDF con Django a partir de una plantilla html

Generar un PDF con Django a partir de una plantilla html

Hola amigos lectores de CodigoJS, desarrollo web en Sevilla. En este artículo quiero compartir con ustedes como generar un PDF a partír de una plantilla HTML utilizando Django y Bootstrap 4.

Para el propósito de este artículo vamos dar por seguro que sabes iniciar un proyecto en Django, sino, te recomiendo que aprendas como crear un entorno virtual e iniciar un proyecto en Django en este enlace.

Instalacion de WeasyPrint

Para esta práctiva vamos a utilizar la librería te WeasyPrint la cual nos permitirá crear un PDF a partír de una plantilla HTML.

Lo primero que haremos será instalar WeasyPrint en su última versión.

$ pip install WeasyPrint

Seguido nos vamos a nuestro editor de código favorito y creamos una vista, la cual será la encargada de crear y devolver el archivo pdf a partir de una plantilla html.

from django.shortcuts import render
from django.http import HttpResponse
from django.template.loader import render_to_string

from weasyprint import HTML
from weasyprint.fonts import FontConfiguration

def export_pdf(request):

    context = {}
    html = render_to_string("report/report-pdf.html", context)

    response = HttpResponse(content_type="application/pdf")
    response["Content-Disposition"] = "inline; report.pdf"

    font_config = FontConfiguration()
    HTML(string=html).write_pdf(response, font_config=font_config)

    return response

Como podemos ver en este ejemplo, hemos creado una vista que renderiza la plantilla report-pdf.html a un string en la variable html. Después creamos un objeto HttpResponse de tipo application/pdf y le especificamos el nombre, en este caso report.pdf. Seguido creamos un objeto WeasyPrint’s HTML con el contendio de la variable html y lo escribimos en el response como si fuera un archivo. Adicionalmente usamos el objeto FontConfiguration el cual nos permite adjuntar y configurar fuentes web.

Crear la plantillas HTML

En el paso anterior creamos una vista muy sencilla para generar el pdf, pero ahora necesitamos crear la plantilla html a partir de la cual se creará el pdf.

Primero crearemos una plantilla base.html de la cual heredaremos en todas las plantillas html que necesitemos crear PDFs.

<!doctype html>
<html lang="es">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Reporte PDF</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <style>
        @page {
            size: "A4";
            margin: 1.0cm 1.5cm 3.5cm 1.5cm;
        }
        body {
            width: 100% !important;
            height: 100%;
            background: #fff;
            color: black;
            font-size: 100%;
            font-family: 'Roboto', sans-serif;
            line-height: 1.65;
            -webkit-font-smoothing: antialiased;
            -webkit-text-size-adjust: none; 
        }
    </style>
</head>
<body>
<main class="container">
    {% block content %}
    {% endblock %}
</main>
</body>
</html>

Lo más significativo en esta plantilla es que hemos insertado un enlace a bootstrap 4.5 para estilizar css como si tratara de una plantilla html normal. Hemos declarado algunos estilos css para establecer el tamaño de la página y los márgenes.

A continuación creamos la plantilla report-pdf.html que tendrá todo el contenido de nuestro pdf.

{% extends "report/base-pdf.html" %}
{% block content %}
<h1 class="text-center">Reporte PDF</h1>
<div class="row text-center">
    <div class="col-6">
        Columna 1
    </div>
    <div class="col-6">
        Columna 2
    </div>
</div>
<br/>
<h2>Ejemplo de una tabla en el reporte PDF</h2>
<table class="table">
    <tr>
        <td>Columna 1</td>
        <td>Columna 2</td>
        <td>Columna 3</td>
    </tr>
    <tr>
        <td>Columna 1</td>
        <td>Columna 2</td>
        <td>Columna 3</td>
    </tr>
    <tr>
        <td>Columna 1</td>
        <td>Columna 2</td>
        <td>Columna 3</td>
    </tr>
</table>
{% endblock %}

Lo más importante en esta plantilla es saber que hemos heredado de nuestra plantilla base.html.

El resto del contenido pertence al pdf que vamos a generar, como pueden ver, es puro html con clases de bootstrap. Hemos creado un H1 centrado, seguido dos columnas de ancho 6 y al final una tabla con 3 columnas.

URL de descarga del PDF

Por últimos vamos a crear la url de descarga del PDF, editamos el archivo de urls de nuestra aplicación y añadimos la siguiente configuración:

urlpatterns = [
    ...
    ...
    path('export/', views.export_pdf, name="export-pdf" )
]

Ejecutamos el servidor de desarrollo:

$ python manage.py runserver

Ahora, nos vamos a nuestro navegador y cargamos la siguiente url: localhost:8000/export y vemos como se descarga y se abre el PDF en nuestro navegador.

Generar PDF con Django

Conclusiones

Como hemos visto WeasyPrint nos permite generar un archivo en pdf a partir de una plantilla HTML de una forma muy fácil y rápido. Además es importante saber que WeasyPrint soporta los estilos hasta la versión CSS 2.1, por lo que debemos ser cuidadosos con los estilos que emplemos en la generación e los PDF.

Hasta aquí este pequeño tutorial, muy básico pero que te puede ayudar a generar archivos PDF mucho más complejos.