# How to Extract Tables from PDFs Using pdf-inspector: 3 Detection Methods Explained

> Extract tables from PDFs with pdf-inspector using rectangle clustering, line analysis, or heuristic text patterns. Get structured Markdown or JSON output easily.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: how-to-guide
- Published: 2026-08-13

---

**pdf-inspector extracts tables from PDF documents by running three independent detection strategies—rectangle clustering, line analysis, and heuristic text patterns—and outputs structured Markdown or JSON.**

pdf-inspector is an open-source Rust library designed to locate and extract tabular data from PDF documents. Unlike simple text extractors, it employs a layered architecture that handles everything from highly formatted financial reports to plain text layouts. Whether you are processing invoices, research papers, or scanned documents, pdf-inspector can identify table structures and convert them into machine-readable formats.

## The Three-Layer Detection Architecture

pdf-inspector implements a robust detection system that combines geometric analysis with text heuristics. The public API in [`src/tables/mod.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/mod.rs) re-exports three distinct detectors, each optimized for different PDF table constructions:

```rust
pub use detect_heuristic::detect_tables;                     // high‑level heuristic detector
pub use detect_lines::detect_tables_from_lines;             // line‑based detector
pub use detect_rects::{detect_tables_from_rects, RectHintRegion}; // rectangle‑based detector

```

### Rectangle-Based Detection

The rectangle-based strategy scans PDF drawing operators (`re`) for cell-border rectangles. Located in [`src/tables/detect_rects.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_rects.rs), this detector clusters spatially overlapping rectangles using a union-find algorithm, builds a grid from the rectangle edges, and creates a `Table` object. This method excels at extracting tables from financial reports and forms with explicit cell borders.

### Line-Based Detection

When tables use line drawings rather than filled rectangles, the detector in [`src/tables/detect_lines.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_lines.rs) looks for explicit horizontal and vertical line operators. It groups these into H/V line sets, derives row and column boundaries from their intersections, and assembles a complete table structure. This approach handles technical diagrams and specification sheets where borders consist of drawn lines.

### Heuristic Text Analysis

For PDFs lacking geometric table markers, the heuristic detector in [`src/tables/detect_heuristic.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_heuristic.rs) falls back to pure-text analysis. It merges adjacent glyph items, normalizes financial-item fragments (such as consolidated currency values), finds column boundaries from text-anchor patterns, and validates the resulting grid. This ensures extraction succeeds even with scanned documents or poorly formatted PDFs.

## How to Extract Tables Using the CLI

pdf-inspector ships with a command-line binary, `pdf2md`, implemented in [`src/bin/pdf2md.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/pdf2md.rs). This tool runs the full detection pipeline and outputs formatted results without writing Rust code.

```bash

# Extract text and tables from a PDF and output Markdown

pdf2md my_report.pdf > my_report.md

# Get JSON-structured output (including tables)

pdf2md --json my_report.pdf > my_report.json

```

The CLI automatically tries all three detection strategies in priority order (rectangle → line → heuristic) and returns the first successful result. The `--json` flag emits structured data including table coordinates, cell contents, and formatting metadata.

## How to Extract Tables Programmatically in Rust

For integration into Rust applications, pdf-inspector exposes the full pipeline through [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) and granular detectors via [`src/tables/mod.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/mod.rs).

### Using the Full Pipeline

The `process_pdf` function handles document loading, text extraction, and table detection in a single call:

```rust
use pdf_inspector::{PdfOptions, ProcessMode, tables::detect_tables_from_rects};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load a PDF document
    let pdf_path = "example.pdf";

    // Run the full pipeline (detect + extract + markdown)
    let result = pdf_inspector::process_pdf(pdf_path)?;

    // Tables discovered via rectangle detection
    let (tables, _hints) = detect_tables_from_rects(
        &result.items,          // Vec<TextItem> from the extractor
        &result.rects,          // Vec<PdfRect> from the extractor
        1,                      // page number (1‑indexed)
    );

    for (i, table) in tables.iter().enumerate() {
        println!("Table {} on page 1:\n{}", i + 1, table.to_markdown());
    }
    Ok(())
}

```

