How to Generate PDF Invoice in Python
As in modern era where the Conventional Payment systems have been checked out completely, we need the dynamic solution to generate the instant invoices and as invoice are best suited in PDF formats, because of some special features that make PDF Stand apart from the other formats like Doc, Xls, etc.
So, In this tutorial, we will learn how to generate simple PDF Invoice using Python. As we know Python supports many libraries that can be used to handle the PDF files, But to make PDFs such as Invoice, Official Documents or Reports one library that is highly recommended is the ReportLab Library.
The ReportLab library is able to directly create PDF file based on your graphics commands. There are no intervening steps available. Your applications can generate reports at extremely fast. Even sometimes faster than traditional tools.
The ReportLab library differs for others in that it can work at much higher levels and full of features for laying out documents that completely using tables as well as using charts.
Some of the exciting features of using ReportLab Library are:
- Generates Dynamic PDFs on the web.
- Generates High-volume Corporate Reports.
- An Ecosystem that supports user customization to the Reports.
- One-Step Conversion of XML to PDF.
Basics of Using ReportLab Library
- Unlike the GUI component designing the cartesian coordinate system of ReportLab starts from ‘Bottom-Left’ as the origin instead of ‘Top-left’.
- The interface object which provides the painting operations in the PDF generation is known as ‘Canvas’.
- The ‘showPage()’ method of the module causes the ‘Canvas’ to stop drawing on the current page. Any further operations will draw on a subsequent page when there are any further operations that exists, otherwise, no new page is created.
- The ‘save()’ method stores the file and closes the canvas.
- The ‘translate()’ method is used for translating the origin at the required coordinates specified.
- The ‘scale()’ method is used for stretches or shrinks the x and y dimensions by the dx, dy factors respectively and it can also be used for getting the mirror image of what is drawn on the Canvas.
- The ‘line()’ method is used to draw straight line segments on the Canvas.
- The ‘drawstring’ method is used to draw a single line of text on the Canvas.
- The ‘drawImage()’ method is used to draw an image on the Canvas.
To learn more about ReportLab Library you can refer to the Documentation available.
Getting Started With the Code
First of all, go through the Source Code then afterward I will explain to you some tricky things why I have done them like that.
pip3 install reportlab
# Importing Required Module from reportlab.pdfgen import canvas # Creating Canvas c = canvas.Canvas("invoice.pdf",pagesize=(200,250),bottomup=0) # Logo Section # Setting th origin to (10,40) c.translate(10,40) # Inverting the scale for getting mirror Image of logo c.scale(1,-1) # Inserting Logo into the Canvas at required position c.drawImage("logo.jpg",0,0,width=50,height=30) # Title Section # Again Inverting Scale For strings insertion c.scale(1,-1) # Again Setting the origin back to (0,0) of top-left c.translate(-10,-40) # Setting the font for Name title of company c.setFont("Helvetica-Bold",10) # Inserting the name of the company c.drawCentredString(125,20,"XYZ PRIVATE LIMITED") # For under lining the title c.line(70,22,180,22) # Changing the font size for Specifying Address c.setFont("Helvetica-Bold",5) c.drawCentredString(125,30,"Block No. 101, Triveni Apartments, Pitam Pura,") c.drawCentredString(125,35,"New Delhi - 110034, India") # Changing the font size for Specifying GST Number of firm c.setFont("Helvetica-Bold",6) c.drawCentredString(125,42,"GSTIN : 07AABCS1429B1Z") # Line Seprating the page header from the body c.line(5,45,195,45) # Document Information # Changing the font for Document title c.setFont("Courier-Bold",8) c.drawCentredString(100,55,"TAX-INVOICE") # This Block Consist of Costumer Details c.roundRect(15,63,170,40,10,stroke=1,fill=0) c.setFont("Times-Bold",5) c.drawRightString(70,70,"INVOICE No. :") c.drawRightString(70,80,"DATE :") c.drawRightString(70,90,"CUSTOMER NAME :") c.drawRightString(70,100,"PHONE No. :") # This Block Consist of Item Description c.roundRect(15,108,170,130,10,stroke=1,fill=0) c.line(15,120,185,120) c.drawCentredString(25,118,"SR No.") c.drawCentredString(75,118,"GOODS DESCRIPTION") c.drawCentredString(125,118,"RATE") c.drawCentredString(148,118,"QTY") c.drawCentredString(173,118,"TOTAL") # Drawing table for Item Description c.line(15,210,185,210) c.line(35,108,35,220) c.line(115,108,115,220) c.line(135,108,135,220) c.line(160,108,160,220) # Declaration and Signature c.line(15,220,185,220) c.line(100,220,100,238) c.drawString(20,225,"We declare that above mentioned") c.drawString(20,230,"information is true.") c.drawString(20,235,"(This is system generated invoive)") c.drawRightString(180,235,"Authorised Signatory") # End the Page and Start with new c.showPage() # Saving the PDF c.save()output
- First of all, while initializing the canvas there is a parameter ‘bottomup’ it is by default set to ‘1’ but I had set it to ‘0’ because if it would be ‘1’ then origin would be at ‘bottom-left’, to start the document from ‘top-left’ we have to set it to ‘0’.
- By doing this there was one problem that occurred, that is when I had drawn image on the canvas it appearing as vertical mirror image by taking the upper edge as an axis, and this was happening due to changes in the ‘bottomup’. So to correct this error first I had reset the origin and for getting the mirror image of appearing mirror image i.e the actual image, I had inverted the scale vertically.
- By doing this my logo image was corrected but the new problem had emerged, that is when I started drawing strings into the canvas now the strings were started to appearing as vertical mirror images and their geometric origin was also not as it was required. So to Correct these errors I had to again reset the origin and again Invert the scale to get the original scale as before.
- Item Description Section I have to use a bunch of lines to draw the table instead of using ‘table()’ method already available, because the ‘table()’ method needs a ‘data’ parameter that needs to be passed an accordingly it gains its alignment and geometry.
The output of the program will generate a PDF file that will look like you can see like this.
So, In this way we can generate simple PDF invoice using ReportLab Library in Python. I hope this tutorial would be useful to you, thank you ‘Keep Learning Keep Coding’.
NOTE: Name, Address, other credentials are just used as an example, they are not related to any person or organization, So don’t try to get messy with it. Thank you !!