PDF Text Extractor & Document Parser: DOCX, XLSX, OCR, Markdown avatar

PDF Text Extractor & Document Parser: DOCX, XLSX, OCR, Markdown

Pricing

from $4.00 / 1,000 document processeds

Go to Apify Store
PDF Text Extractor & Document Parser: DOCX, XLSX, OCR, Markdown

PDF Text Extractor & Document Parser: DOCX, XLSX, OCR, Markdown

Parse Word, PowerPoint, Excel and PDF documents into clean Markdown and structured JSON: tables extracted cell-by-cell, document metadata, and RAG-ready chunks with heading paths. Built-in OCR for scans and images.

Pricing

from $4.00 / 1,000 document processeds

Rating

0.0

(0)

Developer

Daniele Giovane

Daniele Giovane

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Turn PDF, Word, Excel and PowerPoint files into clean Markdown and structured JSON — with tables extracted cell by cell, document metadata, and RAG-ready chunks that carry their heading path. Built for mixed document batches where you feed in .docx, .pptx, .xlsx, .pdf (and scans) and get back one consistent, embeddable record per file.

Scanned pages and images are handled with built-in Tesseract OCR, but OCR and "PDF to text" are table stakes — the reason to use this Actor is the Office formats, the structured cell-level tables, and the chunking that you would otherwise have to build and host yourself.

Why this Actor

  • Office formats as first-class citizens. .docx heading/list styles become Markdown, .pptx gives one section per slide, .xlsx turns every sheet into a real table. Most document parsers focus on PDFs and treat Office as an afterthought.
  • Tables as data, not as blurry text. Tables come back as arrays of cell rows (rows: [["Region","Q1","Q2"], ...]) and as a Markdown table. Merged Word cells are de-duplicated, spreadsheet formula cells without a cached value are flagged.
  • RAG chunks that keep their place. Each chunk carries a heading_path (e.g. ["1 Introduction", "1.2 Scope"]) and a cl100k_base token count. Headings and body-less sections (indexes, tables of contents) are preserved, not dropped. Heading levels are worked out across the whole document, not page by page, so a section on page 12 still nests under the title on page 1.
  • Runs in 1 GB, so you can run 16 at once. Measured peak memory is 99 MB on the heaviest case tried (a 9-page PDF with OCR forced on every page). That is not a vanity metric: it is what decides how many runs fit inside your account's memory limit, and the Actor-start fee you pay is charged once up to 1 GB and then once per extra GB — so a parser that demands 4 GB costs you four start fees per run before it has read a byte.

Everything runs inside the Actor container. The only network traffic is downloading the source URLs you provide — see Your data.

Supported inputs

PDF, DOCX, PPTX, XLSX, PNG, JPG, TIFF, TXT, CSV, MD, HTML.

  • DOCX — paragraphs with heading/list styles mapped to Markdown, inline tables (merged cells de-duplicated), core properties.
  • PPTX — one section per slide (slide title becomes a heading), bullet text, embedded tables.
  • XLSX — every sheet becomes a table plus a Markdown table; runaway sheets are capped (256 columns, 200k cells) and uncached formulas are flagged.
  • PDF — native text extraction (PyMuPDF) with multi-column reading order, font-size heading detection, table detection (pdfplumber), and OCR fallback for scanned pages.
  • PNG / JPG / TIFF — OCR (multi-frame TIFFs frame by frame).
  • TXT / CSV / MD / HTML — plain text passthrough, CSV to table, Markdown kept as-is, HTML reduced to text (tags/scripts stripped with the stdlib parser).

Corrupted files, password-protected documents, oversized files and unreachable URLs never crash the run — the record is emitted with a warnings array explaining what happened.

Input

Provide each document as a public URL, a base64 payload, or a key-value-store record. Up to 500 sources per run — extra sources are skipped and reported both in the log and in a final "source": "_meta" dataset record stating how many were dropped.

