Converting a bank statement PDF to CSV is easy. Knowing whether the conversion is right is the part nobody talks about — and it’s the part that costs money.
This page describes a check you can run in about ten seconds, by hand, in Excel, on the output of any converter. You don’t need a tool for it and you don’t need this project. It’s just arithmetic that most people don’t know is available.
See the tool’s actual output — verified, silently-failing, and batch runs, copied verbatim from real runs: statementproof demo
A converter that crashes is harmless — you notice immediately and try something else.
The expensive failure is silent. A debit gets read as a credit. A decimal shifts. A page header lands in the data as a transaction. The CSV looks perfectly clean, imports without complaint, and reconciles to nothing three weeks later, in someone else’s books, with your name on the work.
The three most common silent failures, in order:
-, or parentheses for negatives may not
survive extraction. (42.50) becomes 42.50.None of these look like errors in the output. They look like data.
Almost every statement prints an opening balance and a closing balance. Many also print a running balance after each transaction. Those numbers are a checksum on your extraction, and they’re free.
opening balance + sum of all extracted amounts = closing balance
In Excel, with your amounts in column D:
=B1 + SUM(D:D) - B2
…where B1 is the opening balance and B2 the closing. If that doesn’t return
exactly zero, at least one row is wrong. Credits positive, debits negative.
This catches sign errors, decimal shifts, dropped rows, and duplicated rows. It will not
catch two errors that happen to cancel, or a junk row with a 0.00 amount.
Check 1 tells you that something is wrong. Check 2 tells you which row.
For every row, this must hold:
balance[n] = balance[n-1] + amount[n]
In Excel, with balances in column E and amounts in D, put this in F2 and fill down:
=ROUND(E2 - E1 - D2, 2)
Every cell should be zero. The first non-zero cell is your error. Not “somewhere in the file” — that row.
Seed the first row from the opening balance rather than from the row itself, or a broken first row silently becomes your baseline.
If you script this, compare in whole cents as integers. 0.1 + 0.2 != 0.3 in
floating point, and an accounting tool that raises false alarms on rounding noise gets
switched off within a week.
Does mean: the extracted transactions are arithmetically consistent with the statement’s own balances. Sign errors, misread digits, dropped rows and duplicated rows are ruled out.
Does not mean the conversion is correct. Errors that don’t disturb the arithmetic are invisible to it:
0.00 amountThe honest claim is “arithmetically consistent,” not “correct.” Treat any tool that claims more than that — including this one — with suspicion.
0.00 row. That’s a header or a total that got captured as a
transaction. It passes check 1 and breaks nothing arithmetically — which is exactly why
it survives.statementproof runs both checks on the output and names the failing row:
row 14 — running balance does not follow: 534.66 +37.07 should give 571.73,
statement shows 497.59 (off by -74.14)
It’s free, MIT licensed, and runs entirely on your machine — no networking library is imported anywhere in the package, and a test parses every module and fails the build if one ever is. Text-layer PDFs only; scans are detected and refused rather than guessed at.
But the check matters more than the tool. Run it with whatever you already use.
Other free, local options worth trying first: Excel’s built-in Data → Get Data → From PDF handles simple layouts and you already have it. Tabula is free and open source, though you draw the extraction regions yourself. Paid services like DocuClipper and QuickBankConvert are faster on a large pile, if uploading a client’s statement is acceptable for that engagement.