How to Extract Tables from PDFs Using pdf-inspector: 3 Detection Methods Explained
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 re-exports three distinct detectors, each optimized for different PDF table constructions:
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, 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 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 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. This tool runs the full detection pipeline and outputs formatted results without writing Rust code.
# 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 and granular detectors via src/tables/mod.rs.
Using the Full Pipeline
The process_pdf function handles document loading, text extraction, and table detection in a single call:
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.
Direct Detector Access
You can invoke specific detectors when you know the structure of your input documents:
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:
-
Collect geometry –
extractor::fontsandextractor::content_streamparse the PDF content stream and expose rectangles (PdfRect) and lines (PdfLine). -
Cluster geometry –
detect_rects::cluster_rectsgroups overlapping rectangles, whiledetect_linesgroups intersecting line segments. -
Build a grid –
detect_rects::detect_table_from_rect_groupanddetect_lines::detect_vector_grid_tables_from_linessnap edges, compute column/row boundaries, and assign text items (TextItem) to cells. -
Heuristic fallback –
detect_heuristic::detect_tablesmerges glyph items, expands consolidated financial numbers, and uses text-anchor patterns to infer a grid when geometry is missing. -
Validate and format –
tables::format::table_to_markdownand themarkdownmodule convert theTablestruct 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. -
The
pdf2mdCLI tool (src/bin/pdf2md.rs) enables immediate table extraction without coding, supporting both Markdown and JSON output through the--jsonflag. -
Rust developers can call
process_pdffromsrc/lib.rsfor full pipeline execution, or use specific functions likedetect_tables_from_rectsanddetect_tables_from_linesfor 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_markdownmethod defined insrc/tables/format.rsfor 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. 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, 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, 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) 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →