django reportlab

All posts tagged django reportlab

replogo

ReportLab is full of different objects that you can place anywhere around the screen.  Following our previous code, we are making a list of elements that we want to draw onto a document.  ReportLab will handle all of the page breaks and lining things up but we can manipulate that a bit to help ourselves get a really clean looking PDF.  You can review the last two guides in the series by clicking these links, ReportLab and Django – Part 1 – The Set Up and a Basic Example, ReportLab and Django – Part 2 – Headers and Footers with Page Numbers.

The two most common elements to get your document to look nice are Paragraphs and Tables.  Paragraphs are, just as they sound, a paragraph of text that can contain some formatting to make it look nice.  It can even include images.  You can set a ParagraphStyle for the entire paragraph or put XML tags inside the Paragraph to get various styles throughout one object.

Paragraphs

A Paragraph is an element that spans the entire width of the area that it is given.  It holds text or images and will wrap when it reaches the end of the drawable area.  You can set a style for a Paragraph by creating a ParagraphStyle and applying it to your Paragraph.  ReportLab comes with a number of built in styles but I found that I preferred creating my own styles to give me more control.

In the example you can see that we first register some fonts.  Fonts are a very important feature of ReportLab because it allows you to use any TrueType Fonts you can find.  This is important because if you are going to be using any foreign language characters you’ll need a font that supports those characters.  If you don’t ReportLab will render them as black squares.

We then got the large amount of style sheets already created for us by ReportLab and then we add to it.  You can see that we add a new ParagraphStyle called ‘RightAlign’ that will use the Arial font and right align any text inside of it.  Simple enough.  To use it we do just like we did in the example in Part 2 but instead of using a prebuilt stylesheet like Heading1 we just call our own RightAlign.  Below is the example with the changed line highlighted.

There are a lot you can do within a Paragraph as well using inline tags.  If you wanted to make changes to a certain section of text and wanted to change it to be a different color, font, or size you can by using the <font> tags.  Adding an image is equally as simple by adding the <img> tag and specifying a file location.  Below is an example of a Paragraph with the same style we created above but with altered font and image added inline.

This creates a right aligned paragraph that has a bold red My followed by a normal Arial User Names and then a image of a smiley face with a height of 5.

Tables

Tables are the biggest help ever for getting things all lined up.  A Table is exactly like every other instance of a table you know.  It has rows and columns and you can specify their size and what is inside of them.  Tables by default will grow to contain whatever object is inside of them.  You can explicitly set the widths and heights of the columns and rows but your text/images can still overflow onto the outside of them.  Getting the widths and heights right is key.  Let’s make a basic table with some user data and set some table styles to make it look great.

This will create a table with all of our users on it, their usernames, and when they last logged in.  The table will be lined, that’s what the INNERGRID and BOX style does.  You can see that the table will span the entire page and that each column will take up a third of the document’s width.  You can customize these for varying column widths.  There are a lot of various customization options for tables.  Read them on the ReportLab docs.

I hope this was helpful.  I spent a lot of time figuring these things out as the documentation and examples are sparse.  If there are any problems you have that you want to know about let me know in the comments below.

replogo

Last time we looked at how to generate a very simple PDF using ReportLab and Django, ReportLab and Django – Part 1 – The Set Up and a Basic Example.  This time let’s make the PDF a little bit more interesting with some headers and footers.  ReportLab gives a pretty good amount of control when it comes to adding headers and footers to your PDF.  To start off let’s bring back the simple __init__ method we had from last time and add a header/footer method to it.

Now we have a method that will draw things onto every page of our header and footer.  Next we need to actually call that method.  Remember last time where we built the document using doc.build(elements) and ReportLab built a PDF using the flowable elements in the list?  Well this time we are just going to add some more parameters to let the build process know that it needs to also draw out the header and footer on every page.  Below is our print_users method from last time with the new parameters added to the build command shown in bold.

That’s it. Now our print_users method will print out a few lines on both the header and the footer of every page. You’ll notice there are two parameters, onFirstPage and onLaterPages. This allows you to have different headers and footers on the front page, which could be a title page, and on later pages that would require page numbers. Speaking of page numbers let’s get into that.

Page numbers on every page was a big challenge for me to find anything on. It was easy enough to put Page X on every page but what I really wanted was Page X of Y and that “of Y” portion was tricky. Luckily, I’ve figured it out and I will present it here for you now.

You can alter the way that the PDF is built using the canvasmaker parameter in the doc.build() process. These canvasmakers can help you inject new things on every page without using a header or footer. Below is the code that I found somewhere online to print the Page X of Y on every page down near the footer. I have placed this all within the printing.py file I created last time.