The `process_pdf` function populates the `items` and `rects` vectors that geometric detectors require. The `Table` struct provides a `to_markdown` helper method implemented in [`src/tables/format.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/format.rs).

### Direct Detector Access

You can invoke specific detectors when you know the structure of your input documents:

```rust
use pdf_inspector::tables::detect_tables;

let tables = detect_tables(&text_items, page_width);

```

Here, `detect_tables` serves as a thin wrapper around the heuristic pipeline (`detect_heuristic::detect_tables`), ideal for documents where you know geometric markers are absent.

## The Table Extraction Pipeline

Understanding the internal flow helps debug extraction issues and optimize performance. According to the source code in `firecrawl/pdf-inspector`, the pipeline executes five distinct phases:

1. **Collect geometry** – `extractor::fonts` and `extractor::content_stream` parse the PDF content stream and expose rectangles (`PdfRect`) and lines (`PdfLine`).

2. **Cluster geometry** – `detect_rects::cluster_rects` groups overlapping rectangles, while `detect_lines` groups intersecting line segments.

3. **Build a grid** – `detect_rects::detect_table_from_rect_group` and `detect_lines::detect_vector_grid_tables_from_lines` snap edges, compute column/row boundaries, and assign text items (`TextItem`) to cells.

4. **Heuristic fallback** – `detect_heuristic::detect_tables` merges glyph items, expands consolidated financial numbers, and uses text-anchor patterns to infer a grid when geometry is missing.

5. **Validate and format** – `tables::format::table_to_markdown` and the `markdown` module convert the `Table` struct into Markdown tables or JSON representations.

## Summary

- pdf-inspector provides **three detection strategies** (rectangle, line, heuristic) to handle diverse PDF table formats, accessible via [`src/tables/mod.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/mod.rs).

- The **`pdf2md` CLI tool** ([`src/bin/pdf2md.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/pdf2md.rs)) enables immediate table extraction without coding, supporting both Markdown and JSON output through the `--json` flag.

- **Rust developers** can call `process_pdf` from [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) for full pipeline execution, or use specific functions like `detect_tables_from_rects` and `detect_tables_from_lines` for targeted extraction.

- The library automatically **tries detectors in priority order** (rectangle → line → heuristic), ensuring robust extraction across financial reports, technical documents, and scanned files.

- Extracted tables expose a **`to_markdown` method** defined in [`src/tables/format.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/format.rs) for immediate serialization.

## Frequently Asked Questions

### How does pdf-inspector handle PDFs without visible table borders?

When geometric operators are absent, pdf-inspector falls back to the heuristic detector in [`src/tables/detect_heuristic.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_heuristic.rs). This module merges adjacent glyph items, normalizes financial formatting fragments, and infers column boundaries from text-anchor patterns to reconstruct the table grid.

### What output formats does pdf-inspector support for extracted tables?

pdf-inspector outputs tables as structured Markdown via the `table_to_markdown` function in [`src/tables/format.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/format.rs), or as JSON when using the `--json` flag with the `pdf2md` binary. Both formats include cell coordinates and content, making them suitable for downstream data processing pipelines.

### Can I use pdf-inspector with programming languages other than Rust?

While pdf-inspector is a Rust library with its public API exposed in [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs), you can integrate it into any technology stack by calling the `pdf2md` CLI tool. The binary accepts PDF files as input and returns Markdown or JSON to stdout, which any language can parse and consume.

### Which detection method is most accurate for financial documents?

For financial reports with explicit cell borders and grid lines, the **rectangle-based detector** (`detect_tables_from_rects` in [`src/tables/detect_rects.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_rects.rs)) provides the highest accuracy. If the document uses line drawings for borders, use the **line-based detector** (`detect_tables_from_lines`). For consolidated financial tables or scanned statements, the **heuristic detector** handles merged cells and currency formatting automatically.