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.
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.