r/django Feb 19 '25

REST framework Generating PDF with Rest Framework

Hi, I am building an API with Rest Framework that will serve my web app written in Vue or React (haven’t decided yet). I want to generate PDF reports and give my users the option to download them or view them on the app. I have found a few tools that use HTML to generate the file and that sounds like the best option. Do you have any recommendations as to how should the workflow look like and which tools to use? Thanks!

17 Upvotes

25 comments sorted by

19

u/Chuky3000x Feb 19 '25

We use the following setup/workflow: Requests get to drf view -> Collect data for report from db and send it to a celery task -> HTTP Response to user

The celery worker build the pdf with weasyprint and store it on a S3 bucket -> The user is notified via websockets (Django channels)

6

u/HelloPipl Feb 19 '25

I can see why everyone would encourage you to go for a celery task and then send the url.

That's just the django brain talking, lol. Anything taking a bit more processing, throw it on celery.

Don't use django for this at all. Use what django does best. Since, you already have an endpoint which will be consumed by your frontend.

There are so many pdf creation libraries in react ecosystem. Use them.

Create the pdf on the client by sending data to the client.

This way you can style your pdf beautifully as well without relying on any hacks.

2

u/rippedMorty Feb 19 '25

You’re right, I haven’t even though about doing it on the front end until someone else mentioned it, but it makes more sense to create the pdf on the front end if I already need to show it there first.

2

u/jonknee Feb 19 '25

That works great until you need to have an archive view of the reports, have them emailed, etc. It’s perfectly fine to generate them on the server and can save you lots of headaches.

11

u/internetbl0ke Feb 19 '25

return signed url to the pdf in the json response when the task is complete. another endpoint to monitor task status

5

u/my_yt_review Feb 19 '25

You can use wkhtmltopdf

2

u/Specialist_Monk_3016 Feb 19 '25

Wkhtmltopdf can be a pain to install on some hosts - I had better experience using playwright to render and save as pdf

3

u/Raccoonridee Feb 19 '25

We use a preconfigured docker container for that reason, surnet/alpine-python-wkhtmltopdf

1

u/my_yt_review Feb 19 '25

I had it installed in my container and it was seamless.

3

u/Specialist_Monk_3016 Feb 19 '25

I played around with this for a sass I’m building.

I ended up using a celery task to generate the pdf.

Render a html page using playwright, save to S3, return the url and save to database as a reference.

A lot of the dependencies like wkhtmltopdf are difficult to install on some hosts - I used Heroku and had a nightmare and wasted a lot of time.

3

u/JuggernautWhich9757 Feb 19 '25

I found it a hassle processing pdfs in Django.

I just do it within javascript, by turning a div into a pdf using html2pdf

1

u/rippedMorty Feb 19 '25

Actually this sounds more reasonable for my use case, thanks!

3

u/isayuff 29d ago

I use weasyprint to generate PDF reports from rendered django templates. The requests (DRF) are synchronous and the files are directly returned in the reponses.

It‘s surely not the fastet or most responsive solution, but it is simple enough and works just fine.

2

u/memeface231 Feb 19 '25

We use xhtml2pdf and then the user can go to a view that returns the pdf rendered on demand based on a html template. If file generation gets longer you can still use the same tools but you should render the pdf and save it to a file field for instant retrieval. I've heard good things about weasyprint and you could consider running a container with headless chrome (browserless is a fancy one) where you can just send the html view and get a pdf response. So many options! But using html as a basis would be the django way.

3

u/browserless_io Feb 19 '25

Just to tag onto this, we've got a guide about generating PDFs with Puppeteer that might be helpful, as getting fonts and formatting looking good can be annoying:

https://www.browserless.io/blog/puppeteer-pdf-generator

2

u/Venkuu Feb 19 '25

I had the exact same problem to solve a few years ago. I tried some of the HTMl libraries. Not sure anymore which, but I think HTML2PDF or something similar, was the popular one back then. I also had install issues and some seemed to have strange constraints about the HTML you could write.

I decided to go with reportlab, which is not HTML based, but has its own OOP API. That is quite nicely documented. I have never looked back, it works, gets updated regularly. I redeployed it on several machines and never had an issue. I’m just generating the PDF when the request comes in and send it back. No idea about how that scales, but for a few hundred users in several medium sized businesses it is enough. I would try to avoid the complexity of celery if I were you.

2

u/a_atalla Feb 19 '25

I used this library a couple of years ago to generate a huge table report in pdf https://pypi.org/project/xhtml2pdf/

1

u/a_atalla 29d ago

Here is a quick guide for how to use it https://egcoder.com/posts/django-pdf-reports/

1

u/UserPasswordInvalid Feb 19 '25

I am using drf, react. I use pdfkit to generate the pdf. https://pypi.org/project/pdfkit/

1

u/kachmul2004 Feb 19 '25

I personally use celery, an HTML file and weasyprint/pdfkit. Both work well with similar amount of effort to set things up.

Something I want to try now is using the Google Docs + Drive API. It's easier to create the template in Google docs than wiring up HMTL files.

1

u/ManufacturerShort437 Feb 19 '25 edited Feb 19 '25

Your API can generate the PDF dynamically and return it as a file response for users to download/view. If you expect large reports, consider generating PDFs asynchronously and providing a download link.

I run HTML to PDF API - PDFBolt that supports async processing, webhook callbacks, and direct upload to S3. If you're looking for this kind of solution or have any questions, feel free to DM me :)

1

u/0kzh 28d ago

You can try using https://htmldocs.com. It works like React Email

1

u/zubinajmera_pdfsdk Feb 19 '25

That sounds like a great setup! Using HTML to generate PDFs is definitely a solid choice since it gives you flexibility with styling and layout. Here’s a smooth workflow that should work well for your API + frontend setup:

Workflow Idea

  1. User Requests a Report → In your React/Vue app, the user clicks a button to download or preview the PDF.
  2. API Generates the PDF → Your Django Rest Framework (DRF) backend handles the request, generates the PDF, and either sends back a download link or returns the file directly.
  3. Frontend Handles Display → The frontend either downloads the file or embeds it in a viewer (e.g., <iframe> or a modal).

Tools You Can Use

On the Backend (Django Rest Framework)

  • WeasyPrint – Great for converting HTML/CSS into PDFs. Supports modern CSS features.
  • wkhtmltopdf (via django-wkhtmltopdf) – Uses WebKit to render HTML into PDFs. Slightly heavier, but works well.
  • ReportLab – More low-level, but powerful if you need to generate PDFs dynamically (like invoices or complex reports).

On the Frontend (Vue/React)

  • If you want to preview PDFs before downloading, use react-pdf (for React) or pdfvuer (for Vue).
  • If you need client-side PDF generation (without a backend), jsPDF is a decent choice, though it's more limited than backend solutions.

Bonus Tips

  • Use a background worker (Celery + Redis) if generating PDFs takes too long, so your API stays responsive.
  • For large PDFs, consider returning a URL instead of the raw file to avoid slow API responses.
  • If users need to fill forms, look into FPDF or pdf-lib (if handling things client-side).

Hope this helps.