You might have faced various scenarios when you needed to convert an HTML document into a PDF file in Python using Django. In Django, you can implement this feature by using some libraries that we will discuss in this article.
In this article, you will learn to convert HTML pages to PDF using Django. You will see some examples so that you can understand the concept better.
Table of Contents
You can use the xhtml2pdf library in Django to convert an HTML document into a PDF file. Let us see how to use this library.
Firstly, you need to install the xhtml2pdf library using the pip command as shown below:
pip install xhtml2pdf
Once installed, you can use this library to convert an HTML document into a PDF file in Python. Let us discuss the further steps with the help of an example.
Firstly, you have to create a new python file inside your Django application. Suppose we have created with a name process.py
Inside this file, you will import the xhtml2pdf library and create a function that will convert an HTML document into a PDF file.
# importing the necessary libraries from io import BytesIO from django.http import HttpResponse from django.template.loader import get_template from xhtml2pdf import pisa # defining the function to convert an HTML file to a PDF file def html_to_pdf(template_src, context_dict=<>): template = get_template(template_src) html = template.render(context_dict) result = BytesIO() pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result) if not pdf.err: return HttpResponse(result.getvalue(), content_type='application/pdf') return None
Now we will import this process.py file into our views.py file. In the views.py file, we will create a class-based view. In the view class, we will define a function that will invoke the function in the process.py file.
In the views.py file, we will also specify the HTML template that we want to be converted into a PDF file. The views.py file will look like this:
# importing the necessary libraries from django.http import HttpResponse from django.views.generic import View from .process import html_to_pdf #Creating a class based view class GeneratePdf(View): def get(self, request, *args, **kwargs): # getting the template pdf = html_to_pdf('result.html') # rendering the template return HttpResponse(pdf, content_type='application/pdf')
For this demonstration purpose, I have created a sample HTML template that will be converted into a PDF file. The HTML template is:
Welcome to Python Guides This is a Sample HTML Content which is converted into a PDF file
Hope you have understood how to convert an HTML document into a PDF file
You can also generate dynamic contenet using this technique.
The last step is to define a URL endpoint where you want to view your PDF file in the url.py file. In my case, the urls.py file is:
from django.contrib import admin from django.urls import path #This will import our view that we have already created from .views import GeneratePdf urlpatterns = [ path('admin/', admin.site.urls), path('pdf/', GeneratePdf.as_view()), ]
In this urls.py file, I have defined a URL endpoint “pdf/”. When a request will be sent to this URL endpoint, the class-based view that we created in the views.py file will be called.
Now let us start the Django server and send a request to the /pdf/ endpoint.
You can see that the content inside the HTML template is rendered as a PDF file. In this way, you can convert an HTML document into a PDF file.
In the above example, we simply converted an HTML page into a PDF file using Python Django. We can also apply some CSS to the HTML template and convert this template into a PDF file in Python using Django.
The approach will be almost the same as explained in the above section. In my case, the process.py file will be:
# importing the necessary libraries from io import BytesIO from django.http import HttpResponse from django.template.loader import get_template from xhtml2pdf import pisa # defining the function to convert an HTML file to a PDF file def html_to_pdf(template_src, context_dict=<>): template = get_template(template_src) html = template.render(context_dict) result = BytesIO() pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result) if not pdf.err: return HttpResponse(result.getvalue(), content_type='application/pdf') return None
I will import this file into the views.py file. You can also write this code directly in the views.py file. But it is a good approach to write this code as a separate module.
Now the views.py file will look like this:
# importing the necessary libraries from django.http import HttpResponse from django.views.generic import View from .process import html_to_pdf #Creating a class based view class GeneratePdf(View): def get(self, request, *args, **kwargs): # getting the template pdf = html_to_pdf('result.html') # rendering the template return HttpResponse(pdf, content_type='application/pdf')
I have created an HTML template with some random text. I have also used some CSS properties for this demonstration. This HTML template is saved with the name results.html:
Welcome to Python Guides Dear Customer,
This is to inform you that your plan is expiring soon. Kindly, pay your monthly premium before expiration.
Thank You
Python Guides
Now let us map the URL endpoint with a function created in the view.py file. This will be done in the urls.py file which is:
from django.contrib import admin from django.urls import path #This will import our view that we have already created from .views import GeneratePdf urlpatterns = [ path('admin/', admin.site.urls), path('pdf/', GeneratePdf.as_view()), ]
Save all the above files and start your Django server. Let us see the output:
You can see that the content in the PDF file is written as it was in the HTML file i.e. our CSS reflected in the PDF file.
In this way, you can convert an HTML file with CSS to a PDF file in Django.
In real-life scenarios, you may need to display dynamic data to your users using a PDF file. For example, retrieving some data from the database and rendering it inside an HTML template, and converting it into a PDF file.
Some common use cases are generating documents like invoices for an e-commerce site, applications data, forms, resumes, etc.
In this section, I will demonstrate how you can retrieve data from your database and render it in your HTML template. Then I will convert this HTML template into a PDF document.
In Django, you have models that you can work with. I have created my models.py file as:
from django.db import models class Employees(models.Model): emp_id = models.AutoField first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) department= models.CharField(max_length=20)
The above model is equivalent to a table. I am using an SQLite database. Therefore I populated this table with some data using SQLite Studio. Now the table becomes:
You can see in the above image that the records stored in the database are rendered inside a PDF document.
Hence, in this way, you can dynamically generate HTML content and convert it into a PDF file using the xhtml2pdf library.
Generating a PDF invoice is one of the most common applications where we need to convert an HTML document into a PDF document using Django.
In this section, I will demonstrate how you can implement this functionality in your Django application.
# importing the necessary libraries from io import BytesIO from django.http import HttpResponse from django.template.loader import get_template from xhtml2pdf import pisa # defining the function to convert an HTML file to a PDF file def html_to_pdf(template_src, context_dict=<>): template = get_template(template_src) html = template.render(context_dict) result = BytesIO() pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result) if not pdf.err: return HttpResponse(result.getvalue(), content_type='application/pdf') return None
# importing the necessary libraries from django.http import HttpResponse from django.views.generic import View from app1 import models from .process import html_to_pdf from django.template.loader import render_to_string #Creating a class based view class GeneratePdf(View): def get(self, request, *args, **kwargs): data = models.invoices.objects.get(id= 1434) open('templates/temp.html', "w").write(render_to_string('result.html', )) # Converting the HTML template into a PDF file pdf = html_to_pdf('temp.html') # rendering the template return HttpResponse(pdf, content_type='application/pdf')
In the above code, you can see that I am loading the invoice data from a database using a Django model. Let me show you the models.py file where you can see the structure of my database:
from django.db import models from django.db.models.base import Model class invoices(models.Model): name = models.CharField(max_length= 20) address = models.CharField(max_length = 100) pay_method = models.CharField(max_length = 15) amount = models.FloatField(max_length=10) description = models.CharField(max_length=50) order_date = models.DateField()
I have already populated this table with some sample records using SQLite studio, as I am using an SQLite database. The table looks like shown in the below image:
Also, in the views.py file, you can see that I am passing the data to a Django template named results.html. The contents of this template are:
Untitled Document Invoice Receipt Invoice Number: > Service Provider Mahesh Traders 1001A, The Capital B Wing, 10th Floor, Bandra Kurla Complex, Bandra (E), Mumbai, Contact: 7863087385
Order Date :> Customer Name > >
Description Bill Amount Payment Method > > >
Please Note: Dear Consumer, the bill payment will reflect in next 48 hours in your account. Please contact our customer support for any queries regarding this order. Thank you for using our service (This is computer generated receipt and does not require physical signature.)
Now the final step is to map a URL endpoint with our code i.e. creating a path in the urls.py file. In my case, the urls.py file will be:
from django.contrib import admin from django.urls import path #This will import our view that we have already created from .views import GeneratePdf urlpatterns = [ path('admin/', admin.site.urls), path('pdf/', GeneratePdf.as_view()), ]
Once you have followed all the above steps, you can send a request to the URL endpoint that you defined in the urls.py file.
http://localhost:8000/pdf/
You can see that the values from the database are loaded in this PDF invoice. You can also customize your Django template by adding some styling using supported CSS( All CSS are not supported).
Thus, you might have got a basic idea of how you can generate a PDF invoice in Django.
Related Python Django tutorials:
Hence, using the above ways, you can convert an HTML document into a PDF document using Django in Python.
I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.