Generate polished PDF financial reports from hledger journals.
hport turns plain-text hledger accounting data into board-ready PDF financial statements — complete with professional formatting, multi-report merging, compression, and optional password protection — all from a single CLI command.
hledger is a powerful double-entry accounting tool, but its output lives in the terminal. When you need to share a balance sheet with stakeholders or archive quarterly financials, you're stuck copying tables into spreadsheets or manually building documents. There's no fast path from journal file to polished PDF.
hport bridges that gap. Point it at an hledger journal and it produces publication-quality PDF reports by:
- Extracting structured data from hledger via its JSON output
- Building Word templates dynamically with Foxit DocGen tag syntax
- Rendering PDFs through the Foxit Document Generation API
- Merging, compressing, and protecting the final output via Foxit PDF Services
| Report | Flag | Description |
|---|---|---|
| Balance Sheet | bs |
Assets, Liabilities, Equity with section totals and grand total |
| Income Statement | is |
Revenues and Expenses breakdown |
| Cash Flow Statement | cf |
Cash inflows and outflows |
| Budget vs Actual | budget |
5-column comparison: Account, Actual, Budget, Remaining, % Used |
hport is built on two Foxit cloud services:
- Receives a
.docxtemplate (built at runtime withpython-docx) containing DocGen tags like{{title}},{{TableStart:rows}}/{{TableEnd:rows}} - Merges the template with structured financial data
- Returns a rendered PDF
- Combine — merges multiple report PDFs into a single document with bookmarks
- Compress — reduces file size for easy sharing
- Protect — adds password encryption when requested
The async task workflow (submit → poll → download) is handled transparently so the user just gets a single output file.
hledger journal
│
▼
hledger.py ── runs hledger CLI, parses JSON → typed models
│
▼
templates.py ── generates .docx with Foxit DocGen tags
│
▼
docgen.py ── POST template + data → Foxit DocGen API → PDF
│
▼
pdfservices.py ── upload → combine → compress → protect
│
▼
report.pdf
Modules:
cli.py— Click-based CLI entry pointconfig.py— Loads credentials from.env, validates hledger is on$PATHmodels.py— Data classes (ReportRow,ReportSection,CompoundReport,BudgetReport)hledger.py— Subprocess runner + JSON parsertemplates.py— Dynamic.docxtemplate builderdocgen.py— Foxit Document Generation API clientpdfservices.py— Foxit PDF Services API clientreports.py— Orchestrator that ties everything together
- Python 3.12+
- hledger on your
$PATH - Foxit API credentials (sign up here)
# Clone and install
git clone https://github.com/<your-username>/hport.git
cd hport
uv sync
# Configure credentials
cp .env.example .env
# Edit .env with your Foxit API keys# Generate all four reports from a journal file
hport sample/sample.journal -o financials.pdf
# Balance sheet + income statement only
hport sample/sample.journal --reports bs,is -o statements.pdf
# Filter by date range
hport sample/sample.journal -b 2024-01-01 -e 2024-06-30 -o h1.pdf
# Password-protect the output
hport sample/sample.journal --password secret123 -o secure.pdf
# Pipe hledger JSON directly via stdin
hledger -f sample/sample.journal balancesheet -O json | hport --stdin bs -o bs.pdfSet these in your .env file:
FOXIT_DOCGEN_CLIENT_ID=your_docgen_client_id
FOXIT_DOCGEN_CLIENT_SECRET=your_docgen_client_secret
FOXIT_DOCGEN_HOST=https://na1.fusion.foxit.com
FOXIT_PDF_CLIENT_ID=your_pdf_client_id
FOXIT_PDF_CLIENT_SECRET=your_pdf_client_secret
FOXIT_PDF_HOST=https://na1.fusion.foxit.com
Optional branding:
HPORT_LOGO_PATH=/path/to/logo.png # Logo at top of each report
HPORT_COMPANY_NAME=Acme Corp # Shown if no logo provided
- Python 3.12 with type hints throughout
- Click — CLI framework
- python-docx — Programmatic Word document generation
- Requests — HTTP client for Foxit APIs
- Rich — Terminal UI with spinners and colored output
- uv — Fast Python package manager