I want to generate a PDF which will show the output of my queryset in table format, for example:
query = ModelA.objects.filter(p_id=100)
class ModelA(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
p_id = models.IntegerField()
description = models.TextField()
I need to show the values for name
, description
and pid
in the generated PDF.
Generating a PDF file using DjangoDjango uses the ReportLab open-source PDF library to generate pdf files. This library needs to be installed using pip before using it. Django uses views to display the PDF files. Therefore, within your application, add the following code to your views.py file.
As mentioned by other people the best way to do this is to generate a template then convert the result, using one of the many libraries around, into a PDF. This method provides you with the usual amount of control over your templates, for example using tags.
I've used the previously mentioned ReportLab/Pisa setup but found it to be quite limiting, most layouts have to be built using tables and many parts of the CSS2 spec aren't implemented yet.
An easier to use library is wkhtmltopdf which is a headless distribution of WebKit. This has the benefit of rendering your templates like any webkit browser would and thus letting you use webkit specific extras, such as parts of the CSS3 spec that exist in WebKit.
Using the wrapper library django-wkhtmltopdf you can render_to_pdf
in your view instead of the usual Django render_to_response
.
Disclaimer: I am a contributor to this library.
This library has been converted to CBVs and most of the information below (which I'll leave to help add some context) is now implemented in the library itself for convenience.
See the quickstart docs for an example of how to implement the below code block. If you need to use more advanced usage you can subclass PDFTemplateView
and add various options like filename and the margins.
An example view:
from django.shortcuts import render_to_response
from wkhtmltopdf import render_to_pdf
def pdf(request):
context.update({'objects': ModelA.objects.filter(p_id=100)})
kwargs = {}
if request.GET and request.GET.get('as', '') == 'html':
render_to = render_to_response
else:
render_to = render_to_pdf
kwargs.update(dict(
filename='model-a.pdf',
margin_top=0,
margin_right=0,
margin_bottom=0,
margin_left=0))
return render_to('pdf.html', context, **kwargs)
The conditional statement here lets you pass ?as=html to the view so you can develop in the browser. It's a bit of an ugly way to do it currently but there are plans to fix this in a release soon.
Using this view you could loop the contents of objects
in your view as you would normally and even extend your base template. I've normally used a different stylesheet specifically for the PDFs for maintainability and readability of the styles as you need to do a few things differently for PDFs, such as setting a min-height if you want to keep your footer block in the same place.
On this note, you can create header and footer templates that will be used on each page of your PDF by passing them into render_to_pdf as part of kwargs
.
Just generate the HTML the way you would want it and ask xhtml2pdf to convert it into pdf.
Like one of the comment mentions, there is ReportLab, but that would need you to give specification in PDF's required format. It provides you more control, but if it is easier for you to generate HTML, the standard way which you need to generate anyway, you can use pisa to make it pdf.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With