PDF Table Extractor
Pricing
from $10.00 / 1,000 page processeds
PDF Table Extractor
Extract every table from PDF invoices, purchase orders, price lists and bank statements into clean JSON with real column names. Reads ruled and whitespace-aligned tables, flags scanned files, and never fails a whole batch because one file was unreachable.
Pricing
from $10.00 / 1,000 page processeds
Rating
0.0
(0)
Developer
Alexandre Leclerc
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Categories
Share
Turn the tables trapped inside your PDFs into clean, structured JSON — one row per table row, ready for a spreadsheet, a database, or an AI agent.
Invoices, purchase orders, delivery notes, price lists, bank statements and reports all carry their most valuable data in tables. Copying that out by hand is slow, and most extraction tools hand back either a wall of text or a grid of anonymous cells. This Actor gives you named columns you can use immediately.
What does PDF Table Extractor do?
Give it one or more links to PDF files. It reads every page, finds the tables, uses the first row as column names, and returns one dataset item per table row. Export the result as JSON, CSV, Excel or XML in one click, or pull it through the Apify API.
It handles both kinds of table found in real documents:
- Ruled tables, where the cells are drawn with visible lines.
- Whitespace-aligned tables, where columns are only held together by spacing —
the layout produced by ERP exports and bank statements, which most extractors miss
entirely. Columns are recovered from the horizontal positions that repeat across
lines, so a heading like
Unit pricestays in a single cell instead of splitting in two.
Why use this PDF table extractor?
It refuses to hand you garbage. Chart figures and heat-maps are drawn with real
ruled cells, so naive extractors report them as tables and fill your dataset with
rows like column_1: "tI". This Actor only keeps a table when its first row can
genuinely name the columns. On a 15-page research paper, that cut the noise from 47
rows to 2.
It never loses a column. When a PDF repeats a header or leaves one blank — routine
in invoices — a naive conversion to JSON silently overwrites data. Blank headers become
column_2, repeats become Ref_2, and every column survives.
It tells you when a PDF is a scan. Image-only documents come back with a clear
no_text_layer status instead of an empty result you have to debug.
One bad file never kills the batch. An unreachable URL is reported as a row with a
download_failed status, so a 500-document run always finishes and you can see exactly
which files need attention.
What data can it extract?
| Field | Description |
|---|---|
sourceUrl | The PDF the row came from |
status | ok, no_text_layer, no_tables_found, charge_limit_reached, download_failed or parse_failed |
pageNumber | Page the table was found on |
tableIndex | Which table on that page |
data | The row itself, keyed by column name |
How to extract tables from a PDF
- Click Try for free.
- Paste one or more direct links to PDF files into the PDF URLs field. Each link must point at the file itself, not at a viewer page.
- Leave the field empty if you just want to see the output format — a sample purchase order ships with the Actor and runs without any input.
- Click Start and open the Dataset tab when the run finishes.
- Export as CSV or Excel, or copy the API endpoint to pull the data automatically.
Input
| Field | Type | Default | Description |
|---|---|---|---|
pdfUrls | array | [] | Direct links to the PDFs to process. Empty runs the bundled sample. |
minTableRows | integer | 2 | Ignore tables smaller than this. Raise it if a layout produces small false positives. |
maxPages | integer | 200 | Stop after this many pages per document, so an unexpectedly large file cannot run up the bill. |
{"pdfUrls": ["https://example.com/invoice-2026-04.pdf","https://example.com/purchase-order-147.pdf"],"minTableRows": 2}
Output
{"sourceUrl": "https://example.com/purchase-order-147.pdf","status": "ok","pageNumber": 1,"tableIndex": 1,"data": {"Part number": "RS-4521-A","Description": "Deep groove ball bearing 6204","Qty": "120","Unit price": "8.40","Lead time": "5 days"}}
Pricing
You pay per page processed, so the bill matches the work and nothing else. Pages inside files that could not be downloaded are never charged.
| Event | Price |
|---|---|
| Actor start | $0.01 |
| Page processed | $0.01 |
How much does it cost to extract tables from 1,000 PDF pages?
About $10. A single 20-page invoice costs roughly $0.20. Charging per page rather than per extracted row keeps the cost predictable: you know how many pages your documents have before you run them, but never how many rows they contain.
Integrations and API
Every run is available through the Apify API, so you can schedule extractions, push results into Google Sheets, Airtable, Zapier or Make, or call the Actor from your own backend. The Actor is also exposed through the Apify MCP server, which lets an AI assistant read a PDF's tables directly as part of a larger workflow. The input is deliberately small — a list of URLs — so it composes cleanly inside an agent.
Works well with
Got scanned documents? Run them through PDF OCR first to get a text layer, then bring the result back here to pull the tables out of it.
FAQ
Does it work with scanned PDFs?
Not directly. A scan is an image with no text layer, so there is nothing to extract
until it has been through OCR. Rather than returning an unexplained empty result, the
Actor flags those documents with the no_text_layer status — and does not charge you
for them — so you know exactly which files to route through
PDF OCR first.
Can it read tables that have no borders?
Yes. Columns are detected from the horizontal positions that recur across lines, which covers whitespace-aligned layouts up to 12 columns. Wider layouts are picked up when the PDF rules them with visible lines.
What happens to tables that span several pages?
They come back as one table per page. Join them on sourceUrl and the column names to
rebuild the full table.
Why did a table come back empty or missing?
Three common causes: the PDF is a scan (no_text_layer), the layout has no detectable
table (no_tables_found — try lowering minTableRows), or the "table" is actually a
chart figure, which is skipped on purpose because its cells hold no usable column names.
Is there a file size limit?
Yes, 50 MB per file. Larger documents should be split before processing.
Is it legal to extract data from PDFs?
You are responsible for having the right to process the documents you submit. This Actor only reads files you point it at; it does not crawl or bypass any access control.
Support
Found a bug or need a format handled that is not covered yet? Open an issue on the Actor's Issues tab and it will be looked at. Feature requests for specific document layouts are welcome — real examples make the Actor better for everyone.