{
"sources": [
{ "url": "https://arxiv.org/pdf/1706.03762" },
{ "base64": "JVBERi0xLjQK...", "filename": "invoice.pdf" },
{ "key": "uploaded-report.docx", "store_id": "abcDEF123" }
],
"output_format": "all",
"ocr": "auto",
"ocr_language": "eng+ita",
"extract_tables": true,
"chunking": "by_headings",
"chunk_size_tokens": 512,
"chunk_overlap_tokens": 64,
"max_file_size_mb": 50,
"concurrency": 2
}
OptionValuesDefaultNotes
output_formattext / markdown / json / allallControls which textual fields are populated
ocrauto / force / offautoauto OCRs text-less and scanned-looking pages (see FAQ)
ocr_languageTesseract codes, e.g. eng+itaeng+itaLanguages not installed are skipped with a warning
extract_tablesbooleantrueStructured tables as arrays of cell rows
chunkingoff / by_headings / fixed_tokensby_headingsby_headings keeps a heading_path per chunk
chunk_size_tokens32–8192512Oversized sections are sub-split
chunk_overlap_tokens≥ 064Capped at half the chunk size
max_file_size_mb1–10050Bigger files are skipped with a warning
concurrency1–102Documents processed in parallel. Office, CSV and image sources scale with this; PDFs are parsed one at a time whatever you set, because the PDF engine is not safe to call from several threads at once

Output

One dataset record per document:

{
"source": "https://example.com/report.pdf",
"doc_type": "pdf",
"n_pages": 12,
"text": "Quarterly Report\n\nRevenue grew by...",
"markdown": "# Quarterly Report\n\n## Revenue\n\nRevenue grew by...",
"tables": [
{ "page": 3, "rows": [["Region", "Q1", "Q2"], ["EMEA", "1.2M", "1.4M"]] }
],
"metadata": { "title": "Quarterly Report", "author": "Finance Team" },
"chunks": [
{
"text": "Revenue\nRevenue grew by...",
"n_tokens": 118,
"index": 0,
"heading_path": ["Quarterly Report", "Revenue"]
}
],
"warnings": [],
"processing": { "ocr_used": false, "ocr_pages": 0, "seconds": 1.87 }
}

n_pages is the page count for PDFs, slide count for PPTX, sheet count for XLSX, frame count for images, and the page count declared in document properties for DOCX (null when unavailable). Records larger than 8 MB have their text, markdown and chunks truncated (with a warning) rather than failing the run.

Pricing (pay per event)

EventPriceWhen it is charged
apify-actor-start$0.005Once per run, charged by the platform. Apify covers the compute cost of the first 5 seconds of every run.
document-processed$0.004Once per document that produced text, Markdown or tables. Empty, failed or skipped documents are not charged
ocr-page-processed$0.012Once per page/image frame that went through OCR and produced text — blank OCR results are not charged

Examples (single run):

  • A 20-page native (non-scanned) PDF: $0.005 + $0.004 = $0.009.
  • A 20-page fully scanned PDF: $0.005 + $0.004 + 20 × $0.012 = $0.249.
  • A batch of 100 DOCX files in one run: $0.005 + 100 × $0.004 = $0.405.

OCR is the expensive part because it is the expensive part of the compute — if your documents are native Office/PDF files, you essentially only pay the per-document fee.

Honest comparison with alternatives

OCR and Markdown output are not what makes this Actor special — several tools do them well and cheaply. Here is where this Actor does and does not make sense:

AlternativeHonest trade-off
memo23 / flat-rate OCR PDF Actors (e.g. ~$0.005 per PDF, ~23 OCR languages, passwords, page ranges, ~20 parallel)For OCR-heavy PDF workloads these are excellent and often cheaper than this Actor — if scanned PDFs in many languages are your main job, use them. This Actor wins when the batch is mixed Office documents and you need cell-level tables and heading-aware RAG chunks, not just OCR text.
LLM parsers (LlamaParse, Reducto, …)Usually better on very complex layouts (nested tables, handwriting) but 5–50× more expensive per page, and your documents are sent to a third-party LLM. This Actor is deterministic, cheaper, and keeps content on-platform.
unstructured (open source)Very capable and free, but heavy to deploy (large image, many system deps) and you still need hosting, retries and an API around it.
Running PDFium / Tesseract yourselfSame underlying engines — this Actor is the glue (format detection, reading order, table normalization, chunking, warnings, storage and scheduling). If you already run that infrastructure, self-hosting is cheaper.
Simple "PDF to text" ActorsCheaper if you only need raw text from native PDFs. Doc2Data earns its price on Office formats, structured tables and RAG chunks.

