Fundor 333's personal space on the web

Letterhead With ReportLab

by Fundor 333

Reading time 3 minutes
Word count 481
2021-05-03 09:12:14

Sometime you need to make some pdf looking more professional. In python you use the ReportLab1 package for make Pdf.

Fist the main core

For every document type I need I write a class with a get_pdf for print2 a Pdf.

Here an example3

class BasicPrinter:
    def __init__(self, buffer, pagesize="A4"):
        self.buffer = buffer
        if pagesize == "A4":
            self.pagesize = A4
        elif pagesize == "Letter":
            self.pagesize = letter
            self.pagesize = A4
        self.width, self.height = self.pagesize

    def _header_footer(canvas, doc):
        BasicPrinter.header(canvas, doc)
        BasicPrinter.footer(canvas, doc)


    def header(canvas, doc):
        header = Image("letterhead_header.jpg", 600, 60)
            canvas, doc.leftMargin - 2 * cm, doc.height + doc.topMargin + 2 * cm

    def footer(canvas, doc):
        footer = Image("letterhead_footer.jpg", 600, 60)
        w, h = footer.wrap(doc.width, doc.bottomMargin)
        footer.drawOn(canvas, doc.leftMargin - 2 * cm, h - 2 * cm)

The real important things are the footer and header function (in our case staticmethod). In each one we add a img (the footer or header) with all the logos and company info in it. If you want you can put the info as text yourself. Remember to save and restore alwayse the canvas because sometime, if you don’t do it can launch error.

The specific printer (or how to use the main core)

After you have done you need to make a “printer” for your document. In this case is a booring paper about Privacy.

class PrivacyPaperPrinter(BasicPrinter):
    def _header_footer(canvas, doc):
        # Save the state of our canvas so we can draw on it 
        PrivacyPaperPrinter.header(canvas, doc)
        PrivacyPaperPrinter.footer(canvas, doc)

    def get_pdf(self):
        buffer = self.buffer
		styles = getSampleStyleSheet()
        doc = SimpleDocTemplate(buffer)

        elements = []
        elements.append(Paragraph("My boring Privacy Paper", style=styles["Title"]))
        elements.append(Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sed sem ornare, dictum sapien at, egestas sapien. Nullam faucibus eleifend finibus. Vivamus vel sapien urna.", style=styles["Normal"])), onFirstPage=self._header_footer, onLaterPages=self._header_footer)

        pdf = buffer.getvalue()
        return pdf

This class extend the previus one and fill the buffer with al the relevant info and other element of the document (like titles, paragraphs, tables and images).

For the way I set up this class you have all the page with the letterhead template. This is happening because I setup the onFirstPage which will be call on the first page and the onLaterPages which will be call from page two with the call for the header and the footer function.

  1. ReportLab is an opensource engine for Pdf documents. The python package is here  ↩︎

  2. I use print for the action of making a Pdf from some data (like a json, a csv or a datasource of other type) If one ore more of this Pdf’s types have a common layout (like a letterhead) I make an parent object for the type of document and call it SomethingPrinter↩︎

  3. My default paper is A4 but you can import any format from reportlab.lib.pagesizes or define a new one following this format A4 = (210mm,297mm) ↩︎

If you liked this article,

please share it on

or webmention it

Also on:

IndieWebCamp logo logo