Build a Simple Invoice Generator in Python
If you freelance or run a small business, generating invoices manually is a waste of time.
In this tutorial, I will show you how to build a clean invoice generator in Python — completely from scratch.
What We Are Building
- Read invoice data from a JSON file
- Calculate subtotals, VAT, and total
- Output a formatted text invoice
Step 1: Invoice Data Structure
Create invoice_data.json:
{
"invoice_number": "INV-2026-001",
"date": "2026-03-22",
"due_date": "2026-04-22",
"client": {"name": "Acme Corp", "email": "billing@acme.com"},
"freelancer": {"name": "Your Name", "email": "you@example.com"},
"items": [
{"description": "Web Development", "quantity": 20, "unit_price": 75},
{"description": "SEO Audit", "quantity": 1, "unit_price": 350}
],
"vat_rate": 0.20,
"currency": "EUR"
}
Step 2: The Generator Script
import json
def load_invoice(filepath):
with open(filepath) as f:
return json.load(f)
def calculate_totals(items, vat_rate):
subtotal = sum(item["quantity"] * item["unit_price"] for item in items)
vat = subtotal * vat_rate
return subtotal, vat, subtotal + vat
def format_invoice(data):
subtotal, vat, total = calculate_totals(data["items"], data["vat_rate"])
cur = data.get("currency", "EUR")
lines = [
"=" * 60,
f"INVOICE {data["invoice_number"]}",
f"Date: {data["date"]} | Due: {data["due_date"]}",
"=" * 60,
]
for item in data["items"]:
line_total = item["quantity"] * item["unit_price"]
lines.append(f"{item["description"]:<35} {item["quantity"]:>3} x {item["unit_price"]:>8.2f} = {line_total:>8.2f} {cur}")
lines += [
"-" * 60,
f"Subtotal: {subtotal:.2f} {cur}",
f"VAT ({data["vat_rate"]:.0%}): {vat:.2f} {cur}",
f"TOTAL: {total:.2f} {cur}",
"=" * 60,
]
return "\n".join(lines)
if __name__ == "__main__":
import sys
data = load_invoice(sys.argv[1] if len(sys.argv) > 1 else "invoice_data.json")
print(format_invoice(data))
Step 3: Run It
python invoice_generator.py invoice_data.json
The script outputs a clean, formatted invoice with automatic VAT calculation.
Extending the Script
-
PDF export with
reportlab -
Email sending with Python built-in
smtplib - Multi-currency support via a free exchange rate API
- Batch processing for multiple clients
Why Build Your Own?
- 100% private — no data sent anywhere
- Customizable to your country tax rules
- Works offline
- Zero subscription fees
Ready-Made Version
I packaged a polished version with FR/EU VAT, IBAN, multiple templates, and client management into Freelancer OS on Gumroad — complete toolkit for freelancers, EUR 19.
Building this? Drop questions in the comments.
Full freelance toolkit: guittet.gumroad.com
Top comments (0)