tmaster
tmaster

Reputation: 9665

How to convert a html page to pdf in Django

I am using Django to create a report site. The reports are generated dynamically, they also include some SVG charts. I want to create a PDF file which is based on the current report the user is viewing, but with extra header and footer. I came across Phantomjs, two problems though, first is that the page requires user to log on, so if I send the url to the server, phantomjs creates the pdf for the logging page; second the reports are generated using ajax, so even the same url will have different reports. Is there any better way to do this?

Upvotes: 0

Views: 3047

Answers (3)

VikrantY
VikrantY

Reputation: 594

The problem in general is how to authenticate with your web-server. For both WKHTMLTOPDF and PHANTOMJS I did this by passing the authentication token to them and making them pass that back to the server in a cookie.

So for WKHTMLTOPDF this becomes:

wkhtmltopdf --cookie=LtpaToken2=<sometoken>  

This works in Java Webservers that pass an authentication token. I don't know django well enough, but it must use a similar cookie based mechanism for authentication. You will need to:

  1. Get the token serve side(Generally you can get this by referring to cookies or request-header)
  2. pass it to the tool, wkhtmltopdf or phantomjs
  3. When the tool requests any protected pages, it needs to pass the cookie back. Both have command line parameters for the same.

For AJAX, the best way is to put in a delay. Again, both have mechanisms to configure delays. In case of WKHTMLTOPDF you can specify it in command line paramters, phantomjs you can windows.setTimeOut. Give sufficient delay fo the Ajax to finish before rendering the page.

Upvotes: 1

tmaster
tmaster

Reputation: 9665

Okay, after whole lot googling, I couldn't find anything. So I came up with two hackish solutions.

  1. On the page which user is viewing, create a form with a hiding text area, the submit button is named 'Generate PDF', after rendering the page, I use JavaScript to get all the html within the divs I want and put them into the text area. When the button is clicked, the html will be passed to the server side, then I use python to create a html file locally and use Phantomjs to create a PDF according to the html file.

  2. Create a url render the exact same page user is viewing, but don't need to require user logging in. So one has to configure the Apache or Nginx so that url only can be accessed by the local host. So Phantomjs can access the url without any problem and generate the PDF.

Upvotes: 0

Krzysztof Rosiński
Krzysztof Rosiński

Reputation: 1478

Prince is a nice option (it should handle SVG), and it is free for non-commercial use. I was using pisa in one of my projects, but it does not handle SVG though.

Upvotes: 0

Related Questions