Skip to content

marco-jardim/invoice-generator

Repository files navigation

Invoice PDF Generator

Generate polished, single-page PDF invoices from a JSON file with one command.
The project uses the rock-solid ReportLab toolkit — no third-party APIs, 100 % offline.


✨ Key Features (2025-06-23)

What you get
1-page guarantee – designed to fit neatly on A4 or US-Letter.
Professional layout – dark header band, crisp table grid, tidy typographic hierarchy.
Full banking block – combined SWIFT instructions with clear “FIELD 56A / 57A / 59 / 70” labels + optional settlement text.
Logo support – drop logo.png in the root and you’re branded.
Zero external services – perfect for CI/CD pipelines or air-gapped systems.
Easily hackable – tweak colours, fonts, margins, or even insert extra tables with a few lines of Python.
Outputs go to /invoices – keeps your repo root clean.

🛠 Prerequisites

Requirement Version Notes
Python 3.8 + Earlier 3.x should work, but 3.8 + is recommended
pip Latest For dependency install
ReportLab ≥ 4.0.5 Installed automatically via pip install -r requirements.txt

requirements.txt


reportlab>=4.0.5


🚀 Installation

git clone https://github.com/marco-jardim/invoice-pdf-generator.git
cd invoice-pdf-generator

# (optional) create + activate a virtual environment
python -m venv .venv
source .venv/bin/activate     # Windows: .venv\Scripts\activate

pip install -r requirements.txt

⚡ Quick Start

python invoice_generator.py          # uses example.json
# OR
python invoice_generator.py mydata.json custom_name.pdf

Output: a timestamped PDF inside invoices/ – e.g. invoices/invoice_20250623_141530.pdf.


📝 Preparing Your Invoice Data

All content lives in JSON (no code edits required).

Minimal schema

{
  "invoice_date": "July 4, 2025",
  "invoice_number": "20250704-042",
  "client":      { "name": "Client Inc.", "extra": "VAT GB123 456 789" },
  "contractor":  { "name": "My Company Ltd.", "extra": "United Kingdom" },
  "services":    [
    { "description": "Consulting", "amount": 3000.0 }
  ],
  "payment_terms": "Please pay within 15 days.",

  /* optional */
  "logo_path": "logo.png",
  "page_size": "letter",          // default = A4
  "wire_transfer": {  }          // full banking block (see below)
}

Banking / Wire-transfer block

"wire_transfer": {
  "owner_type": "Company",
  "legal_name": "My Company Ltd.",
  "cnpj": "38.659.441/0001-72",        // or VAT / EIN etc.

  "street": "123 Tech St.",
  "city": "London",
  "state": "ENG",
  "zip": "EC2A 4AA",
  "country": "United Kingdom",

  "bank": {
    "intermediary": {
      "name":   "THE BANK OF NEW YORK MELLON",
      "swift":  "IRVTUS3N",
      "routing": "021000018"
    },
    "final": {
      "name":   "BARCLAYS PLC",
      "swift":  "BARCGB22",
      "account_number": "12345678"
    },
    "beneficiary": {
      "name": "MY COMPANY LTD.",
      "iban": "GB12 BARC 2004 3002 3456 78"
    }
  },

  /* optional extra notice shown under the table */
  "settlement_text": "FX / CASH<br/>Bacen institution code 05218<br/>Location code 5885 (São Paulo)"
}

💡 The script produces a single, readable table:

FIELD 56A – Intermediary Bank: THE BANK OF NEW YORK MELLON
                               SWIFT IRVTUS3N
                               ABA   021000018

FIELD 57A – Final Bank:        BARCLAYS PLC
                               SWIFT BARCGB22
                               Acct# 12345678

FIELD 59 – Beneficiary / IBAN: MY COMPANY LTD.
                               IBAN GB12 BARC 2004 3002 3456 78

FIELD 70 – Reference (CNPJ):   38.659.441/0001-72

🎨 Branding & Styling

Task How-to
Add / change logo Place your PNG, set "logo_path": "mylogo.png".
Custom colours / fonts Edit build_styles() in invoice_generator.py.
Change margins or paper size Adjust the SimpleDocTemplate( … ) margins or put "page_size": "letter" in your JSON.
Add columns or extra tables Build more Table objects and append them to story.

📁 Repo Structure

invoice-pdf-generator/
├── invoices/               # generated PDFs (auto-created)
├── invoice_generator.py    # main script
├── example.json            # sample data file
├── requirements.txt
└── README.md               # you’re reading it

🔄 Updating Dependencies

pip install -U reportlab

🩺 Troubleshooting

Problem / Symptom Likely fix
ModuleNotFoundError: reportlab Run pip install -r requirements.txt inside the active venv.
Fonts too large, text overruns page Reduce fontSize & leading in build_styles() or shorten long descriptions.
Need multi-page invoices Remove the “one-page guarantee”: enable allowSplitting=1 on tables or add a PageBreak().
No PDF appears in invoices/ Check filename arg; ensure script has write permissions.

🪄 Advanced: Calling from other Python code

import json, invoice_generator
from pathlib import Path

data = json.loads(Path("my_invoice.json").read_text(encoding="utf-8"))
invoice_generator.generate_invoice(data, "invoices/embedded_call.pdf")

Use it in a Flask view, a serverless function, or your CI pipeline.


📜 License

GNUv3 © 2025 Tormenta Labs & contributors PRs / issues welcome — happy invoicing!

About

Another invoice generator, but this time without 3rd parties

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages