Checked PDF Table Extractor avatar

Checked PDF Table Extractor

Pricing

from $10.00 / 1,000 page processeds

Go to Apify Store
Checked PDF Table Extractor

Checked PDF Table Extractor

PDFs and scans to CSV/Excel tables plus a validation report that flags wrong totals, broken computed columns, unparsed numbers and low-confidence OCR, so you know which numbers to trust.

Pricing

from $10.00 / 1,000 page processeds

Rating

0.0

(0)

Developer

JYInnovation

JYInnovation

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Categories

Security

Limited permissions

Share

Checked PDF Table Extractor: PDF and Scan to CSV, Excel and JSON with Validation

Turn PDFs and scanned documents into clean CSV, Excel or JSON tables, plus a validation report that tells you which numbers to trust. Every table is checked: totals are re-added, computed columns are re-computed, numbers that failed to parse are flagged cell by cell, and low-confidence OCR is marked. You get a PASS / WARN / FAIL per table and a human-readable REPORT.html.

Who it is for

  • Finance and bookkeeping teams and developers turning invoices, bank and account statements and financial reports into spreadsheets or API data without silently importing a wrong total.
  • Analysts and researchers pulling price lists, government and statistical tables out of PDFs.
  • Automation builders who need a machine-readable pass/fail signal (checks.status) to route documents to review.

Works on invoices, statements, reports, price lists and government tables, as text PDFs or scans (PNG, JPG, TIFF).

Why the validation report matters

Extraction errors are silent. A misread digit in a scanned invoice, a dropped row at a page break or a total that never matched the line items all look like perfectly normal data in a spreadsheet. This Actor does the cross-checks a careful bookkeeper would, automatically, on every table:

CheckWhat it catchesResult
Totals cross-footRows labelled Total, Subtotal, Sum, Grand total (also Gesamt, Summe, Zwischensumme, Totale, Total general, Sous-total ...) are compared with the sum of the rows above, including Subtotal + Tax + Shipping = Total layouts.FAIL with expected vs found and the cell address
Computed columnsIf at least 80% of rows satisfy qty x unit price = amount, a + b = c, a - b = c, or Q1 + Q2 + Q3 + Q4 = Total, the rows that do not are flagged.FAIL with expected vs found per row
Numeric parse rateCells that look like numbers but cannot be parsed (1,23,4.5, 1O0.00 with a letter O, mixed separators). Reported per column with exact cell coordinates.WARN
OCR confidenceFor OCR'd pages every word keeps its Tesseract confidence; cells below 60 are flagged.WARN
StructureInconsistent column counts, empty or merged cells, empty rows and columns, header rows repeated mid-table (removed and reported).WARN / info
Page coveragePages where no table was found, pages skipped, pages not processed because of a limit.listed per file

A difference of a few units in the last digit (for example 0.01 on a 2-decimal invoice) is reported as a rounding warning instead of a failure.

PASS means every check that could run agreed. It does not prove the extraction is perfect - for example, a table with no totals and no computed columns can only be checked for number parsing. The report says exactly what was checked (totals_checked, computed_columns).

What you get

  • Dataset: one item per extracted table - file, table_index, pages, n_rows, n_cols, header, rows (numbers are real numbers; capped at 500 rows with a rows_truncated flag), links to the full files, and a checks summary with the status and every issue.
  • Key-value store (default store of the run):
    • <n>_<file>_table<k>.csv, .xlsx, .json for every table (the XLSX highlights flagged cells and has a Checks sheet)
    • REPORT.html - open it in a browser: one section per table, issues highlighted, data preview
    • REPORT.json - the same report, machine-readable
    • OUTPUT - run summary (files, tables, PASS/WARN/FAIL counts, pages processed, report links)
  • Files that fail (password-protected PDF, broken file, HTML page instead of a PDF, 404, over 50 MB) produce a clear error item and never stop the other files.

How to use

  1. Paste PDF or image URLs (PDF, PNG, JPG, TIFF) into PDF / image URLs, or upload one file.
  2. Leave OCR on Auto: pages with a text layer are read directly, scanned pages are OCR'd.
  3. Run it, then open REPORT.html in the key-value store, or fetch the dataset through the API.

Input

{
"files": ["https://example.com/invoice-2024-0042.pdf", "https://example.com/scanned-statement.pdf"],
"pages": "1-3,5",
"ocr": "auto",
"ocrLanguage": "eng",
"mergeMultiPageTables": true,
"outputFormats": ["csv", "xlsx"],
"numberLocale": "auto",
"maxPages": 200
}
FieldMeaning
filesURLs of PDFs / images. fileUpload lets you upload one file instead.
pagesOptional page selection such as 1-3,5 or 4-. Applies to every file.
ocrauto (OCR only pages with no text layer), always, never.
ocrLanguageInstalled: eng, deu, fra, spa. Combine with +, e.g. eng+deu.
mergeMultiPageTablesJoin a table continued on the next page (repeated header, or same column count and data-like first row).
outputFormatsAny of csv, xlsx, json.
numberLocaleauto, us (1,234.56) or eu (1.234,56). Negatives such as (1,234.00) and 45-, currency signs and % are understood. Percentages keep their face value (12% becomes 12).
maxPagesSafety cap on processed (billed) pages per run, default 200.

