You ran the statement through a PDF to Excel converter and got a spreadsheet. Columns line up, dates run in order, the amounts look like amounts. Then you total the debits and the closing figure is out by a few hundred, and there is nothing in the file to tell you which rows are responsible.
This is a common outcome rather than bad luck. A generic converter and a bank statement converter are solving different problems, and the gap between them is not accuracy. It is meaning.
First, check what your bank will give you directly
Before any converter enters the picture, open online banking and look for a CSV, OFX or QBO download covering the period you need. If it exists and it carries the columns you want, it is the cleanest data you will get from that account, and no extraction step can improve on a file the bank generated itself.
It frequently is not there, or not there for the period that matters. Download windows are commonly capped at ninety days or eighteen months while the statement archive goes back years, so older periods exist only as statement documents. Raw exports often omit the running balance, which removes the one figure that lets you check the rows against the bank's own arithmetic. Descriptions arrive truncated to a fixed width, losing the reference you needed to code the transaction. And a closed account usually offers no export at all, only the statements already saved. Where any of that applies, you are converting statement documents, and the rest of this page is about how that goes wrong.
What a generic converter actually does
Table extraction is a geometry problem. The tool looks at a rendered page and searches for structure: ruling lines, boxes, or vertical bands of whitespace with text aligned on either side. It clusters characters into cells, decides where the row and column boundaries fall, and writes the resulting matrix out as a spreadsheet.
Nothing in that description involves money. The point is not that any particular tool is careless. It is that the category is not attempting the ledger problem at all: software built to find tables in contracts, reports and invoices has no reason to know which column is a balance, which is a date, or that the numbers are supposed to relate to each other. It has found a grid, and a grid is what it was asked for.
On a ruled single-page table that is enough. A bank statement is a ledger that happens to be laid out as a table, and the difference shows up immediately.
Where geometry loses the ledger
A wrapped description is not a new transaction
Long merchant names, payment references and standing order details wrap onto a second and sometimes third line. Geometrically that continuation is a new row: it sits below the previous one, in the description column, with the date and amount cells empty.
Extraction that works from layout alone emits it as a row. Your spreadsheet now has more rows than the statement has transactions, several of them with a description and nothing else, and any row count you take is meaningless. A statement-aware converter starts from the rule that a transaction must carry a date and an amount, so a bare description line belongs to the row above it.
A carried-forward subtotal is not a transaction
Multi-page statements print running subtotals, balance carried forward lines, and section totals. These have a number in the amount column and text beside them, which is exactly what a transaction looks like to a geometry engine.
Counted as transactions, they double part of the period. This is the failure that produces a spreadsheet whose total is too high rather than too low, and it is harder to spot because nothing is visibly missing.
A balance column is not just another number
The running balance is the most important column on the page and the one a generic tool treats as least special. It is simply the fourth column of numbers.
Some banks do not even put it there. Where the balance is printed in a side column, outside the transaction table, table detection either drops it entirely or produces a column of figures that never line up with the rows they belong to. Either way the one number that could verify the extraction has been discarded.
Direction is encoded, not written
Statements express whether money came in or went out in at least five incompatible ways: separate debit and credit columns, a single signed column, a trailing minus after the figure, parentheses around negatives, and DR or CR suffixes.
Layout analysis copies the characters and leaves the meaning to whatever type detection sits downstream. Some tools resolve a parenthesised negative or a trailing minus on their own; a suffix like CR is less often handled, so you can end up with a column mixing "1,234.56-" and "845.00 CR" as text, which will not sum. The harder case is not the formatting at all: if the statement changes convention between sections, the characters convert cleanly and part of your ledger is still sign-flipped. Fixing that by hand across a year of statements is most of the work the converter was supposed to save. Amounts arriving as unsummable text is one of the most common complaints after any conversion of a statement to CSV.
Page furniture becomes data
Statements contain material that is not a transaction: headers repeated on every page, interest rate disclosures, marketing inserts, and on some banks scanned cheque images interleaved with the transaction pages. Some of that is structurally table-shaped. It gets extracted.
Grouped sections destroy chronology
Some banks list deposits in one block and withdrawals in another rather than running strictly by date. A geometry engine reads them in the order they appear on the page. The output looks chronological within each block and is not chronological overall, which quietly breaks every running-balance calculation you build on top of it.
The test a generic converter cannot pass
Here is the decisive part. Suppose the statement opens at 4,182.55, with credits of 9,310.00 and debits of 7,846.20, closing at 5,646.35 as printed by the bank. A withdrawal of 412.80 was dropped during extraction.
The converter reports success. It found a grid, it wrote cells, the job completed. Some extraction tools do surface a confidence score for the characters they recognised, and that is worth having, but it answers a different question: how sure the tool is about what it read, not whether what it read adds up. Nothing in a layout pipeline holds an opening balance, a closing balance, or the requirement that one follows from the other. The missing 412.80 is fully present in the file and entirely absent from the report.
Be precise about what that reconciliation would prove, because anyone reviewing your work will be. A balance chain that lands is not a certificate of correctness. It says nothing about whether the dates parsed correctly or the descriptions are complete, and two errors that offset each other exactly will pass it unnoticed. What it does is catch the error class that costs the most on this document: a wrong digit in an amount changes a total, and a changed total breaks the arithmetic. It is the strongest automatic check a bank statement supports, and it is the one thing a grid of cells has no way to offer.
That is the whole argument. Not that generic extraction is careless, but that on this class of document it is not built to check itself.
Convert statements with the ledger understood
What statement-aware conversion does instead
A converter built only for bank statements can carry knowledge a general tool has no place to put.
The brief is narrower, so the assumptions can be stronger. Recognising the issuing layout is part of the job rather than something you configure per bank. The running balance is a named column, not the fourth column of numbers. The opening and closing figures are bounds on everything between them. Wrapped narration attaches to the transaction above rather than becoming a phantom row. DR, CR, trailing minus signs and parenthesised negatives are read as directions and normalised into one signed amount. Carried-forward lines, page furniture and cheque images are known shapes to exclude rather than table-like text to keep.
Then comes the thing layout analysis alone cannot do: verify the running balance line by line, and flag the rows that fail rather than returning a tidy file. Convert·Into reports extraction accuracy of 99.6%, and the balance check is what puts the remainder in front of you instead of leaving it in the sheet. A flagged row is a minute of review. An unflagged wrong row is found at the next reconciliation, if it is found at all.
If you are working with a generic tool anyway
The output is usable if you treat it as a draft and do the ledger work yourself.
- 1
Delete the phantom rows
Filter for rows with a description but no date or amount, and merge each one into the transaction above it before you count anything. - 2
Remove carried-forward and subtotal lines
Search for balance forward, subtotal and section total wording. Every one of these left in the sheet inflates the period. - 3
Normalise the sign convention
Convert trailing minus signs, parentheses and DR or CR suffixes into a single signed numeric column, and confirm the column sums rather than concatenates. - 4
Restore chronological order
Sort by date and check the sequence against the statement, particularly if the bank groups deposits and withdrawals separately. - 5
Reconcile before you use it
Add credits to the opening balance, subtract debits, and compare with the printed closing figure. Do not import anything until those two agree.
That sequence takes real time per statement, and it has to be repeated every month because the tool learns nothing between runs. Weighed against the alternatives, that recurring cost is the honest reason statement-specific extraction exists, and it is the same calculation behind what you actually get when you pay for a converter and behind the broader comparison of routes from a statement into a spreadsheet.
Frequently asked questions
Why can't I just use a normal PDF to Excel converter for bank statements?
Because it solves a geometry problem, not an accounting one. It finds columns of aligned text and writes them out as cells, with no concept of a running balance, a debit, or a transaction, so it cannot tell whether the rows it produced account for the whole period.
What does a generic converter get wrong on a bank statement?
Five things repeatedly: wrapped descriptions become phantom rows with no amount, carried-forward subtotals get counted as transactions, debit and credit column pairs are collapsed or mis-split, DR and CR suffixes arrive as text that will not sum, and page furniture between transaction pages is emitted as data.
How is a statement converter different from table extraction?
It knows what the columns mean. A statement-aware converter identifies the running balance, treats the opening and closing figures as bounds on everything between them, attaches wrapped description lines to the row above, and reconciles the result before it hands you a file.
Will a generic converter tell me if it missed transactions?
Not as a rule. Some tools report how confident they were about the characters they read, which is a different question. Completeness is a ledger question, and a pipeline with no opening or closing balance to check against has nothing to answer it with, so it reports success whenever it found a grid and wrote cells.
How do I check a spreadsheet produced by a generic converter?
Take the opening balance from the statement, add the credits, subtract the debits, and compare with the printed closing balance. If they differ, the gap is usually the exact value of a dropped or duplicated row, which tells you what to look for.