CtrlK
BlogDocsLog inGet started
Tessl Logo

extracting-tables

Use when extracting tabular data from PDFs, spreadsheets, or images. Covers layout-aware table detection, table model selection, output formats (markdown / JSON cells), and known limits.

65

Quality

78%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./plugin/.ai-rulez/skills/extracting-tables/SKILL.md
SKILL.md
Quality
Evals
Security

Extracting tables

Use this when the user wants structured tabular data — financial statements, scientific tables, invoices, spreadsheet-style PDFs. Xberg detects tables via a layout model (RT-DETR v2) and reconstructs cell structure with a configurable table model.

Basic usage

# Markdown tables embedded in the content stream
xberg extract report.pdf --layout --content-format markdown

# Structured JSON output, tables appear under result.tables
xberg extract report.pdf --layout --format json

--layout turns on layout-aware extraction; without it, tables fall back to plain text reflow and you lose cell boundaries.

Output shapes

Two surfaces, picked via --format (CLI shape) and --content-format (content rendering):

  • Markdown tables in content — --content-format markdown. Tables appear inline as | col | col | blocks. Good for LLM ingestion.
  • Structured tables array — --format json. Each entry has cells[][] (rows × cols), markdown (pre-rendered), page_number, bounding_box. Use this when downstream code needs exact cell access. (bounding_box is omitted when no position data is available.)

Both are populated at once when --layout is on. The tables array is always structured; the content stream switches representation.

xberg extract financials.pdf --layout --format json \
  | jq '.result.tables[] | {page: .page_number, rows: (.cells | length)}'

Table models

--layout-table-model picks the reconstruction backend:

ModelBest forNotes
tatrdense complex tables (academic, financial)Default. Heaviest, highest accuracy.
slanet_autodispatches per-table to wired/wirelessGood when table styles are mixed.
slanet_wiredtables with visible bordersFaster than tatr.
slanet_wirelesstables without borders (whitespace-separated)For invoices, simple grids.
slanet_plushybrid wired / wirelessLighter than slanet_auto.
disabledlayout detection only, no table structureUse to skip table model cost.
xberg extract bank-statement.pdf \
  --layout --layout-table-model tatr --content-format markdown

Drop --layout-confidence when the layout model misses tables (default threshold ~0.5):

xberg extract noisy-scan.pdf --layout --layout-confidence 0.3

Spreadsheets

.xlsx, .ods, .csv, .tsv are extracted by dedicated parsers — no layout model needed. Each sheet becomes a markdown table (or structured table) automatically:

xberg extract workbook.xlsx --content-format markdown
xberg extract data.csv --format json

Pass --no-cache=true only when iterating on the same file with different configs.

Config file alternative

# `output_format` in config files equals `--content-format` on the CLI.
output_format = "markdown"

[layout]
confidence_threshold = 0.5
table_model = "tatr"

Then:

xberg extract report.pdf --format json

Programmatic access

From Python, structured tables live on the document in the result envelope (result.results[0].tables):

from xberg import ExtractInput, extract, ExtractionConfig, LayoutDetectionConfig

config = ExtractionConfig(
    layout=LayoutDetectionConfig(table_model="tatr"),
    output_format="markdown",
)
result = await extract(ExtractInput(uri="report.pdf"), config)
for table in result.results[0].tables:
    print(table.markdown)        # rendered markdown
    print(table.cells[0][0])     # cell access

Node.js mirrors this (extract, output.results[0].tables, camelCase fields). See references/python-api.md and references/nodejs-api.md in the sibling xberg skill for full type signatures.

Known limitations

  • Merged cells — reconstructed as repeated values across the spanned region; the merge is not preserved as metadata.
  • Rotated tables — enable --ocr-auto-rotate true for image-based PDFs before extraction.
  • Nested tables — flattened. Detection succeeds; structural nesting is lost.
  • Multi-page tables — each page yields a separate tables[] entry. Stitch by matching column headers if needed.
  • ONNX Runtime required — layout and table models are unavailable in WASM builds and on the Android x86_64 emulator; native targets ship full support.

Common failure modes

  • Empty tables with --layout on — confidence threshold too high or table model mismatched. Drop --layout-confidence to 0.3, try --layout-table-model tatr.
  • Markdown tables look ragged — switch --layout-table-model to slanet_wired for bordered grids or slanet_wireless for invoices.
  • Slow extraction — tatr is heavy. Use slanet_auto or slanet_plus as a default; reach for tatr only when accuracy matters.

See references/cli-reference.md for the full layout flag set and references/advanced-features.md for the layout pipeline internals.

Repository
xberg-io/xberg
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.