Output example (dataset item, shortened)

{
"item_type": "table",
"file": "invoice-2024-0042.pdf",
"table_index": 1,
"pages": [1],
"extraction_method": "lines",
"n_rows": 8,
"n_cols": 4,
"header": ["Item", "Qty", "Unit Price", "Amount"],
"rows": [["Widget A", 4, 12.5, 50], ["Widget B", 10, 3.2, 32]],
"rows_truncated": false,
"csv_url": "https://api.apify.com/v2/key-value-stores/.../records/01_invoice-2024-0042_table1.csv",
"xlsx_url": "https://api.apify.com/v2/key-value-stores/.../records/01_invoice-2024-0042_table1.xlsx",
"checks": {
"status": "FAIL",
"issue_counts": { "FAIL": 1, "WARN": 0, "INFO": 0 },
"issues": [{
"code": "TOTAL_MISMATCH",
"severity": "FAIL",
"message": "'Total' in column 'Amount' is 632.14 but the sum of the subtotals plus the rows after the last one is 623.14 (difference 9.00).",
"cell": "D9", "page": 1, "expected": "623.14", "found": "632.14", "difference": "9.00"
}],
"totals_checked": 2,
"totals_ok": 1,
"computed_columns": [{ "formula": "Qty x Unit Price = Amount", "rows_checked": 5, "rows_ok": 5, "match_rate": 1.0 }]
}
}

Cell addresses (D9) refer to the exported CSV/XLSX, where row 1 is the header.

Pricing

Pay per event. You are charged for pages processed, exactly one event per page:

EventWhenPrice
page-processeda page with a text layer (read directly)$0.01 / page
ocr-pagea page that had to be OCR'd (scans, photos and images; each image or TIFF frame counts as one page)$0.02 / page

Examples: a 20-page text report is about $0.20; 100 scanned pages are about $2.00. Tables, files, reports and validation are included - there is no per-table or per-check fee. A page that was processed is charged even if no table is found on it (use the Pages field to process only the pages you need). Pages that fail to process, are skipped (for example OCR set to never) or are never started are not charged. Set a maximum charge per run in the run options to cap your spend: when it is reached the Actor stops starting new pages, writes everything finished so far, lists the unprocessed pages in the report and says so in the status message.

Limitations

  • Handwriting is not supported; neither are very low-quality, skewed or rotated scans. Scan at 200 dpi or more, straight and upright, for good OCR.
  • Complex tables: deeply nested headers, heavily merged cells, tables with row spans or multi-line headers, and several tables side by side can come out with shifted columns. Merged and missing cells are reported. Newspaper-style multi-column text is not treated as a table.
  • Borderless tables are reconstructed from word positions. Very tight column spacing can merge columns - check the preview in REPORT.html.
  • Tables embedded as pictures inside a text PDF are not OCR'd unless you set ocr to always.
  • OCR languages installed: English, German, French, Spanish. No Asian-script or right-to-left support.
  • Validation needs something to validate against: totals need a row labelled Total/Subtotal/Sum (or equivalent), computed columns need at least 5 data rows and 80% agreement. A table without either is checked for number parsing and structure only.
  • Password-protected PDFs are rejected with a clear error. Limits: 50 MB per file, 200 pages per run by default.
  • Totals that include unparsed numbers are reported as unverifiable (WARN), never silently passed.

Privacy and data handling

Use it for public documents only. Each file is downloaded into the run's memory, processed transiently and not retained as a source copy; OCR runs inside the Actor and no content is sent to any third-party service. Extracted tables, reports and (if you used the upload field) the uploaded file live in your run's own dataset and key-value store under your Apify retention settings; delete the run to remove them. Links to private networks and localhost are refused.

Integrations

Use the Apify API, Make, Zapier, Google Sheets or webhooks. Typical pattern: run on a schedule or on new files, read the dataset, and alert (Slack/email) whenever checks.status is FAIL or WARN.

from apify_client import ApifyClient
run = ApifyClient("<APIFY_TOKEN>").actor("<owner>/checked-pdf-table-extractor").call(
run_input={"files": ["https://example.com/invoice.pdf"]})
for t in ApifyClient("<APIFY_TOKEN>").dataset(run["defaultDatasetId"]).iterate_items():
print(t["file"], t["checks"]["status"], t["checks"]["issues"])

FAQ

Does PASS mean the extraction is perfect? No. PASS means every check that could run agreed. A table with no total row and no computed columns can only be checked for number parsing and structure, and the report lists exactly what was checked.

Can it read scanned documents? Yes. With OCR on Auto, pages without a text layer are OCR'd (English, German, French, Spanish). Handwriting is not supported.

What do I get for a failed file? A clear error item in the dataset (password-protected, broken, not a PDF, 404, over 50 MB). Other files in the run are not affected.

European number formats? Yes. Use Number format eu for 1.234,56, or leave it on auto.

Where are the CSV and Excel files? In the run's key-value store, one file per table per selected format, with links in the dataset items and in REPORT.html.

Support

Found a document that extracts badly? Open an issue on the Actor page with the (public) link and what you expected. JYInnovation reads every report.

Built by JYInnovation.