Skip to main content

bankstatementparser-writer-xlsx logo

bankstatementparser-writer-xlsx

A polished Microsoft Excel (.xlsx) workbook export writer plugin for bankstatementparser transaction data.

PyPI version Python versions PyPI downloads Tests License

Latest release: v0.0.19 — 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

Ecosystem

bankstatementparser is part of a modular financial ecosystem. Optional companion packages provide specialized loaders, writers, AI agents, language servers, and transport protocol adapters:

Package GitHub Repository PyPI Role Description
bankstatementparser sebastienrousseau/bankstatementparser PyPI Core Engine Unified parser for CAMT (052/053), PAIN.001, CSV, OFX, QFX, MT940, and PDF statements
bankstatementparser-mcp sebastienrousseau/bankstatementparser-mcp PyPI AI Protocol Model Context Protocol (MCP) server exposing statement tools to LLMs & AI agents
bankstatementparser-lsp sebastienrousseau/bankstatementparser-lsp PyPI Developer Tooling Language Server Protocol (LSP) with live SWIFT MT940 statement validation & diagnostics
bankstatementparser-transport-ebics sebastienrousseau/bankstatementparser-transport-ebics PyPI Transport Automated bank statement retrieval over EBICS 3.0 (H005) and 2.5 (H004) protocols
bankstatementparser-writer-xlsx sebastienrousseau/bankstatementparser-writer-xlsx PyPI Output Writer Formats and exports parsed banking transactions into styled Microsoft Excel (.xlsx) workbooks
bankstatementparser-writer-qif sebastienrousseau/bankstatementparser-writer-qif PyPI Output Writer Serializes transactions into standard Quicken Interchange Format (.qif) exchange files
bankstatementparser-writer-ofx sebastienrousseau/bankstatementparser-writer-ofx PyPI Output Writer Serializes transactions into standard Open Financial Exchange (.ofx) XML/SGML files
bankstatementparser-writer-swift sebastienrousseau/bankstatementparser-writer-swift PyPI Output Writer Exports transactions to SWIFT MT940 customer statements and MT942 interim reports
bankstatementparser-loader-bai2 sebastienrousseau/bankstatementparser-loader-bai2 PyPI Input Loader Parses BAI2 cash-management and account balance statements
bankstatementparser-loader-mt942 sebastienrousseau/bankstatementparser-loader-mt942 PyPI Input Loader Parses SWIFT MT942 interim transaction reports with credit/debit summary reconciliation
bankstatementparser-loader-cfonb sebastienrousseau/bankstatementparser-loader-cfonb PyPI Input Loader Parses French CFONB 120 / AFB120 120-byte fixed-width banking statement files
bankstatementparser-loader-camt054 sebastienrousseau/bankstatementparser-loader-camt054 PyPI Input Loader Ingests ISO 20022 CAMT.054 real-time debit/credit notification stream XML
bankstatementparser-loader-sepa sebastienrousseau/bankstatementparser-loader-sepa PyPI Input Loader Ingests ISO 20022 SEPA PAIN.002 payment status reports and PAIN.008 direct debit mandates
bankstatementparser-loader-bacs sebastienrousseau/bankstatementparser-loader-bacs PyPI Input Loader Parses UK BACS Standard 18 / Faster Payments 106-byte fixed-width transmission files

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.

Metadata

Release files for bankstatementparser-writer-xlsx 0.0.19

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bankstatementparser-writer-xlsx 0.0.19
File Size Uploaded
bankstatementparser_writer_xlsx-0.0.19.tar.gz 19.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bankstatementparser-writer-xlsx 0.0.19
File Interpreter ABI Platform
bankstatementparser_writer_xlsx-0.0.19-py3-none-any.whl Python 3 none any Details

Total release size: 35.7 kB

Release files / bankstatementparser_writer_xlsx-0.0.19.tar.gz

Download URL bankstatementparser_writer_xlsx-0.0.19.tar.gz
Size 19.0 kB
Tags Source
SHA-256 checksum
How to use checksums
703ec0a477a1b18ec8f5e5c2603ea317add836d2fbb75553a6b4a86914c117f8
BLAKE2b-256 checksum
How to use checksums
b192de112653cd13cb918af0bc64a7d0c2438340b2261a88d08fa43abb2319af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / bankstatementparser_writer_xlsx-0.0.19-py3-none-any.whl

Download URL bankstatementparser_writer_xlsx-0.0.19-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
78e43d170237593ce35ba77fa85ca77bcbdf136f734ddadf3d038baee6e93f87
BLAKE2b-256 checksum
How to use checksums
c1c9a00e9836c914d6fad67c554e2d9e0048f6dab744b30e42d59ba6051a26c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.19 This release

2 release files

0.0.18

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page