Excel (.xlsx) writer for bankstatementparser-parsed bank statements.
Project description
bankstatementparser-writer-xlsx: Excel writer for parsed bank statements
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 --strictclean.
Contents
- Overview
- Install
- Quick start
- Input shapes
- Value coercion
- The summary sheet
- Examples
- When not to use this package
- Development
- Security
- Documentation
- License
- Contributing
- Acknowledgements
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:
01_write_dataframe.py— write a pandasDataFrameto a single sheet.02_write_transactions.py— write a list ofTransactionobjects in stable field order.03_write_dicts.py— write a list of plaindictrecords (union of keys).04_write_with_summary.py— write a DataFrame plus a secondSummarysheet viasummary=.05_custom_sheet_name.py— rename the transactions sheet withsheet_name=.06_value_coercion_and_errors.py—Decimal/datecoercion,None/NaN/missing keys as blank cells, the 60-character column-width cap, and theTypeError/ValueErrorerror paths.
When not to use this package
- You need a custom sheet layout. The single-sheet (+ optional
Summary) structure is intentionally simple. Compose your own
openpyxlworkbook if you need pivot-ready, multi-sheet layouts. - You need
.xls(legacy binary).openpyxlwrites.xlsxonly; convert downstream if you must. - You need encrypted output. Out of scope; encrypt the produced
.xlsxdownstream with a tool likemsoffcrypto-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
README.md— this fileARCHITECTURE.md— module map and design decisionsCHANGELOG.md— release notesROADMAP.md— what's nextSECURITY.md— disclosure + supported versionsexamples/— runnable scripts, exercised in CI
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bankstatementparser_writer_xlsx-0.0.12.tar.gz.
File metadata
- Download URL: bankstatementparser_writer_xlsx-0.0.12.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
421d8789fe7eb349b857d583a009a8959d4117b8b2a7d546bcb759265e029919
|
|
| MD5 |
62db18b4ca0916615e7b38849cc3735c
|
|
| BLAKE2b-256 |
edca596c5f08f6989e57f20829b85e36785a5c42b8bd16d351fdbbb81e608382
|
Provenance
The following attestation bundles were made for bankstatementparser_writer_xlsx-0.0.12.tar.gz:
Publisher:
release.yml on sebastienrousseau/bankstatementparser-writer-xlsx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bankstatementparser_writer_xlsx-0.0.12.tar.gz -
Subject digest:
421d8789fe7eb349b857d583a009a8959d4117b8b2a7d546bcb759265e029919 - Sigstore transparency entry: 1953914952
- Sigstore integration time:
-
Permalink:
sebastienrousseau/bankstatementparser-writer-xlsx@922bc32a60e8923f19ee83f63ba002a40f4b7154 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@922bc32a60e8923f19ee83f63ba002a40f4b7154 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bankstatementparser_writer_xlsx-0.0.12-py3-none-any.whl.
File metadata
- Download URL: bankstatementparser_writer_xlsx-0.0.12-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f862d3d1570527f2c9c8cc6842bf542b6ad1467986a9b2f193b77a3c71167b37
|
|
| MD5 |
829ff1b4d1d684983e9a9ad4bea6ce92
|
|
| BLAKE2b-256 |
84827dde049c7d4961bd6f663b1326d4b9d1517633856fdd8f733c0fe241900f
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bankstatementparser_writer_xlsx-0.0.12-py3-none-any.whl -
Subject digest:
f862d3d1570527f2c9c8cc6842bf542b6ad1467986a9b2f193b77a3c71167b37 - Sigstore transparency entry: 1953915050
- Sigstore integration time:
-
Permalink:
sebastienrousseau/bankstatementparser-writer-xlsx@922bc32a60e8923f19ee83f63ba002a40f4b7154 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@922bc32a60e8923f19ee83f63ba002a40f4b7154 -
Trigger Event:
push
-
Statement type: