Convert a bank statement to CSV, free

Upload a bank statement PDF, scan or photo and download its transactions as a CSV: one row per transaction, one column per field, in UTF-8. It's built for importing into accounting software or a spreadsheet, and it works for any bank. It's free, with no account; the free try converts the first page.

Upload your bank statementTake a photo or pick a PDF, up to 10 MB
  • Free
  • No sign-up, no card
  • Download as Excel, CSV or JSON

A bank statement holds personal financial data. Upload your own, or one you may share. We keep the first page and the result for 7 days to run and improve this tool, then delete them. The rest of your file is not stored. Privacy policy

Sample. Every value is invented.

Northfield Bank

Savings statement

Client Name
Alex Sample
Account Number
0098 7654 3210
Statement Start Date
2026-10-01
Statement End Date
2026-10-31
Starting Balance
12,500.00
Ending Balance
12,941.32
DateDescriptionDebitCreditBalance
2026-10-01Transfer from current account500.0013,000.00
2026-10-14Standing order, insurance72.1812,927.82
2026-10-31Interest13.5012,941.32
{
  "client_name": "Alex Sample",  "account_number": "0098 7654 3210",  "statement_start_date": "2026-10-01",  "statement_end_date": "2026-10-31"}
  • Any layout, no template

    It works out the fields from the page itself, so there's nothing to set up.

  • Scans and phone photos

    Digital PDFs, scanned pages and photos all go through the same way.

  • Structured, not just text

    Named fields and table rows you can download as Excel, CSV or JSON, not a wall of OCR text.

  • An API when you need it

    The same data from your own code, as the sample call further down shows.

Two CSV downloads, for two jobs

Which CSV to choose from Download
DownloadWhat is in itUse it for
CSV: Transactions onlyA header row, then one row per transactionImporting into QuickBooks, Xero, Wave, Zoho Books or a database
CSVAccount fields as Field,Value rows, then each table under its nameKeeping a full record of the statement in one text file

Most imports reject anything above the header row, so choose the transactions-only file when the CSV is going into software. The file starts with a UTF-8 byte-order mark, so Excel opens Urdu, Arabic and accented descriptions correctly. Values that a spreadsheet could run as a formula are prefixed with an apostrophe, so a hostile description can't execute.

Import the CSV into accounting software

Each accounting package wants its own columns, so expect a short mapping step on import. The transactions file uses the column names printed on your statement.

  • QuickBooks Online accepts a three-column file (Date, Description, Amount) or a four-column one (Date, Description, Credit, Debit). Delete the Balance column and any extra columns before you upload.
  • Xero's statement import maps Date and Amount, plus optional Payee, Description and Reference. One signed Amount column is what it expects.
  • Wave, Zoho Books, Sage and FreshBooks have similar importers. Check the date format your software expects, and set it when it asks.
  • Google Sheets: File, Import, Upload, then choose comma as the separator.

Bank statement to text, CSV or JSON

If you searched for bank statement to text, a CSV is usually what you want: it is plain text that any program can open, with the structure kept. For code, download JSON instead, which keeps each field's name and each table's columns. Raw OCR text, by contrast, loses which number belongs to which column.

Common problems and fixes

  • Password-protected PDF: open it, print or save it without the password, then upload the copy.
  • Amounts with Dr and Cr: they're kept as printed. Add a column that makes Dr negative before importing.
  • Commas in amounts such as 2,400.00: they're quoted in the CSV, so the column stays intact. If your importer wants plain numbers, remove thousands separators with find and replace.
  • Only part of the statement came through: the free try reads page 1. A free account reads every page and joins them into one table.

Sample API call

This is how the same bank statement looks from your own code. wf_demo_bank_statement is a dummy workflow id and every value below is invented, so the call won't run as written. A real run reads every page and adds a confidence score and page position to each field.

Run a workflow, then read the result
curl -X POST "$DOCREFINERY_API/v1/workflows/wf_demo_bank_statement/run" \
  -H "Authorization: Bearer $DOCREFINERY_API_KEY" \
  -F "[email protected]"

# Take trace_id from the answer, then poll until status is "fulfilled"
curl "$DOCREFINERY_API/v1/runway/9f1c0a7e" \
  -H "Authorization: Bearer $DOCREFINERY_API_KEY"
Response (invented values)
{
  "trace_id": "9f1c0a7e",
  "status": "fulfilled",
  "document_type": "bank_statement",
  "result": {
    "fields": [
      {
        "key": "client_name",
        "alias": "Client Name",
        "text": "Alex Sample",
        "field_confidence": 0.99,
        "location": { "page": 1, "bbox": [0.08, 0.12, 0.46, 0.14] }
      },
      {
        "key": "account_number",
        "alias": "Account Number",
        "text": "0098 7654 3210",
        "field_confidence": 0.98,
        "location": { "page": 1, "bbox": [0.08, 0.17, 0.46, 0.19] }
      },
      {
        "key": "statement_start_date",
        "alias": "Statement Start Date",
        "text": "2026-10-01",
        "field_confidence": 0.97,
        "location": { "page": 1, "bbox": [0.08, 0.22, 0.46, 0.24] }
      },
      {
        "key": "transactions",
        "alias": "Transactions",
        "table": [
          [
            { "key": "date", "alias": "Date", "text": "2026-10-01" },
            { "key": "description", "alias": "Description", "text": "Transfer from current account" },
            { "key": "debit", "alias": "Debit", "text": "" },
            { "key": "credit", "alias": "Credit", "text": "500.00" },
            { "key": "balance", "alias": "Balance", "text": "13,000.00" }
          ]
        ]
      }
    ],
    "extraction_approval": "auto",
    "low_confidence_fields": []
  }
}

Make it run on your own bank statement

  1. Create a free account.
  2. Upload one sample under Workflows, keep the fields you want and save. That gives you a real workflow id.
  3. Create an API key under Settings. Keys are switched on per account, so ask us if you don't see the option.
  4. Set DOCREFINERY_API and DOCREFINERY_API_KEY as in the quickstart, and swap in your id.

Free try or free account?

Free try and free account, compared
FeatureFree tryFree account
Pages readPage 1Every page
Allowance5 tries a day100 pages a month
File sizeUp to 10 MBUp to 100 MB
How it readsFinds the fields on the pageBuilt-in bank statement fields, or your own workflow
CheckingCompare with your pageConfidence scores and page citations
OutputFields on screen, download as Excel, CSV or JSONExcel, CSV and JSON for every page, and API keys on request

Common questions

Is converting a bank statement to CSV free?

Yes. You get 5 free tries a day with no account and no card. Each converts the first page of one statement, and you can download CSV, Excel or JSON.

Can I import the CSV into QuickBooks or Xero?

Yes, after mapping the columns on import. Use the transactions-only CSV, keep Date, Description and Amount (or Credit and Debit for QuickBooks) and remove the rest. docRefinery isn't affiliated with Intuit or Xero.

Does it work for statements from Pakistani and Indian banks?

Yes. It reads any bank's layout, including statements from HBL, Meezan Bank, UBL, Allied Bank, Bank Alfalah, SBI and HDFC, and Urdu or Arabic descriptions stay intact in UTF-8.

How do I convert a multi-page statement to one CSV?

Create a free account. It reads every page, up to 100 pages a month, joins the transactions into one table and exports them as a single CSV or Excel file.

Is my statement kept?

We keep the first page and the result for 7 days to run and improve the tool, then delete them. The CSV is built in your browser from the result on screen.

Related

Try it on your own bank statement.

Free, with no sign-up and no card.