To use this we just add a new parameter to our doc.build() command. You can see it added below in bold.

There you have it. Now you have a great header and footer on every page, or every page after the first, and page numbers on all of them. How fantastic is that? Next time we will go a bit deeper into Tables and how to use them to line everything up really nicely. They will be usable wherever you want a flowable including your new headers and footers.

It’s been far too long since my last post.  A lot has happened and the holidays make things so busy but I’m back and ready to get back in to the swing of things.  To start off the new year I’m going to do a series of posts relating to ReportLab specifically with its application to Django.  I want to go over a few of the pitfalls I’ve experienced and how to get things set up.  ReportLab is notoriously tricky to get working and the documentation seems sparse to say the least.  I hope these posts help not only myself remeber how I did all of this but others who are struggling with the same problems.

ReportLab

The problem is simple, how to generate PDFs using Django.  In our on going rewrite of our system at work we are getting to PDF generation.  The old system uses wkhtmltopdf which is great if you just want something to render HTML out to a PDF and you don’t give much care to speed or formatting.  Wkhtmltopdf suffers from having to use HTML to format everything on the page.  This is limiting because it is difficult to add headers and footers, positioning objects on the page is tricky, and we have a bad problem with it printing blank pages due to random overflow of the elements.  We needed a better solution and we have found it with ReportLab.  ReportLab has some HTML support, and we’ll get to that in a later segment, but for the most part you are drawing elements, text, images, etc. directly onto a canvas that is then rendered as a PDF.  The speed increase for us was unbelievable.  The formatting and control that we get is unmatched.  Most importantly, the font support has given us cleaner paperwork than we ever thought possible.  I guess what I’m trying to say is ReportLab is great…once you get it to work.  ReportLab Documentation is broad but not specific enough for a lot of our concerns.  You’ll find yourself heading to Google for even the smallest of questions.  I hope to alleviate many of the common pitfalls with this series.

Getting Set Up

Start by installing reportlab into your virtual environment with pip install reportlab. The first thing to do is get a robust class set up for doing all of your printing.  I created a printing.py file that houses all of my basic ReportLab set up and functions.  Branching off from there I have my individual pages and paperwork that get combined and output to the user.  Let’s start with a simple printing.py file.

As you can see my class is very simple. I pass in a buffer to house my data that will be returned to the user, I’ll show this once we get set up, and a page size. ReportLab has a lot of built in page sizes but you can even set your own if you’d like by using your own width and height variables.

Simple Example – Printing Users

Now let’s add a simple method to print out all of the users of our application into a PDF and return it to the browser.  Inside of the MyPrint class I’m adding a method that will print the list of users.

The code is commented nicely but let’s walk through it.  We start by taking our buffer and putting it into what is a SimpleDocTemplate.  This is a ReportLab object that will generate a PDF with some standard values.  There are a ton of customizations you can make and even create your own document templates but for now let’s stick with the simple.  We set the margins for the page and the page size.  You can use inches or millimeters too if you’d like, ReportLab has a few built in measurement sizes that just need to be imported.

Next we have a list of elements.  This list will hold all of the ReportLab Flowables that will be generated on the PDF itself.  A Flowable is an object that has space and size on a PDF.  This can be a block of text, a table, an image, or you can even create a custom Flowable.  Whatever we put in this list will be generated in order on our PDF.

After that you’ll see some styles that we use.  These styles are going to be used for various elements like Paragraph styling.  After we get the style sheets I’ve added a new one that simply centers text and nothing more.

Now we come to the part where we are going to add elements to our document to be rendered.  I’ve used Django to grab my list of users and I loop through them one at a time to add their name to a Paragraph flowable.  A Paragraph flowable will take up the entire width of the area you give it.  In our case we have not confied the Paragraph to the inside of a table or to a column so each Paragraph will fill in the entire width of the document.

Once we have added all of our elements we simply build the doc.  This renders the PDF and places all PDF data into that buffer we gave the doc when we initiated it.  Close the buffer for good practice and return the contents of the PDF to the user.  Simple enough.  To run all of the code that I have shown I have a view in my views.py file that will run all of this and you can see how to access the printing.py class and method and output your PDF to your users.

That’s all there is to it. I hope this was enlightening on at least how to get started. Next time I will explain how to add headers and footers to your documents as well as a surprisingly tricky to find way of adding page numbers.

If you have anything you’d like to learn about for ReportLab and Django please leave a comment below.

ReportLab and Django – Part 2 – Headers and Footers with Page Numbers