Skip to main content

Excel (.xlsx) writer for bankstatementparser-parsed bank statements.

Project description

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.12 — 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.

Project details


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.12.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.12.tar.gz.

File metadata

File hashes

Hashes for bankstatementparser_writer_xlsx-0.0.12.tar.gz
Algorithm Hash digest
SHA256 421d8789fe7eb349b857d583a009a8959d4117b8b2a7d546bcb759265e029919
MD5 62db18b4ca0916615e7b38849cc3735c
BLAKE2b-256 edca596c5f08f6989e57f20829b85e36785a5c42b8bd16d351fdbbb81e608382

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_writer_xlsx-0.0.12.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.12-py3-none-any.whl.

File metadata

File hashes

Hashes for bankstatementparser_writer_xlsx-0.0.12-py3-none-any.whl
Algorithm Hash digest
SHA256 f862d3d1570527f2c9c8cc6842bf542b6ad1467986a9b2f193b77a3c71167b37
MD5 829ff1b4d1d684983e9a9ad4bea6ce92
BLAKE2b-256 84827dde049c7d4961bd6f663b1326d4b9d1517633856fdd8f733c0fe241900f

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_writer_xlsx-0.0.12-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 Pingdom Monitoring Sentry Error logging StatusPage Status page