How do I convert a PDF bank statement to Excel?
First check your online banking for a CSV or Excel export; most banks have one. If you only have PDFs, extract the transaction table with a converter, then check that opening balance plus all transactions equals the closing balance. An agent can convert a whole folder of statements, check the totals and add categories.
How to do it
- Look for an export. In online banking, the transaction list usually has Export or Download as CSV, XLSX or OFX. This is cleaner than any PDF conversion.
- Convert the PDF. Use a converter or Excel's Get Data from PDF. Expect split rows, merged descriptions and dates in the wrong format.
- Clean the columns. One row per transaction: date, description, amount (negative for money out), balance.
- Check the balance. Opening balance plus the sum of all amounts must equal the closing balance. If it does not, a row was lost or split.
- Categorise. Add a category column (rent, software, travel) for your accountant or budget.
Your options
| Option | Effort | Catch |
|---|---|---|
| Bank CSV export | A few clicks | Not every bank, often short history |
| Online PDF converters | Upload each file | Your statements on someone else's server; rows break |
| Retype into Excel | Hours | Typos |
| TODO for AI | One message | You review the categories once |
Watch the agent do it
A real run on sample files. Yours starts from here.
I converted the statement to Excel. All three months add up exactly to their closing balances. I checked this in Python only: the cloud computer has no spreadsheet program, so the formulas in the file haven't been calculated yet. They'll fill in when you open it in Excel or Google Sheets.
File: ~/work/bank/statement_jul-sep_2026.xlsx (92 transactions, Jul to Sep 2026)
Transactions sheet: one row per transaction with Date, Description, Category, Amount and Balance. Withdrawals are negative and deposits positive. A "Balance check" column recalculates each row from the one before; any row that doesn't match turns red. It has a filter and the header row stays visible when you scroll.
Reconciliation sheet: for each month it shows the opening balance plus deposits minus withdrawals, compared with the closing balance on the statement:
| Month | Opening | Deposits | Withdrawals | Calculated closing | Statement closing |
|---|---|---|---|---|---|
| Jul | 4,210.37 | 3,851.12 | 4,575.23 | 3,486.26 | 3,486.26 ✓ |
| Aug | 3,486.26 | 3,851.12 | 3,996.14 | 3,341.24 | 3,341.24 ✓ |
| Sep | 3,341.24 | 3,851.12 | 4,294.03 | 2,898.33 | 2,898.33 ✓ |
Every row's running balance also matches the statement, and each month's closing balance equals the next month's opening balance.
Categories: I matched each description to a category by keyword (merchant name). Nothing was left uncategorised. Totals for the quarter:
| Category | Total |
|---|---|
| Income | +11,550.00 |
| Housing | −4,950.00 |
| Savings Transfer | −1,500.00 |
| Transport | −1,007.59 |
| Health & Pharmacy | −1,006.23 |
| Dining & Coffee | −904.44 |
| Groceries | −869.93 |
| Transfers (P2P) | −727.15 |
| Utilities | −706.24 |
| Fuel | −514.16 |
| Shopping | −333.19 |
| Cash Withdrawal | −300.00 |
| Subscriptions | −46.47 |
| Interest | +3.36 |
Worth knowing: the account was overdrawn from Aug 25 to Aug 28, going as low as −$320.62, until payroll arrived. That month the paycheck came on the 28th, while rent had already gone out on the 10th.
convert.py in the same folder rebuilds the file. To change how merchants are categorised, edit the CATEGORIES list at the top. It assumes this bank's PDF layout and the year 2026.