Skip to main content

Command Palette

Search for a command to run...

PDF invoices with dynamic branding

Published
3 min readView as Markdown
L
I build and operate a fleet of 7 self-improving Python bots that trade crypto derivatives, scan freelance markets, and generate digital products automatically. Writing about trading bot architecture, web scraping, API integrations, and autonomous agents. All source code available at payhip.com/botfarm.

Creating PDF invoices that match your brand's look and feel can be a bit of a hassle, especially when juggling multiple clients or trying to present a professional image consistently. I recently dove into this problem space and found some neat ways to generate dynamic PDF invoices with customizable branding using Python. Here's how I tackled it and a few nuggets I picked up along the way.

Setting Up the Basics

First off, I wanted a simple way to generate PDFs without diving into too many dependencies. After some research, I settled on using the fpdf2 library. It's a lightweight library that handles the basics of PDF creation without a steep learning curve. If you're starting from scratch, you'll want to install it like this:

pip install fpdf2

Once you've got that sorted, setting up a basic PDF document is straightforward. Here's a snippet to generate a simple invoice layout:

from fpdf import FPDF

class PDFInvoice(FPDF):
    def header(self):
        # Company Logo
        self.image('logo.png', 10, 8, 33)
        self.set_font('Arial', 'B', 12)
        self.cell(0, 10, 'Invoice', 0, 1, 'C')

    def footer(self):
        self.set_y(-15)
        self.set_font('Arial', 'I', 8)
        self.cell(0, 10, f'Page {self.page_no()}', 0, 0, 'C')

pdf = PDFInvoice()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(40, 10, 'Hello World!')
pdf.output('invoice.pdf')

Dynamic Branding

The real trick here is dynamically inserting branding elements like logos and colors. You can easily swap out the logo or change the colors based on the client or specific branding guidelines. Here's how I managed that:

  1. Logos: Using the image method, you can dynamically insert different logos. Just pass the path to the client's logo at runtime.

  2. Colors: fpdf2 allows for setting colors using the set_text_color and set_fill_color methods. You can store your color schemes in a dictionary or JSON file and apply them as needed.

def add_branding(pdf, client_info):
    pdf.image(client_info['logo_path'], 10, 8, 33)
    pdf.set_text_color(*client_info['text_color'])

This approach means you can have a JSON like:

{
    "client_a": {
        "logo_path": "client_a_logo.png",
        "text_color": [0, 0, 0]
    },
    "client_b": {
        "logo_path": "client_b_logo.png",
        "text_color": [255, 0, 0]
    }
}

And then load and apply it at runtime, making your invoices look spot-on for each client.

Automating the Process

Beyond branding, I wanted to automate as much of the invoice generation process as I could — things like client details, invoice numbers, and payment terms. I found that maintaining a simple client database and using Python's string formatting capabilities lets you generate complete invoices with minimal effort.

For example, you can auto-fill client details like this:

client_info = {
    "name": "Client A",
    "address": "123 Business Rd.",
    "invoice_number": "0001"
}

invoice_text = f"""
Invoice Number: {client_info['invoice_number']}
Bill To: {client_info['name']}
Address: {client_info['address']}
"""
pdf.multi_cell(0, 10, invoice_text)

If you're looking to streamline this process or want a more out-of-the-box solution, I actually packaged this into a tool called Invoice Generator. It lets you create professional PDF invoices in seconds with customizable templates and a client database to auto-fill important details. You can check it out here.

Building a polished invoicing system with dynamic branding doesn't have to be daunting. With a few smart choices and some Python magic, you can make it look easy.

Also available on Payhip with instant PayPal checkout.


If you need a server to run your bots 24/7, I use DigitalOcean — $200 free credit for new accounts.

More from this blog

P

Python Bots & Automation

27 posts