Skip to main content

bankstatementparser-writer-xlsx: Excel writer for parsed bank statements

PyPI Version Python Versions License Coverage

An Excel .xlsx writer for data parsed by bankstatementparser — turn parsed transactions (a pandas DataFrame, a list of Transaction objects, or a list of plain dicts) into a polished workbook that accountants, auditors, and reconciliation macros can open directly.

Latest release: v0.0.13 — single write_xlsx(data, path, ...) function, 100% line + branch coverage, 100% docstring coverage, mypy --strict clean.

Contents

Overview

bankstatementparser-writer-xlsx is a small, focused companion to the bankstatementparser library. It does one thing well: given already-parsed bank-statement records, write a clean Excel workbook with a bold header row, one row per transaction, auto-sized columns, and an optional second Summary sheet.

The package consumes parsed data — it does not read PDFs, CSVs, or XML itself. Parsing (and the security surface that comes with untrusted input) lives upstream in the bankstatementparser core.

Install

bankstatementparser-writer-xlsx runs on macOS, Linux, and Windows and requires Python 3.10+. It pulls in bankstatementparser, openpyxl, and pandas automatically.

pip install bankstatementparser-writer-xlsx

Quick start

from bankstatementparser import CsvStatementParser
from bankstatementparser_writer_xlsx import write_xlsx

parser = CsvStatementParser("statement.csv")
df = parser.parse()                      # a pandas DataFrame
write_xlsx(df, "statement.xlsx")         # one polished workbook

That's an Excel workbook ready for your accountant. Add a summary sheet in one extra argument:

from bankstatementparser import CsvStatementParser
from bankstatementparser_writer_xlsx import write_xlsx

parser = CsvStatementParser("statement.csv")
df = parser.parse()
write_xlsx(df, "statement.xlsx", summary=parser.get_summary())

Input shapes

write_xlsx(data, path, *, sheet_name="Transactions", summary=None) accepts three input shapes and normalises each to a flat table:

Input Column order
pandas.DataFrame (from a parser's .parse()) the DataFrame's own column order
list[bankstatementparser.Transaction] the stable Transaction field order
list[dict] the union of keys, in first-seen order

A header row (bold) is written to the sheet_name sheet, followed by one row per record. Columns are auto-sized to their widest cell, capped at 60 characters so wide descriptions don't run off-screen (the cell content itself is never truncated — only the displayed column width).

Empty input is accepted: an empty list writes an empty sheet (no header), while an empty DataFrame that still carries column labels writes a header-only sheet.

Value coercion

Spreadsheet cells can't hold arbitrary Python objects, so the writer coerces the rich types the parser emits:

Python type Written as
decimal.Decimal float (Excel has no decimal type; floats aggregate natively)
datetime.date / datetime.datetime native Excel date cell (unchanged)
str, int, float, bool, None unchanged
None / float('nan') (e.g. a missing DataFrame cell) blank cell
anything else str(value)

bool is preserved as a true/false cell (it is not coerced to 0/1), and a missing list[dict] key writes a blank cell in the same way a None value does.

Errors

write_xlsx validates its data argument and fails fast with a precise exception rather than writing a malformed workbook:

Condition Raised
data is neither a DataFrame nor a list/tuple (e.g. a str or int) TypeError
data is a non-empty sequence whose items are neither dict records nor Transaction objects (e.g. [42]) ValueError
from bankstatementparser_writer_xlsx import write_xlsx

try:
    write_xlsx("not-a-table", "out.xlsx")  # a bare str is not a table
except TypeError as exc:
    print(f"rejected: {exc}")

try:
    write_xlsx([42], "out.xlsx")           # 42 is not a dict/Transaction
except ValueError as exc:
    print(f"rejected: {exc}")

The summary sheet

If you pass summary= a mapping (for example a parser's get_summary() result), the writer adds a second sheet titled Summary with a bold Key / Value header and one row per item:

from decimal import Decimal

from bankstatementparser_writer_xlsx import write_xlsx

transactions = [
    {"date": "2026-06-01", "description": "Salary", "amount": Decimal("3000.00")},
    {"date": "2026-06-03", "description": "Coffee Shop", "amount": Decimal("-4.20")},
]

write_xlsx(
    transactions,
    "out.xlsx",
    summary={
        "account_id": "DE89370400440532013000",
        "transaction_count": 128,
        "total_amount": Decimal("12045.67"),
        "currency": "EUR",
    },
)

Examples

Six runnable examples live in examples/ and are exercised in CI on every commit. Together they cover every supported input shape, option, coercion rule, and error path of write_xlsx:

When not to use this package

  • You need a custom sheet layout. The single-sheet (+ optional Summary) structure is intentionally simple. Compose your own openpyxl workbook if you need pivot-ready, multi-sheet layouts.
  • You need .xls (legacy binary). openpyxl writes .xlsx only; convert downstream if you must.
  • You need encrypted output. Out of scope; encrypt the produced .xlsx downstream with a tool like msoffcrypto-tool.
  • You want to read Excel. This package is a writer.

Development

git clone https://github.com/sebastienrousseau/bankstatementparser-writer-xlsx
cd bankstatementparser-writer-xlsx
poetry env use python3.12
poetry install
poetry run pytest        # 100% line + branch coverage gate
poetry run ruff check bankstatementparser_writer_xlsx tests
poetry run mypy bankstatementparser_writer_xlsx
poetry run interrogate -c pyproject.toml bankstatementparser_writer_xlsx

Security

bankstatementparser-writer-xlsx consumes already-parsed data, not raw statement files — the PDF/CSV/XML parsing surface lives upstream in the bankstatementparser core. Reporting practice, supported versions, and supply-chain posture are documented in SECURITY.md.

Documentation

License

Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.

Contributing

Contributions are welcome — open an issue or PR on the repository.

Acknowledgements

Built on the bankstatementparser library and openpyxl.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bankstatementparser_writer_xlsx-0.0.13.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file bankstatementparser_writer_xlsx-0.0.13.tar.gz.

File metadata

File hashes

Hashes for bankstatementparser_writer_xlsx-0.0.13.tar.gz
Algorithm Hash digest
SHA256 b1e517658bb06f52f76445d5af3f534e3bf431c46306c038a51bcdbddca7e7e1
MD5 205f71e1974890f19898a87bafede589
BLAKE2b-256 9765c1347752dc60d5282f573928a600f243f896999c5ced5dd787113d56f4b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_writer_xlsx-0.0.13.tar.gz:

Publisher: release.yml on sebastienrousseau/bankstatementparser-writer-xlsx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bankstatementparser_writer_xlsx-0.0.13-py3-none-any.whl.

File metadata

File hashes

Hashes for bankstatementparser_writer_xlsx-0.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 552b4750d33c014bf3b730bda9553410f745e320eb09dc1eef7e049225f7c44a
MD5 d9443f295d8a50b0c6abd3d1bafe9255
BLAKE2b-256 1fd598243f7f6bbb570112e0daa5aa1a8c97e5bda90372d4b1f25606a6eb97d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_writer_xlsx-0.0.13-py3-none-any.whl:

Publisher: release.yml on sebastienrousseau/bankstatementparser-writer-xlsx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page