A Claude skill that gets tables out of PDFs and into a spreadsheet without the usual mess: columns that slide into each other, a 3-page table split into three pieces with the header repeated, 1.234,56 pasted as text, (1,200.00) that should be negative.
You give Claude one or more PDFs (reports, bank or card statements, price lists, exported ledgers). You get:
- tables.xlsx: an Index sheet listing every table, then one sheet per table, named from the PDF's own caption (for example "T1 Revenue by region").
- csv/: one CSV per table.
- report.md: what was found, where, and which checks passed.
What it does
- Finds ruled tables (with lines) and borderless tables (columns lined up with spaces).
- Joins a table that continues over the next page and drops the repeated header.
- Rejoins cells that wrap onto a second line.
- Turns
1,234.50,1.234,56,(12.00),-12,12.5%and dates into real numbers and dates, column by column. Use--keep-textto keep everything exactly as printed. - Checks what it can prove: a Total row against the rows above it, and a running balance against the debits and credits. These show as PASS or FAIL in the report.
- Scanned pages (no text layer) are listed, not skipped. Claude reads them visually and passes its reading back through the same cleaning and checks, so a misread digit in a column with a total shows up as a FAIL.
What you need
- A Claude plan with code execution (claude.ai), or Claude Code, or the Claude API.
- Or no Claude at all: Python 3 with pdfplumber and openpyxl to run the script yourself.
5-minute setup
- In claude.ai, open Settings, then Capabilities, and turn on code execution.
- Open Customize, then Skills. Click the plus button and choose Upload a skill.
- Pick
claude-ai-uploads/pdf-to-sheet-extractor.zipfrom this download. - Start a new chat. Drop in
samples/quarterly_report.pdf. - Ask: "Put the tables from this PDF into a spreadsheet."
- You get
tables.xlsxwith one sheet per table and a report that says which totals were checked.
Setup
Claude Code
unzip oarsman-pdf-to-sheet-extractor-v1.0.2.zip
cp -r oarsman-pdf-to-sheet-extractor/skills/* ~/.claude/skills/
or as a plugin: claude plugin marketplace add ./oarsman-pdf-to-sheet-extractor then claude plugin install oarsman-pdf-to-sheet-extractor@oarsman-pdf-to-sheet-extractor.
claude.ai (turn on code execution under Settings > Capabilities): Customize > Skills > + > Upload a skill, and pick claude-ai-uploads/pdf-to-sheet-extractor.zip.
Claude API: upload the skill folder with the Skills API and use it with the code-execution tool. It needs pdfplumber and openpyxl, which the sandbox has.
Then attach PDFs and ask: "Put the tables from these PDFs into a spreadsheet."
Run the script yourself (no Claude needed)
pip install pdfplumber openpyxl
python3 skills/pdf-to-sheet-extractor/scripts/extract_tables.py samples/*.pdf --out-dir tables
Options: --pages 2-5, --no-merge, --keep-text, --iso-dates, --add-json transcribed.json.
Try it on the samples
samples/ has three made-up PDFs: a quarterly report (a ruled table, a borderless table, and a 46-row ledger over two pages), a German bank statement (borderless, 1.234,56 numbers, running balance) and a scanned page. expected/ has the output from our run. python3 tests/run_tests.py re-runs our 24 checks (needs pdfplumber).
AI disclosure and limits
- The extraction is code (pdfplumber plus our own rules), not AI. Claude's part is checking the output, naming things and reading scanned pages. Reading scans is AI and can be wrong; the checks only catch it in columns that have a total or a balance.
- Tables with no total row and no balance column are not checked. The report says so.
- We tested on PDFs we generated ourselves. Real PDFs vary a lot, especially borderless ones; that's why the skill tells Claude to compare the first and last rows with the PDF before answering.
- Dense statistical reports (many columns, two-line headers, section breaks inside one table) come out fragmented. We tried one real report like that (see
tests/real_world_smoke.md) and the result needed manual rebuilding. - Password-protected PDFs need the password removed first. Since v1.0.1 they are listed as skipped instead of stopping the run.
- Real-world test (v1.0.1, see
tests/REAL-WORLD-QA.md) on public government PDFs: on a 7-page US Census release, rows of most tables were packed into single cells; on a 3-page rotated Federal Reserve release, column headers were misaligned. v1.0.1 now flags both under "Check these pages" so they are not passed off as clean, but it does not fix them. A 22-page Federal Reserve release came out in fragments with weak table names. Simple ruled and borderless tables, like the samples, work well. - Not tested: Claude's visual reading of real scanned pages (needs a paid model), and PDFs over about 50 pages.
- Charts and images of tables inside text PDFs are not read.
What Pro adds
PDF to Sheet is free. If your PDFs are supplier invoices, bills or receipts, the paid Invoice & Receipt Extractor (oarsmanai.com/agents/invoice-receipt-extractor/) adds: one checked row per invoice plus line items, receipt photos and scans, total and tax arithmetic checks, day/month date checks, duplicate-bill detection against last month's ledger, and an n8n workflow that fills a Google Sheet from an upload form or Gmail. It is a separate tested product, not an unlocked version of this one.
What's in the folder
skills/pdf-to-sheet-extractor/ SKILL.md, scripts/extract_tables.py, scripts/numparse.py, references/tips.md
claude-ai-uploads/ the skill as a single zip for claude.ai
samples/ 3 synthetic PDFs and ground_truth/ CSVs
expected/ the outputs from our test run
tests/ run_tests.py, fixtures, results.json, run_log.txt
Built by Oarsman AI's AI agents and checked against the test report in TESTS.md. Support is self-serve: this README, TROUBLESHOOTING.md and versioned updates at the same download link. There is no call, chat or email support. Not affiliated with Anthropic; Claude is a trademark of Anthropic, PBC.