Skip to content
Power On Labs

Small web-data tools, and the runs that show what they return.

How do I get the tables out of a PDF as rows and columns?

A PDF has no tables in it. It has text placed at coordinates, and a table is something a reader infers from how that text lines up. Which is why copy-pasting a PDF table gives you a run of words: the structure was never stored.

Rebuilding it means grouping text by its position — and doing it from the alignment rather than from the drawn lines, because plenty of tables have no borders at all. What you should get back is an array of rows, each an array of cells, with the page it came from.

A real run

Input
{
  "pdfUrls": ["https://www.irs.gov/pub/irs-pdf/i1040tt.pdf"],
  "detectTables": true,
  "extractKeyFields": false,
  "outputFormats": ["json", "csv"],
  "maxPages": 10
}
Output — the summary of the row (the full row also carries every table and every page of text)
{
  "url": "https://www.irs.gov/pub/irs-pdf/i1040tt.pdf",
  "ok": true,
  "pageCount": 28,
  "pagesCharged": 10,
  "tableCount": 34,
  "tablesCsvUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-i1040tt.csv?signature=...",
  "jsonUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-i1040tt.json?signature=...",
  "metadata": {
    "title": "2025 Publication 1040",
    "author": "W:CAR:MP:FP",
    "subject": "TAX AND EARNED INCOME CREDIT TABLES",
    "keywords": null,
    "creator": "AH XSL Formatter V6.6 MR4 for Linux64 : 6.6.6.37929 (2019/03/11 12:35JST)",
    "producer": "Antenna House PDF Output Library 6.6.1437 (Linux64); modified using iText 2.1.7 by 1T3XT",
    "createdAt": "2025-09-17T17:52:35.000Z",
    "modifiedAt": "2026-01-15T07:41:41.000Z",
    "pageCount": 28,
    "pdfVersion": "1.7",
    "language": "EN",
    "encrypted": false,
    "hasAcroForm": false,
    "hasSignatures": false,
    "linearized": true
  }
}

Each table comes back with its shape and its position, so you can tell a real table from a layout artefact before you try to use it:

One of the 34 tables, exactly as returned
{
  "page": 9,
  "rows": [
    ["Your tax is—", "Your tax is—", "Your tax is—"],
    ["57,000", "60,000", "63,000"]
  ],
  "header": ["Your tax is—", "Your tax is—", "Your tax is—"],
  "rowCount": 2,
  "columnCount": 3,
  "bbox": { "x0": 54.2, "y0": 109.1, "x1": 532.4, "y1": 134.5 }
}

That is a small one, picked because it fits on this page. The tax tables themselves come back as 18-column, 21-row grids — ["57,000", "57,050", "7,460", "6,366", …] — and the same ten pages exported to CSV are 636 lines with a # table n — page n comment before each one.

What else is in a PDF worth taking

What this does not do

What it costs

$0.002 per page extracted, capped at 40 pages per document. The run above touched 10 pages of a 28-page file and was charged for 10 — firstPage and maxPages mean you pay for the range you need and not for the document. Reading only the metadata or the outline costs a single page. Scanned pages and files that will not download are free.

The tool that does it

PDF to JSON Extractor on Apify Store.

$0.002 per page extracted, capped at 40 pages per document. Scanned pages and files that will not download are not charged.