How to Extract Tables From a Scanned PDF to CSV With OCR

Extract a table from a scanned PDF to CSV with OCR. Keep rows and columns correct, check OCR errors, and validate the final file.

PdfParse Team

A scanned PDF doesn't contain a table. It contains a photograph of a table. OCR has to read the photograph first, and only then can extraction put each value back in its proper row and column.

This guide extracts a scanned invoice table to CSV with PdfParse — and, just as importantly, checks the result before you trust it.

What good output looks like

Say the scanned page contains this table:

DateInvoiceCustomerTotal
2026-06-03INV-00142Blue Mountain Foods1,284.50
2026-06-07INV-00147Harbour Office Supply297.00

The CSV has to carry the same two records:

date,invoice_number,customer,total
2026-06-03,INV-00142,Blue Mountain Foods,1284.50
2026-06-07,INV-00147,Harbour Office Supply,297.00

If OCR turns 00142 into OO142, the result still looks plausible at a glance — and it's wrong. Same story if a wrapped customer name splits into a brand-new row.

1. Confirm that the PDF is a scan

Open the PDF in a viewer and try to select a single word.

  • If the word highlights, the page probably contains digital text.
  • If the complete page selects as one slab, it's a scan.
  • If some pages contain text and others don't, the PDF is mixed.

This test changes how careful you need to be, not the procedure: PdfParse processes digital and scanned pages automatically. There's no OCR switch to flip.

2. Prepare the scan

Use the best source file you have — a clean scan prevents most OCR errors before they happen.

Before you upload:

  1. Put every page in the correct orientation.
  2. Remove blank pages.
  3. Make sure that no page edge hides a column.
  4. Check that small characters are readable at normal zoom.
  5. Unlock a protected PDF only if you have permission.

Don't upscale the image to manufacture extra pixels — that's just blur with confidence. If you can, rescan the original instead.

The characters that deserve a second look:

Printed valueCommon OCR error
0O
1I or l
5S
8B
decimal pointmissing character
minus signmissing character

3. Decide which fields you need

Write the required fields down before you convert anything:

FieldTypeValidation rule
datedateUse YYYY-MM-DD
invoice_numbertextKeep leading zeros
customertextKeep the complete name
totalnumberRemove the currency symbol

This list is your validation plan, not a mapping screen — the temporary converter doesn't have one.

PdfParse infers the schema from the first PDF, so make that first file count. It should show every important column and the repeating rows.

4. Upload the scanned PDF

Open the PDF to CSV converter. Then:

  1. Complete the security check if it appears.
  2. Select Open converter.
  3. Select Upload PDF in the empty workspace.
  4. Select the scanned PDF.
  5. Wait for the message Inferring the best CSV schema….
  6. Wait for the message CSV schema ready.
  7. Let the upload and extraction start automatically.

The temporary converter accepts a maximum of three PDFs and five pages in total, and the workspace expires after two hours.

No OCR toggle, no manual column-mapping step — the converter infers the structure from the first PDF and starts extraction on its own.

5. Review the extracted table

Open the Results tab once extraction completes, and work through it in order:

  1. Confirm that the required columns exist.
  2. Count the source records.
  3. Count the extracted rows.
  4. Select a row.
  5. Compare the row with the source PDF on the right.
  6. Repeat the check for the first, middle, and last row.

If PdfParse inferred related tables, inspect each dataset tab — parent data and repeating child data can land in separate datasets.

On a scanned page, always inspect codes, dates, negative values, and decimal points. These are exactly the values that can look reasonable while being quietly wrong.

6. Check difficult table structures

A scanned table is a picture of a table, and pictures don't come with data rules. A few structures to check by eye:

Wrapped text

One description across two printed lines is still one CSV field.

Repeated page headers

A header repeated on every page is not a data row, no matter how many times it shows up.

Merged cells

One customer name can apply to several rows. A flat CSV repeats the value in each applicable row; a relational output can instead store the customer once and link child rows to it.

Tables across pages

Check the last row on one page against the first row on the next — one source row should never split into two result rows.

7. Download and validate the CSV

Select Download CSV when the review is done.

  • One dataset downloads as one CSV file.
  • Related datasets download as a ZIP file that contains CSV files.

Open every downloaded file, then run the boring checks:

  • The header names are correct.
  • Every row has the same number of fields.
  • Leading zeros remain present.
  • Dates use one format.
  • Decimal points are present.
  • Negative signs are present.
  • The row count matches the source.
  • Totals match the source document.

This Python example checks the row count and the total:

import csv
from decimal import Decimal

with open("invoices.csv", newline="", encoding="utf-8") as file:
    rows = list(csv.DictReader(file))

assert len(rows) == 2
assert sum(Decimal(row["total"]) for row in rows) == Decimal("1581.50")

Use Decimal for money — binary floating point and financial totals don't mix.

When OCR needs human review

Review every result that comes from:

  • handwriting
  • faint carbon copies
  • low-resolution images
  • strong page shadows
  • rotated text
  • handwritten corrections
  • tables without clear columns
  • damaged pages

OCR saves you the typing. It doesn't save you the checking.

Use the PDF to CSV converter for a small test. Use JSON for nested data. Use SQLite for related tables and SQL queries. For automated processing, read the API documentation.