/pdf - Extract Structured Data from PDFs
Extract structured data from PDFs into JSON and Excel format efficiently.
Universal skill for batch-processing PDF documents into structured JSON and a merged Excel file. Works from any project directory.
Do NOT ask for confirmation — just execute and report results at the end.
Step 0: Detect input
- Find PDF source folder: Check for a
pdf/directory in the current working directory. If it doesn't exist, check forpdfs/,documents/, ordocs/(in that order). If none found, ask the user to specify the path. - List all
.pdffiles in the source folder (non-recursive by default). Print the count:Found N PDFs in <folder>/. - Create output directory:
mkdir -p ./outputin the current working directory. - If no PDFs are found, STOP and report:
No PDF files found in <folder>/.
Step 1: Parallel extraction — spawn sub-agents
For EACH PDF file, launch an independent sub-agent (using the Agent tool). Launch ALL sub-agents in a SINGLE message so they run in parallel — do NOT process sequentially.
Each sub-agent receives this task:
Read the PDF file at: <absolute_path_to_pdf>
Extract ALL structured data and write a JSON file to: <absolute_path_to_output>/<filename_without_ext>.json
The JSON schema MUST be exactly:
{
"source_file": "<original filename>",
"title": "<document title — from metadata, first heading, or first prominent text>",
"sections": [
{
"heading": "<section heading or 'Introduction' if none>",
"content": "<full text content of this section>",
"page_numbers": [1, 2]
}
],
"key_entities": [
{
"name": "<entity name>",
"type": "<person|organization|date|location|amount|product|other>",
"context": "<short sentence where entity appears>"
}
],
"metadata": {
"page_count": <number>,
"language": "<detected language code, e.g. cs, en>",
"extracted_at": "<ISO 8601 timestamp>"
},
"raw_text": "<complete raw text of the entire document>"
}
Rules:
- Read the PDF using the Read tool (it supports PDFs). For large PDFs (>10 pages), read in chunks of 20 pages at a time.
- Extract entities: names of people, organizations, dates, monetary amounts, locations, products — anything notable.
- Split into sections based on headings, page breaks, or logical content boundaries.
- If the PDF has no clear sections, create a single section with heading "Content".
- Write the JSON to disk IMMEDIATELY after extraction — do not hold it in memory.
- Use JSON.stringify with 2-space indentation.
- Report back: filename, title found, number of sections, number of entities, page count.
Important: If there are more than 10 PDFs, batch them into groups of 10 sub-agents at a time. Wait for each batch to complete before launching the next. This prevents overwhelming the system.
Step 2: Verify extraction
After all sub-agents complete:
- List all
.jsonfiles in./output/. - Compare against the original PDF list — report any missing extractions.
- For each JSON, verify it parses correctly and has the required schema fields.
- Report:
Successfully extracted N/M PDFs.
If any extractions failed, note them but continue with the successful ones.
Step 3: Merge into Excel
Before generating the Excel file, present the proposed structure to the user and wait for approval.
Show the user a preview like this:
Navrhovaná struktura výstupního Excel souboru:
📊 final_output.xlsx
├── Sheet 1: "Summary"
│ └── Columns: File | Title | Language | Pages | Sections | Entities | Extracted At
│ └── (jeden řádek per dokument)
│
├── Sheet 2: "<název souboru 1>"
│ ├── Tabulka "Sections": Section Heading | Content | Pages
│ └── Tabulka "Entities": Entity | Type | Context
│
├── Sheet 3: "<název souboru 2>"
│ └── (stejná struktura)
└── ...
Celkem: N listů (1 summary + N dokumentů)
Výstup: ./final_output.xlsx
Wait for the user to confirm or request changes (e.g., different columns, different sheet layout, additional sheets). Adjust the structure accordingly before proceeding.
Once approved, create ./final_output.xlsx using a Python script:
- Check if
openpyxlis available:python3 -c "import openpyxl". If not, install it:pip3 install openpyxl. - Generate and execute a Python script that:
- Reads all JSON files from
./output/ - Creates a workbook with the approved structure (default below if user confirms without changes):
- Summary sheet (first sheet): columns =
File | Title | Language | Pages | Sections | Entities | Extracted At. One row per document. - One sheet per document (sheet name = first 31 chars of filename): columns =
Section Heading | Content | Pages. Below the sections table, add an "Entities" table:Entity | Type | Context.
- Summary sheet (first sheet): columns =
- Sheet names must be truncated to 31 characters (Excel limit) and deduplicated if needed.
- Saves to
./final_output.xlsx.
- Reads all JSON files from
Step 4: Report results
Print a single summary:
## 📄 PDF Processing Report
### Source: <folder> (N files)
### Extraction: ✅ N/N successful / ⚠️ N failed
### Output JSON: ./output/ (N files)
### Excel: ./final_output.xlsx
### Per-file summary:
| File | Title | Pages | Sections | Entities |
|------|-------|-------|----------|----------|
| doc1.pdf | ... | 12 | 5 | 23 |
| doc2.pdf | ... | 3 | 2 | 8 |
### Failures (if any):
- doc3.pdf: <error reason>
Notes
- This skill works with any PDF content: contracts, reports, invoices, research papers, etc.
- Entity extraction is best-effort — it identifies prominent named entities, not an exhaustive NER.
- The raw_text field preserves the complete document text for downstream use.
- All intermediate JSON files are kept in
./output/for inspection or re-processing.