PDF Tables to CSV and JSON
Pricing
from $10.00 / 1,000 page processeds
PDF Tables to CSV and JSON
Extract tables from batches of PDF URLs with page references and downloadable CSV and JSON files.
Pricing
from $10.00 / 1,000 page processeds
Rating
0.0
(0)
Developer
Kiwi Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Turn the tables inside PDF reports into spreadsheet-ready CSV and structured JSON. Paste a list of PDF links, get one clean file per table, with the source URL and page number attached to every table.
Powered by the open-source Docling library for layout and table-structure recognition, with optional English OCR for scanned pages.
What it's good for
- Financial statements and annual reports: income statements, balance sheets and cash-flow tables into CSV for analysis.
- Government and statistics publications: pull the data tables out of 50-page reports without copying by hand.
- Research papers: results tables from scientific PDFs, keeping multi-level headers readable.
- Batch pipelines: up to 100 PDFs per run via the API, with per-PDF status so one bad link never stops the batch.
- Scanned documents: turn on OCR for pages that have no text layer (see OCR caveats below).
How it works
- Each PDF is downloaded (public HTTP/HTTPS links only) and checked.
- Docling detects tables and their cell structure on the first
maxPagespages. - Tables are cleaned up:
- Stacked headers become
Parent / Childnames, e.g.Three Months Ended / September 28, 2024. - Merged cells and section labels such as
ASSETS:appear once, not repeated across every column. - Tables of contents and lists of figures are skipped.
- Stacked headers become
- Each table is saved as its own CSV and JSON file, and listed in the dataset with download links.
Input
| Field | Type | Default | Description |
|---|---|---|---|
pdfUrls | array of URLs | required | Direct links to public PDFs, 1–100. Duplicates are processed once. |
maxPages | integer | 20 | Process the first N pages of each PDF (1–200). You pay per processed page. |
enableOcr | boolean | false | Read scanned pages (no text layer) with English OCR. |
tableMode | accurate / fast | accurate | Table-structure model. fast is quicker on simple grids. |
headerStyle | joined / leaf / dotted | joined | Multi-level headers as Parent / Child, lowest header only, or Parent.Child. |
mergedCells | first / repeat | first | Put a merged cell's text in its first cell only, or repeat it in every covered cell. |
includeNonDataTables | boolean | false | Keep contents pages and lists of figures (marked tableType: "contents"). |
safeCsv | boolean | true | Prefix formula-like CSV cells (=, +, -, @) with an apostrophe so spreadsheets don't execute them. JSON keeps the original text. |
maxFileSizeMb | integer | 25 | Reject larger downloads (1–100 MiB). |
documentTimeoutSeconds | integer | 180 | Stop converting a PDF that takes longer than this (30–1800). |
{"pdfUrls": ["https://example.org/annual-report.pdf", "https://example.org/statistics.pdf"],"maxPages": 20,"enableOcr": false,"headerStyle": "joined"}
Output
Dataset: one table record per extracted table and one document record per PDF. The Console's "Tables and document results" view shows the key fields with CSV/JSON links.
Table record (shortened):
{"recordType": "table","sourceUrl": "https://example.org/annual-report.pdf","tableIndex": 1,"pages": [1],"columns": ["", "Three Months Ended / September 28, 2024", "Three Months Ended / September 30, 2023"],"rows": [["Net sales:", "", ""], ["Products", "$ 69,958", "$ 67,184"]],"rowCount": 38,"columnCount": 5,"headerRowCount": 2,"sectionRows": [0],"tableType": "data","ocrUsed": false,"caption": "Table 1: …","csvUrl": "https://api.apify.com/v2/key-value-stores/…/records/doc-001-…-table-001.csv?signature=…","jsonUrl": "https://api.apify.com/v2/key-value-stores/…/records/doc-001-…-table-001.json?signature=…"}
Document record (shortened):
{"recordType": "document","sourceUrl": "https://example.org/annual-report.pdf","status": "success","totalPages": 61,"convertedPages": 20,"tableCount": 4,"ocrPages": [],"nonDataTablesSkipped": [{"pages": [5], "reason": "dot leaders"}],"billing": {"events": {"page": 20, "ocr-page": 0}},"warnings": ["Only the first 20 pages were requested."]}
status is one of:
successpartial: Docling converted only some pages.error: witherrorTypeanderror, e.g. HTTP 404, not a PDF, encrypted, corrupt, too large, or timed out.skipped: your maximum charge was reached.
Key-value store: …-table-NNN.csv (UTF-8 with BOM, opens directly in Excel) and …-table-NNN.json for every table, plus a SUMMARY record with totals and any skipped URLs.
Pricing
Pay per event: you pay only for pages of PDFs that convert successfully.
| Event | Price | When it's charged |
|---|---|---|
Page processed (page) | $0.01 | Each page converted and searched for tables, including pages where no table was found. |
OCR page processed (ocr-page) | $0.025 | Each scanned page (no text layer) read with OCR when enableOcr is on. Charged instead of a normal page, never both. |
- Failed, skipped and errored PDFs are free. Only the first
maxPagespages are processed. - Digital pages are always charged as normal pages, even with OCR enabled.
- Example: a batch of 10 reports × 20 pages costs $2.00. Five 2-page scans with OCR cost $0.25.
- Set Maximum cost per run in the run options. The Actor checks each PDF's page count before converting it. If processing it would go over your limit, it stops cleanly and lists the remaining URLs as
skippedin the dataset and inSUMMARY.skippedUrls.
OCR caveats (read before using scans)
- OCR reads pixels, not text. It can silently misread numbers: dropped decimal points (
1.47→147), missing or wrong thousands separators (294,866→294866,14,695→14.695), and stray characters (14,874 um). - In testing on a clean 200 dpi scan of financial statements, table structure was recovered exactly, but about 7% of cells differed from the digital original.
- Tables read with OCR have
ocrUsed: trueand asuspiciousValueslist flagging values that look misread, with row, column and reason. In the same test it flagged 12 of the 13 numeric errors. It is a prompt to check, not a guarantee: values it doesn't flag can still be wrong. - Verify important figures against the PDF, especially for scans, low-resolution images, handwriting, or non-English text. Only English OCR is included.
- Digital PDFs don't need OCR. Leave it off for faster, cheaper and more accurate results.
Limits and accuracy
- Table detection is machine learning, not magic. It can miss borderless tables, split or merge cells, or misread complex layouts. "No tables found" doesn't prove a PDF has no tables.
- Tables that continue across pages are returned as separate tables, one per page.
- Header rows are detected automatically. Occasionally the first data row is treated as part of the header.
- Contents-page detection is heuristic. Turn on
includeNonDataTablesif a real table goes missing. - Up to 100 PDFs, 200 pages per PDF and 100 MiB per file per run. Password-protected PDFs, login-only links, private-network addresses and non-standard ports are not supported.
- The default memory is 4 GB. Most PDFs peak at 1–2.2 GB. Choose 8 GB for roughly 1.7× faster processing.
Your responsibility
Only submit PDFs that you have the right to download and process, and respect any copyright, licence or confidentiality terms that apply to them. Results and downloaded files are stored in your Apify account storage and follow your account's retention settings.
Attribution and licences
This Actor is an independent product. It is powered by the open-source Docling library (MIT licence) and is not affiliated with, endorsed by or sponsored by IBM or the Docling project. It also uses:
- Docling's layout model (Apache-2.0) and TableFormer model weights (CDLA-Permissive-2.0)
- PyTorch (BSD-style licence)
- Tesseract OCR (Apache-2.0)
- the Apify SDK (Apache-2.0)
Licence texts and notices ship with the Actor image (THIRD_PARTY_NOTICES.md and the licenses/ folder).