DEV Community

Cover image for Create PDF documents in Django - Tutorial for Beginners
Sm0ke
Sm0ke

Posted on • Edited on

Create PDF documents in Django - Tutorial for Beginners

Hello Coders,

This article explains how to generate PDF documents in Django using different techniques: via Django Shell, generate the document using a GET parameter pull an image from the internet, and use it to build a new (PDF) document.

👉 Django Apps a curated index with projects

For newcomers, Django is an open-source web framework designed by experienced developers that we can use to code from simple one-page projects to complex APIs and eCommerce platforms.

Topics covered in this tutorial

  • ✅ Built a new Django App
  • ✅ Configure Django to activate the new app
  • ✅Add/explain code for each case
    • Generate the PDF using Django CLI
    • Generate a (simple) dynamic PDF in a new page
    • Generate a dynamic PDF using an image
  • ✅ Mention a few open-source Django Templates

Create PDF using Django CLI

This tutorial assumes the audience has already a Django project and we will add a new app that implements the PDF generation process. Complete beginners without a working project might find a dedicated Django tutorial that covers the Django basics: Django for Beginners.


Install dependencies using a Virtual Environment

$ virtualenv env           # create a VENV
$ source env/bin/activate  # activate VENV
$
$ pip install reportlab
Enter fullscreen mode Exit fullscreen mode

reportlab is the library that brings all the PDF magic to our app. Let's use it and create a simple PDF document right in the Django shell:

$ python ./manage.py shell                   # start Django CLI
>>>
>>> import reportlab                         # import the library
>>> from reportlab.pdfgen import canvas      # import modules 
>>> p = canvas.Canvas('1.pdf')               # Init a PDF object
>>> p.drawString(200, 200, "Hello world.")   # Draw a simple String  
>>> p.showPage()                             # Create the PDF
>>> p.save()                                 # Clean UP the library usage
Enter fullscreen mode Exit fullscreen mode

Once all instructions are executed, we should see a new PDF file created in the root of our Django project. Let's open the file, without leaving the Django shell:

>>> import os,sys
>>> os.startfile('1.pdf', 'open')
Enter fullscreen mode Exit fullscreen mode

The startfile helper should open the PDF file using the default handler registered in the operating system.


Generate PDF in Django - Simple Hello World.


Create the new Django app

$ # Current Dir: ROOT of the Django project
$ python manage.py startapp pdf_app
Enter fullscreen mode Exit fullscreen mode

Code a simple PDF generator

# File contents: `app_pdf/views.py` (partial content)
...
from reportlab.pdfgen    import canvas
from reportlab.lib.utils import ImageReader
from datetime            import datetime
...

def pdf_dw(request):                                  

    # Create the HttpResponse object 
    response = HttpResponse(content_type='application/pdf') 

    # This line force a download
    response['Content-Disposition'] = 'attachment; filename="1.pdf"' 

    # READ Optional GET param
    get_param = request.GET.get('name', 'World')

    # Generate unique timestamp
    ts = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')

    p = canvas.Canvas(response)

    # Write content on the PDF 
    p.drawString(100, 500, "Hello " + get_param + " (Dynamic PDF) - " + ts ) 

    # Close the PDF object. 
    p.showPage() 
    p.save() 

    # Show the result to the user    
    return response
Enter fullscreen mode Exit fullscreen mode

This simple PDF generator will set a few properties to the HttpResponse object returned to the user, read an optional GET parameter and generate a timestamp saved in the PDF. Once the new PDF is saved in memory, we can return the contents to the user.

Sample Usage: http://localhost:8000/pdf_dw/?name=Bill Gates

Generate PDF in Django - Dynamic content with GET parameter.


Generate PDF with an Image

Using the same reportlab library we can generate PDF documents with embedded images without much effort - Let's see the code:

# File contents: `app_pdf/views.py` (partial content)
...
from reportlab.pdfgen    import canvas
from reportlab.lib.utils import ImageReader
from datetime            import datetime
...

def pdf_img(request):                                  

    # Create the HttpResponse object with the appropriate PDF headers. 
    response = HttpResponse(content_type='application/pdf') 

    # Create the PDF object, using the response object as its "file." 
    p = canvas.Canvas(response)     

    my_image = ImageReader('https://www.google.com/images/srpr/logo11w.png')

    p.drawImage(my_image, 10, 500, mask='auto')

    # Close the PDF object. 
    p.showPage() 
    p.save() 

    # Show the result to the user    
    return response
Enter fullscreen mode Exit fullscreen mode

my_image object is the Google logo, downloaded from a public address and used in our PDF via drawImage directive.

Sample output served by http://localhost:8000/pdf_img/

Generate PDF in Django - Dynamic content with Image Object.


Once we save the code, Django settings must be updated in order to activate the new app:

# Update Django Settings.py
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_pdf',
]
...
Enter fullscreen mode Exit fullscreen mode

Update Project Routing

urlpatterns = [
    path('admin/', admin.site.urls),
    path(""    , include("app_pdf.urls")),   # <-- NEW
]
Enter fullscreen mode Exit fullscreen mode

Thanks for Reading! For questions related Django and PDF generation process, feel free to AMA in the comments section.


✅ More Django Templates

The open-source samples presented in this section might help beginners (and not only) to code faster a new project in Django by reusing codebase and provided features.

👉 Black Dashboard Django

Black Dashboard Django features over 16 individual components, giving you the freedom of choosing and combining. This means that there are thousands of possible combinations. All components can take variations in color, that you can easily modify using SASS files. You will save a lot of time going from prototyping to full-functional code because all elements are implemented. We thought about everything, so this dashboard comes with 2 versions, Dark Mode and Light Mode.

Django Codebase is crafted using a simple, modular structure that follows the best practices and provides authentication, database configuration, and deployment scripts for Docker and Gunicorn/Nginx stack. Any developer with basic Django/Python knowledge, by following the product documentation should be able to compile and use the app by typing only a few lines in the terminal.

Django Admin Black - Template project for Django provided by AppSeed.


👉 Django Argon Dashboard

Argon Dashboard is built with over 100 individual components, giving you the freedom of choosing and combining. All components can take variations in color, that you can easily modify using SASS files. You will save a lot of time going from prototyping to full-functional code, because all elements are implemented. This Dashboard is coming with pre-built examples, so the development process is seamless, switching from our pages to the real website is very easy to be done.

Argon Dashboard 2 - Free Starter.


👉 Django Material Dashboard

Material Dashboard makes use of light, surface and movement. The general layout resembles sheets of paper following multiple different layers, so that the depth and order is obvious. The navigation stays mainly on the left sidebar and the content is on the right inside the main panel.

Material Dashboard - Full-Stack Starter generated by AppSeed.


✅ Resources

Top comments (4)

Collapse
 
uithemes profile image
ui-themes

Really nice! Thank you!

Collapse
 
sm0ke profile image
Sm0ke

Glad you like it! 🚀🚀

Collapse
 
ioeshu profile image
Eswar

very help full , thanks for sharing

Collapse
 
sm0ke profile image
Sm0ke

Ty! 🚀🚀