larzpdf
Money-native PDF documents in pure Python. Zero dependencies.
A from-scratch PDF writer with one thing it's genuinely great at: financial
documents. Generating an invoice or a receipt — line items, exact decimal
totals, tax, clean right-aligned money columns — should be a few lines, not a
graphics project. No reportlab, no font files, no C extensions.
from larzpdf import Invoice
inv = Invoice("INV-1001", date="2026-07-27",
seller={"name": "Acme Co", "email": "billing@acme.com"},
buyer={"name": "Ada Lovelace"}, currency="$")
inv.item("Consulting", qty=10, price="150.00")
inv.item("Hosting", qty=1, price="29.99")
inv.tax(0.0825)
inv.save("invoice.pdf")
What makes it different
Most pure-Python PDF libraries are general drawing tools, and general drawing tools make invoices tedious. larzpdf inverts that: the invoice/receipt is the first-class feature.
- Money done right. Totals use exact
Decimalmath (no float cents drifting), formatting groups thousands and rounds HALF_UP, and money columns are right-aligned in a monospaced font so they line up perfectly. - Accepts real money objects. Pass plain numbers, strings, or
larzmoney
Moneyobjects — it formats and totals them correctly either way. - Zero dependencies. A complete, spec-valid PDF writer in a few hundred lines — correct cross-reference table and byte offsets, standard built-in fonts (no embedding). It opens in any reader.
Underneath there's a general Document (headings, wrapped text, tables, rules,
auto page breaks) and a low-level PDF canvas, but the money documents are the
point.
Install
pip install larzpdf
Invoices & receipts
from larzpdf import Invoice, Receipt
inv = Invoice("INV-42", date="2026-07-27",
seller={"name": "Acme", "address": "1 St", "email": "b@acme.com"},
buyer={"name": "Ada", "email": "ada@ex.com"},
currency="$", notes="Payment due in 30 days.")
inv.item("Design work", qty=8, price="120.00")
inv.item("Revisions", qty=2, price="90.00")
inv.tax(0.08, label="VAT")
inv.subtotal() # Decimal('1140.00') — exact
inv.tax_amount() # Decimal('91.20')
inv.total() # Decimal('1231.20')
inv.save("invoice.pdf")
receipt = Receipt("R-100", buyer={"name": "Bo"}, currency="$", paid=True)
receipt.item("Coffee", 2, "3.50")
receipt.save("receipt.pdf")
General documents
from larzpdf import Document
doc = Document()
doc.heading("Monthly Report")
doc.text("A paragraph that wraps automatically and paginates as needed. " * 10)
doc.hr()
doc.table(
[["Widgets", "1200", ("money", "9999.50")],
["Gadgets", "340", ("money", "1210.00")]],
headers=["Product", "Units", "Revenue"],
widths=[0.5, 0.25, 0.25],
align=["l", "r", "r"],
)
doc.save("report.pdf")
A cell written as ("money", value) is formatted and right-aligned in a
monospaced column automatically.
Low-level canvas
from larzpdf import PDF
p = PDF()
p.text(72, 720, "Hello", font="Helvetica-Bold", size=18)
p.line(72, 710, 540, 710)
p.rect(72, 600, 200, 80, fill=(0.95, 0.95, 0.95), stroke=(0, 0, 0))
p.add_page()
p.save("out.pdf")
Scope
larzpdf targets clean, text-and-table business documents (invoices, receipts, statements, reports) with the standard PDF fonts. It doesn't embed custom fonts or draw images — if you need rich graphics, that's a different tool. For getting correct, good-looking money documents out the door with zero dependencies, it's exactly enough.
Tests
python -m unittest discover -s tests -v # 20 tests incl. a PDF xref validator
The Larz stack
Pure-Python, zero-dependency building blocks: larz · larzchain · larzmoney · larzcrypt · larzdb · larzagent · larzchart · larzmark · larztask · larzvault · larzvm · larzcache · larzvalidate · larzid · larzrpc · larzstate · larzhttp · larzconf · larzcron · larzlimit · larzlog · larzcli · larzretry · larztime · larzpdf
License
MIT © larz-scripter
Metadata
Release files for larzpdf 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| larzpdf-0.1.0.tar.gz | 13.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| larzpdf-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.1 kB
Release files / larzpdf-0.1.0.tar.gz
| Download URL | larzpdf-0.1.0.tar.gz |
|---|---|
| Size | 13.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eaa9aa9b3d6cdd64b141731a4079517973262d2d96591c2e0f068f7b79d7d32e
|
|
BLAKE2b-256 checksum How to use checksums |
1561b98ad29f1e9dcb31cfcd79201868fb11d371f5750eef50ef2000dfb7a4aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / larzpdf-0.1.0-py3-none-any.whl
| Download URL | larzpdf-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ec46d005f600701ad59aefff61ca56aa37d2818aa464874d64dffd48039c35bb
|
|
BLAKE2b-256 checksum How to use checksums |
96a1ffdba10329a69f9a96803a2800972c30f09eee320c7e0a137673fd997c83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|