Using ReportLab in Django 5

In this tutorial, we’ll learn how to generate PDF file using ReportLab library from within Django 5 project. This tutorial assumes that you are using Linux-based system, macOS or WSL and you already have Python3 installed in your system. So, let’s open the terminal and execute following command to create a new folder:

mkdir myapp

Go inside this newly created folder:

cd myapp

Then create virtual environment by executing following command:

python3 -m venv .env

Mount virtual environment:

source .env/bin/activate

(Once virtual environment is mounted, you’ll use command python instead of python3)

Now, install Django 5 along with ReportLab library by executing following command:

pip install django==5 reportlab

Then create the project:

django-admin startproject project .

Next, create an app named app:

python manage.py startapp app

In order to define routes for our app, create urls.py inside app folder by executing:

touch app/urls.py

Then, open app/urls.py and put following code inside it:

from django.urls import path
from . import views

app_name = "app"
urlpatterns = [
    path('', views.app, name='app'),
    path('pdf', views.pdf, name='pdf'),
]

Now, let’s propagate our app’s routes by amending project/urls.py as follows:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("app/", include("app.urls")),
    path("admin/", admin.site.urls),
]

Next, amend project/settings.py as follows, in order to add app into project:

INSTALLED_APPS = [
    'app.apps.AppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Now, let’s have our views’ logic by amending app/views.py as follows:

from django.shortcuts import render
from django.http import FileResponse
from . import utils

def app(request):
	return render(request, 'app/index.html', context={})

def pdf(request):
	buffer = utils.generate_pdf()
	return FileResponse(buffer, as_attachment=True, filename="app.pdf")

Create another file named utils.py inside app folder, by entering following command:

touch app/utils.py

We’ve created the utils.py file just to keep our views.py clean. Now insert PDF generating logic inside utils.py file:

import io
import reportlab
from reportlab.pdfgen import canvas

def generate_pdf():
    buffer = io.BytesIO()
    c = canvas.Canvas(buffer)

    c.drawString(100, 700, "Hello world!")

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

Run the migrations:

python manage.py migrate

Now, let’s move on to client-side. So, create templates folder app/templates/app by executing following command:

mkdir -p app/templates/app

Create base.html and index.html inside the above folder. You may execute following command to create these files in one go:

touch app/templates/app/{base,index}.html

Put following code inside app/templates/app/base.html:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<title>{% block title %}My App{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>

<div class="container-fluid">
<div class="row">

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">

{% block content %}
{% endblock %}

</main>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</body>
</html>


Then put following code inside app/templates/app/index.html:

{% extends "app/base.html" %}
{% block content %}


<div class="">
      <a href="{% url 'app:pdf' %}" class="btn btn-outline-secondary btn-sm">Generate PDF</a>
</div>

{% endblock %}

Finally, run dev server:

python manage.py runserver

Browse to localhost:8000/app and press Generate PDF button.

In next tutorial, we’ll start using ReportLab library practically, in order to generate PDFs using data from database.

Leave a Comment