extract table from pdf
How to Extract Tables from PDF in Python — 8 Libraries Tested & Compared in 2026
Python PDF Table Extraction : An Introduction
Extracting tables from PDFs is one of those tasks that sounds simple until you actually try it.
PDFs were designed for print fidelity, not data portability. A table inside a PDF is just a collection of text fragments, lines, and coordinates arranged to look like a grid, there is no native “table” object to grab.
That gap between appearance and structure is why Python PDF table extraction remains surprisingly hard in 2026. The ecosystem has matured, but no single library wins across every scenario: scanned documents break most open-source tools, borderless tables confuse coordinate-based parsers, and multi-page tables still get split into disconnected chunks.
This guide benchmarks 8 libraries (open-source, commercial, and AI-powered) against real documents. For each, you will find the installation steps, a working code snippet, a breakdown of strengths and limitations, and a recommendation for when to use it.
Quick Comparison: 8 Python PDF Table Extraction Libraries (2026)
Before we proceed, let’s take a look at a quick comparison between the 8 libraries:
TL;DR: For digital PDFs with structural line objects, use pdfplumber (or Camelot if you need its visual debugger). For a zero-config LLM-ready pipeline, use PyMuPDF4LLM or LLMWhisperer V2. For open-source AI extraction including scanned PDFs, use Surya / Marker. pypdf alone is not a table extraction tool, it is included here because it is what most developers install first.
| Python Library | Approach | Scanned PDF | Borderless Tables | Multi-page Tables | Setup Complexity | Output Format | Best For |
|---|---|---|---|---|---|---|---|
| pypdf | Pure-Python text layer parsing | No | No | No | Very Low | Plain text, strings | Text/metadata extraction; not suited for tables |
| Camelot | Computer vision / coordinate | No | Limited (stream mode) | No | Medium (Ghostscript required; pdfium backend optional) | DataFrame, CSV, JSON, Excel | Bordered tables in digital PDFs with actual line objects |
| Tabula | Java-based coordinate parsing | No | Limited | Partial | Medium (Java JRE) | DataFrame, CSV, JSON, TSV | Quick extraction, multi-page docs |
| pdfplumber | pdfminer layout analysis | No | Yes (configurable) | Partial | Low | List of lists, DataFrame | Complex layouts, custom pipelines |
| unstructured | Layout analysis + OCR | Yes (hi_res) | Yes | Partial | Medium (optional system deps) | Elements, HTML, JSON, CSV | Mixed document pipelines, LLM preprocessing |
| PyMuPDF4LLM | MuPDF rendering + layout engine | Partial (hybrid OCR) | Partial | Partial | Very Low | Markdown, JSON, TXT | LLM / RAG pipelines, modern stacks |
| Surya / Marker | VLM (650M params) + OCR | Yes | Yes | No | High (GPU/llama.cpp) | Markdown, JSON, HTML | Open-source AI table extraction |
| LLMWhisperer | AI + OCR, layout preserving | Yes | Yes | Yes | Very Low (API key) | Layout-preserved text | Complex/irregular tables for LLMs |
Why PDF Table Extraction Is Still Hard in 2026
The root problem has not changed: PDFs encode visual appearance, not semantic structure.
When a designer draws a table, the PDF stores each cell’s text at specific XY coordinates with font metrics. There is no
| Axis | What we measured |
|---|---|
| Ease of setup | Installation steps, system dependencies, time to first result |
| Extraction accuracy | Completeness and correctness of cell content vs. source |
| Structure preservation | Whether rows, columns, and merged cells survived extraction |
| Scanned/image support | Whether the tool can process image-only PDFs |
| Multi-page table handling | Whether tables spanning pages are merged or split |
| LLM readiness | Whether output can feed directly into an LLM prompt without post-processing |
pypdf
pypdf is a free, pure-Python PDF library capable of splitting, merging, cropping, transforming, encrypting, and extracting text and metadata from PDF files. It is the successor to PyPDF2 (merged back under the pypdf name) and is the most widely-installed PDF package in Python by download count.
Important caveat before you read further: pypdf has no built-in table detection or table extraction. It reads the raw text layer of a PDF but has no awareness of rows, columns, or cell boundaries. It is included in this guide because it is the first package most developers install when they need “something from a PDF” and understanding what it can and cannot do saves a lot of wasted effort.
What pypdf is Good For
- Extracting raw text from digital (non-scanned) PDFs
- Reading and writing PDF metadata
- Splitting, merging, and rotating pages
- Filling PDF form fields
- Encrypting/decrypting PDFs
- Cropping page regions for pre-processing before passing to a table extractor
Installation
No system-level dependencies. Pure Python.
Core Extraction Approach
pypdf parses the PDF’s internal content streams and reconstructs text by reading character codes, their font mappings, and positioning operators. It does not analyze spatial layout; it simply concatenates glyphs in stream order. For clean, single-column documents this produces readable text. For tables it typically produces garbled strings where cell content runs together or appears in wrong order.
Strengths
- Zero dependencies – pure Python, installs everywhere
- Best-in-class for PDF manipulation: merge, split, rotate, encrypt, form-fill
- Very fast for text extraction on clean documents
- Excellent for metadata reading and PDF introspection
- Works as a pre-processing step for other extractors
Limitations
- No table detection – extracts raw text only, no row/column awareness
- Text order can be incorrect for multi-column layouts or tables
- Cannot process scanned (image-only) PDFs
- No DataFrame output; all results are strings
Results
Running the script against both test documents confirms what the limitations section states – but seeing the exact output makes the distinction concrete.
Apple financial document
The cropped PDF output is the most practically useful result from this script: a single-page PDF containing only the bottom half of page 1, ready to pass to another tool. That downstream call will find the table correctly. pypdf’s role here is pre-processing, not extraction:
Ideal Use Case
Use pypdf when you need to manipulate PDFs (merge, split, crop, encrypt) or extract plain text from simple single-column documents. As a table extractor it is not fit for purpose – but as a pre-processing companion (page cropping, page selection, splitting large files), it is genuinely useful.
Camelot
Camelot is a Python library built specifically for PDF table extraction. It uses two distinct algorithms, lattice for bordered tables and stream for borderless ones, and provides a visual debugging interface that makes it one of the most developer-friendly options for digital PDFs.
Key features
- Lattice mode: uses computer vision to detect table borders and intersections
- Stream mode: infers columns from whitespace gaps (useful for borderless tables)
- Visual debugging:
camelot.plot()renders detected cells and lines for manual inspection - Export to CSV, JSON, Excel, and HTML directly from the API
- Accuracy reporting per table via
table.parsing_report
Installation
Camelot requires Ghostscript to be installed at the OS level before the Python package will work.
Core Extraction Approach
Camelot’s lattice mode converts the PDF page to an image, runs edge detection to find horizontal and vertical lines, computes cell intersections, and maps text fragments into cells. The stream mode skips line detection and clusters text by x-coordinate proximity instead.
Strengths
- Highest accuracy among open-source tools for bordered, digital PDFs
- Visual debugging saves hours of manual checking
- Direct pandas integration – no format conversion needed
- Per-table accuracy score helps filter low-confidence results
Limitations
- No OCR: fails entirely on scanned or image-based PDFs
- Ghostscript dependency: adds OS-level setup friction in CI/CD pipelines
- Multi-page tables: each page is treated independently; cross-page tables must be merged manually
Ideal Use Case
Digital PDFs with clearly bordered tables where accuracy matters and you can afford a short setup step. Financial reports, invoices, and government data in well-formatted PDFs are Camelot’s sweet spot.
Tabula
Tabula started as a browser-based table extraction app and grew into a widely-used Java library (tabula-java) with an official Python wrapper (tabula-py). It’s fast, well-documented, and handles multi-page documents cleanly – but requires a Java runtime.
Key features
- Two detection algorithms:
lattice(ruled lines) andstream(whitespace) - Returns tables as a list of pandas DataFrames – one per detected table
- Multi-page extraction with
pages="all" - Batch processing: convert entire directories of PDFs to CSV/JSON
- Remote PDF support: can fetch and extract from a URL directly
Installation
You need Java 8 or later installed and available on your system PATH.
Core Extraction Approach
tabula-py is a thin wrapper around tabula-java. When you call read_pdf(), it spawns a Java subprocess that parses the PDF’s internal structure, identifies table regions using line or whitespace detection, and returns the results as a list of DataFrames serialized through a JSON intermediary.
Strengths
- Excellent multi-page document handling – one call covers the entire document
- Batch directory processing built in
- Stream algorithm handles many borderless tables without configuration
Limitations
- Java dependency: adds setup complexity and startup latency per call
- No OCR: cannot process scanned documents
- Table boundary ambiguity: stream mode sometimes merges adjacent tables or splits a single wide table
Ideal Use Case
Bulk extraction from large batches of digital PDFs where speed and batch processing matter. Works particularly well when piped into a data pipeline that consumes DataFrames or CSV files downstream.
pdfplumber
pdfplumber is built on top of pdfminer.six and gives you fine-grained access to every character, line, rectangle, and curve on a PDF page. Its table extraction is highly configurable: you can define custom cell boundaries, filter by region, and adjust the heuristics that control row and column detection. It is the most flexible open-source option tested.
Key features
- Access to raw character positions, lines, curves, and rectangles
- Table extraction with fully configurable
TableSettings(line strategies, snap tolerance, join tolerance) - Region cropping: extract tables only from specific page areas using bounding boxes
- Debug visualization: render detected table boundaries as an annotated image
- Lossless preservation of merged-cell structure better than most alternatives
Installation
pdfplumber pulls in pdfminer.six, Pillow, and pypdf as dependencies, no system-level installs required.
Core Extraction Approach
pdfplumber maps every character on the page to an XY coordinate. Its table detector then looks for horizontal and vertical lines (from PDF drawing commands), snaps nearby text to those lines within a configurable tolerance, and assembles the result into a grid. Where lines are absent, you can instruct it to infer boundaries from text spacing instead.
Strengths
- Most configurable open-source option – you can handle nearly any layout with the right settings
- No system dependencies beyond Python packages
- Excellent for pages with mixed text and table content
Limitations
- No OCR: works only on text-based PDFs
- Verbosity: complex layouts require significant settings tuning
- Performance: character-level processing is slower than for instance Tabula on large documents
Ideal Use Case
Pipelines that need precise, programmatic control, especially when tables share a page with prose, footnotes, or diagrams and you need to extract only specific regions. Also the best choice when you want to post-process the raw cell data before persisting it.
unstructured.io
unstructured is an open-source Python library from Unstructured.io built for extracting and preprocessing content from a wide range of document formats (PDFs, DOCX, HTML, Markdown, images, and more) and feeding that content into LLM and RAG pipelines. Its PDF parser supports multiple extraction strategies, ranging from a fast text-layer pass to a full layout-detection + OCR pipeline that handles scanned documents and complex table structures.
Key features
- Three PDF strategies:
fast(text layer only),hi_res(layout detection + OCR), andocr_only(OCR across the whole page) - Table extraction:
hi_resstrategy withinfer_table_structure=Truereturns tables as HTML strings with full cell structure - Structured Elements API: every extracted piece of content – title, paragraph, table, list item – is typed (
Table, Text, Title, NarrativeText, etc.) - LangChain and LlamaIndex integration out of the box
unstructured-ingest CLIand Python API for batch pipeline processing- Supports 20+ document formats with a unified API
Installation
The hi_res strategy also requires system-level dependencies:
Note: hi_res uses detectron2 (or layoutparser) for layout detection. On first use it downloads model weights automatically. A GPU is not required but significantly speeds up processing for large documents.
Core Extraction Approach
unstructured applies a multi-stage document understanding pipeline. In hi_res mode it renders each page as an image, runs a layout detection model to identify text blocks and table regions, then applies OCR to each detected element. Table regions are parsed into HTML using the detected cell structure.
Ideal Use Case
Building document ingestion pipelines that process many different file types alongside PDFs, or LLM/RAG workflows where you need structured, typed elements rather than raw extracted text. Also a strong choice when you need local OCR-capable extraction without a paid API, and are willing to invest in the hi_res setup.
PyMuPDF4LLM
PyMuPDF4LLM is a lightweight extension for PyMuPDF (the Python bindings for the MuPDF rendering library) that converts PDFs into clean, structured output (Markdown, JSON, or plain text) with automatic table detection, layout analysis, and optional hybrid OCR. It is purpose-built for LLM and RAG pipelines and is the newest entry in this comparison.
Key features
- Automatic table detection – no configuration required for most PDFs
- Tables render as GitHub-Flavored Markdown
tables in to_markdown()output to_json()returns cell-level bounding boxes and layout metadata for custom pipelines- Hybrid OCR: automatically OCRs only image-covered or illegible regions, skipping clean text
- Layout analysis reconstructs reading order across single and multi-column pages
- LangChain and LlamaIndex integration out of the box
Ideal Use Case
Building LLM or RAG pipelines where the extracted content goes directly into a prompt or a vector store. Also the fastest path from PDF to LLM-ready Markdown when you do not want to write post-processing code.
Surya / Marker (DataLab)
Surya and Marker are two complementary open-source libraries from DataLab. Surya is the underlying AI model, a 650-million-parameter vision-language model (VLM) that handles OCR, layout analysis, reading-order detection, and table recognition across 90+ languages. Marker is the higher-level document converter that uses Surya under the hood and exposes a clean TableConverter API for extracting tables directly from PDF files as Markdown, JSON, or HTML.
Key features
- Fully local – no data leaves your machine
- OCR built in – works on scanned and image-only PDFs
- HTML table output with full spanning cell support (
colspan,rowspan) - 90+ language support
- marker
TableConverter: extracts only tables, output as Markdown/JSON/HTML - Apache 2.0 code license; model weights under modified OpenRAIL-M
Ideal Use Case
Teams that need high-quality, locally-run AI table extraction without sending data to a third-party API. Especially strong for scanned PDFs, multi-language documents, and tables with complex spanning cells.
LLMWhisperer
LLMWhisperer is an AI-powered document processing API. Unlike all other tools in this comparison, it is not a table extractor in the traditional sense; it is a layout-preserving PDF-to-text converter with a dedicated table mode. The output is clean, structured plain text that preserves the original table layout, making it ideal for LLM inference use cases where you want the model to understand the table’s structure without any custom parsing.
Key features
- Layout-preserved text output: tables come out looking like tables, not jumbled text
- Handles scanned, image-based, and handwritten PDFs via built-in OCR
- Cross-page table support: rows that overflow to the next page are correctly merged
Ideal Use Case
Any pipeline where extracted tables will be consumed by an LLM. Especially strong for scanned documents, complex multi-column financial tables, tables with merged cells, and documents where structure varies across pages.
Python Table Extraction: Benchmark Summary
Results from running all libraries against apple.pdf (clean financial statements) and best-unicef-1.pdf (mixed-format annual report):
| Library | apple.pdf | best-unicef-1.pdf | Scanned | Setup Time | Notes |
|---|---|---|---|---|---|
| pypdf | No table output (raw text only) | No table output (raw text only) | No | ~1 min | Not a table extractor; included for completeness |
| Camelot | Failed (lattice) / Partial (stream, column errors) | High accuracy | No | ~5 min | Lattice fails on cosmetic borders; stream mode recovers data with tuning |
| Tabula | Partial (some columns merged) | Good accuracy | No | ~5 min | Java required; stream mode helps |
| pdfplumber | Very high accuracy | Very high accuracy | No | ~2 min | Best open-source for digital PDFs |
| unstructured | Good accuracy (hi_res) | Good accuracy (hi_res) | Yes (hi_res) | ~10 min | hi_res needs Tesseract + layout model; open-source |
| PyMuPDF4LLM | High accuracy (Markdown tables) | High accuracy | Partial | ~1 min | Best for LLM/RAG pipelines |
| Surya / Marker | Very high accuracy | Very high accuracy | Yes | ~30 min | GPU/llama.cpp required; best open-source AI option |
| LLMWhisperer | Very high (table mode) | Very high (table mode) | Yes | ~2 min | Best overall for LLM inference |
Key findings
- pypdf extracted raw text from both documents but produced no table structure whatsoever, cell content merged with adjacent text. It is not a table extraction tool.
- Camelot failed on apple.pdf because that document uses text-drawn table separators rather than actual PDF line objects, a common issue with programmatically generated financial PDFs.
- Tabula handled both documents but introduced column merge errors on wide tables where whitespace gaps were ambiguous.
- pdfplumber consistently delivered the best accuracy among open-source coordinate tools on both documents, with no additional configuration beyond the defaults.
- unstructured with hi_res strategy extracted tables from both documents with good accuracy, returning structured HTML. The fast strategy missed most table structure, confirming that infer_table_structure=True with hi_res is required for reliable table output.
- PyMuPDF4LLM handled both documents cleanly on bordered tables and its Markdown output was immediately usable in LLM prompts. Borderless table detection was inconsistent, outcome varied by page with no reliable configuration override.
- Surya / Marker produced very high accuracy across both documents and was the only fully open-source tool to also handle scanned content correctly. Multi-page tables are not merged automatically. The trade-off is significant setup time and GPU/llama.cpp infrastructure.
- LLMWhisperer V2 with table mode and ASCII line markers produced the most accurate and LLM-ready output across both documents and handles scanned PDFs identically without any code changes.
How to Choose the Right Python Library for PDF Table Extraction
No single library wins every scenario. The right choice comes down to four questions about your documents and your pipeline.
Start with what your PDF actually is. If you only need to merge, split, crop, rotate, or read metadata from PDFs and do not need table data at all, pypdf is the correct tool. It is pure Python, installs in seconds, and handles PDF manipulation better than any other library here.
If your PDF is scanned or image-only (no embedded text layer), most tools in this guide will return nothing useful.
For teams where reliability and time-to-result matter more than keeping everything on-premise, LLMWhisperer V2 is the more practical answer: a single API call handles scanned, digital, and mixed PDFs identically, OCR is included with no configuration, cross-page tables are merged automatically, and the free tier covers 100 pages per day with no credit card required.
If your PDF has a text layer (digitally created, not scanned), the next question is where the extracted tables are going.
For LLM and RAG pipelines, the output format matters as much as accuracy. PyMuPDF4LLM is a solid local starting point, one pip install, no system dependencies, and tables render as GitHub-Flavored Markdown.
Camelot is a useful alternative when you need its visual debugger (camelot.plot()) to inspect why a table is being mis-parsed. For borderless tables, pdfplumber via the “text” vertical strategy and Tabula via stream mode both work, though both require per-document tuning.
Tabula is the simpler API when you need quick batch extraction across many files. If your pipeline handles multiple document formats alongside PDFs – DOCX, HTML, Markdown – unstructured with the hi_res strategy and infer_table_structure=True avoids the overhead of maintaining separate parsers for each type.