Your data

  • Processed in memory only. Documents are parsed inside the Actor's container and are never written to any store except the dataset records you receive.
  • No document content is logged. Logs contain source labels, page counts and warnings — never the extracted text.
  • No external API or LLM calls. All parsing, OCR and tokenization run locally in the container, with permissively licensed engines: PDFium (BSD-3-Clause, the PDF engine from Chromium) and Tesseract (Apache-2.0). The cl100k_base tokenizer vocabulary is baked into the Docker image at build time, so nothing is downloaded at run time — the only outbound requests are fetching the source URLs you provide.
  • The author never sees your data. There is no telemetry and no hidden persistence.
  • SSRF-guarded fetching. Requests to internal/private addresses are refused — source URLs that resolve to private, loopback or link-local addresses are rejected, including across redirects.

FAQ

Which OCR languages are available? The image ships with English (eng), Italian (ita), French (fra), German (deu), Spanish (spa), Portuguese (por), Dutch (nld) and Polish (pol); combine them with +, e.g. eng+ita. Requested languages that are not installed are skipped and reported in warnings. Need another language preinstalled? Open an issue on the Actor.

How are scanned PDFs detected? In auto mode a page is OCRed when it has almost no extractable text (fewer than 25 characters), or when it looks scanned — a raster image covering more than 15% of the page area with fewer than 200 characters of extractable text. A scan with a small digital header or timestamp is therefore still OCRed. Pages with under 25 characters that cannot be OCRed (OCR off, Tesseract unavailable, cap reached) are flagged in warnings. Use force to OCR every page, off to never OCR. OCR is capped at 300 pages per document, and only OCR pages that produce text are charged.

Are password-protected documents supported? No — they are skipped with a warnings entry, and are not charged.

What if a document hangs? Each document has a 180-second budget and each OCR page a 60-second one. OCR runs as a separate process, so a page that hangs is actually killed and the run continues; the record says so in warnings. A parse stuck inside the PDF engine itself still cannot be force-killed mid-call, so the input caps (file size, cell/column limits, 300 OCR pages per document, 500 sources per run) remain the hard protection. Timed-out documents are not charged.

Is my data sent to any third party? No. See Your data. All parsing, OCR and tokenization happen inside the Actor container; the only outbound requests download the source URLs you provide.

What tokenizer do chunk token counts use? OpenAI's cl100k_base (via tiktoken), baked into the image. If it is somehow unavailable at run time, a len/4 approximation is used and a warning is added to the record — token counts are never silently fabricated.

Does output_format: "json" still contain my text? json omits the top-level text and markdown fields, but chunks are the RAG payload and therefore still contain the chunk text. Set chunking: "off" if you want structured data (tables, metadata) with no text at all.

What happens with very large spreadsheets? Sheets are capped at 256 columns, 200,000 cells and 10,000 rows per table (each with a warning), and Markdown tables render at most 200 rows to keep records manageable.

Can I process files I upload to Apify storage? Yes — upload the file to a key-value store, then reference it as { "key": "my-file.pdf", "store_id": "..." } (omit store_id to use the run's default store).

You may also need

Same author, same principles: you pay for work that was actually done, nothing is stored outside your own run, and no third-party API ever sees your data.

  • Email List Cleaner — deduplicate, verify and segment a whole email list from CSV or XLSX.
  • Phone Number Cleaner — validate and format phone numbers in bulk to E.164, with line type and carrier.