Extraction checks / Recorded October 14, 2026
What came out
of five PDFs.
The simple table came back intact. A borderless header lost a word. A rotated table came back in the wrong order. Here are the exact files, settings and outputs.
5 invented PDFs6 case + setting combinations1 extraction libraryNo OCR tested
These are tiny, synthetic examples of pdfplumber 0.11.9. They are not an accuracy estimate, a comparison of tools or representative business documents. Each result applies to the shown file and configuration.
Two different questions.
Will a tool fit my setup?
The matcher uses reviewed documentation to check operating system, setup, privacy and licensing constraints. Its rankings are documented workflow fit, not measured extraction quality.
What did this file produce?
The checks below actually executed pdfplumber on five invented PDFs. They do not validate every compatibility profile, the other four tools, or the matcher's rankings.
Exact match means every cell and its position matched the expected logical grid. Two settings were tested on the same borderless file, so six observations do not mean six independent fixtures.
Case 01Exact match
A simple ruled table
All 12 cells, including the header, matched the expected 4 × 3 grid in the raw output.
Compare expected and extracted cells
Whitespace/blank-row cleanup did not change this output.
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "lines",
"horizontal_strategy": "lines"
},
"observed_pages": [
{
"page": 1,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 53,
"image_count": 0,
"tables": [
[
[
"Item",
"Quantity",
"Unit price"
],
[
"Alpha",
"2",
"10.00"
],
[
"Beta",
"5",
"3.25"
],
[
"Gamma",
"1",
"99.00"
]
]
]
}
],
"raw_exact_match": true,
"normalized_exact_match": true
}
Case 02Exact pages; joining assumed
A table over two pages
Both 4 × 3 page tables matched. Separate example code joined them into the expected 7 × 3 grid, removing an exactly repeated header. It assumes the tables belong together; pdfplumber did not infer continuation.
Compare expected and extracted cells
Whitespace/blank-row cleanup did not change this output.
Separate, explicitly assumed page joining
Concatenate tables in page order, removing a repeated first row only when it exactly equals the first table's header. Assumes these tables belong together; does not infer continuation or handle missing/split rows.
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "lines",
"horizontal_strategy": "lines"
},
"observed_pages": [
{
"page": 1,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 53,
"image_count": 0,
"tables": [
[
[
"Item",
"Quantity",
"Unit price"
],
[
"Alpha",
"2",
"10.00"
],
[
"Beta",
"5",
"3.25"
],
[
"Gamma",
"1",
"99.00"
]
]
]
},
{
"page": 2,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 54,
"image_count": 0,
"tables": [
[
[
"Item",
"Quantity",
"Unit price"
],
[
"Delta",
"4",
"8.50"
],
[
"Epsilon",
"3",
"12.00"
],
[
"Zeta",
"6",
"5.75"
]
]
]
}
],
"raw_exact_match": true,
"normalized_exact_match": true
}
Case 03No table detected
No borders, line-based settings
The line-based configuration returned no table from this borderless fixture. This observation is about this file and these settings.
Compare expected and extracted cells
Actual raw output
Page 1: no tables returned
Whitespace/blank-row cleanup did not change this output.
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "lines",
"horizontal_strategy": "lines"
},
"observed_pages": [
{
"page": 1,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 53,
"image_count": 0,
"tables": []
}
],
"raw_exact_match": false,
"normalized_exact_match": false
}
Case 04A header word is missing
Same file, text-based settings
One table was detected, but “Unit price” became “Unit”. Removing blank rows restored the expected shape, not the missing word. A table count alone would hide the error.
Compare expected and extracted cells
After the documented cleanup
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "text",
"horizontal_strategy": "text"
},
"observed_pages": [
{
"page": 1,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 53,
"image_count": 0,
"tables": [
[
[
"Item",
"Quantity",
"Unit"
],
[
"",
"",
""
],
[
"Alpha",
"2",
"10.00"
],
[
"",
"",
""
],
[
"Beta",
"5",
"3.25"
],
[
"",
"",
""
],
[
"Gamma",
"1",
"99.00"
]
]
]
}
],
"raw_exact_match": false,
"normalized_exact_match": false
}
Case 05Wrong logical orientation
A page rotated 90 degrees
The output was 3 rows × 4 columns, transposed/reversed relative to the expected 4 × 3 grid. The header also contained a line break. No rotation correction or cell reordering was applied.
Compare expected and extracted cells
Whitespace/blank-row cleanup did not change this output.
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "lines",
"horizontal_strategy": "lines"
},
"observed_pages": [
{
"page": 1,
"rotation": 90,
"width": 792,
"height": 612,
"character_count": 53,
"image_count": 0,
"tables": [
[
[
"Gamma",
"Beta",
"Alpha",
"Item"
],
[
"1",
"5",
"2",
"Quantity"
],
[
"99.00",
"3.25",
"10.00",
"Unit\nprice"
]
]
]
}
],
"raw_exact_match": false,
"normalized_exact_match": false
}
Case 06Expected negative control
An image-only copy
The page contained one image, zero extracted characters and zero tables. This is the expected result without OCR. No OCR pipeline was tested.
Compare expected and extracted cells
Actual raw output
Page 1: no tables returned
Whitespace/blank-row cleanup did not change this output.
Raw settings and observations (JSON)
{
"settings": {
"vertical_strategy": "lines",
"horizontal_strategy": "lines"
},
"observed_pages": [
{
"page": 1,
"rotation": 0,
"width": 612,
"height": 792,
"character_count": 0,
"image_count": 1,
"tables": []
}
],
"raw_exact_match": false,
"normalized_exact_match": false
}
Inspect it / Run it yourself
Nothing to take on faith.
Download the evidence ZIP and open the proof-of-use-evidence folder. The recorded outputs, expected cells and SHA-256 hashes are included. No customer files are needed.
1. Check the downloaded record
Uses Python's standard library. Confirms the saved observations and fixture hashes; it does not rerun extraction.
python3 verify.py
2. Rerun the experiment
Package installation uses the registry. The experiment itself stays local. Rerunning replaces the extracted folder's generated fixtures and result, so keep a copy to compare.
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python run.py
.venv/bin/python verify.py
On Windows, use .venv\Scripts\python.exe. See the full reproduction guide.
The recorded environment
- Executed UTC
- 2026-10-14T11:45:45+00:00
- Runtime
- Python 3.12.14, Linux x86_64
- Packages
- pdfplumber 0.11.9 · reportlab 4.4.9 · pypdfium2 5.13.0
- Extractor
- pdfplumber.Page.extract_tables
- Settings
- vertical_strategy / horizontal_strategy:
lines / lines or text / text
Direct and key transitive packages are pinned, not a full platform lock. ReportLab generates fixtures; PDFium renders them. Only pdfplumber extracts tables.
A passing verifier means the recorded behavior is consistent, including the known failures. It does not mean all extraction cases succeeded. Compare changed outcomes before updating expectations.
Download individual PDFs and inspect their hashes
- digital-ruled.pdf2,194 bytes · SHA-256
c8f832ec40ef5d7b3b77c222cd782f2f7f258e632664aed623cbe66b28889f40 - multipage-ruled.pdf3,292 bytes · SHA-256
07027d40f391b07dd88939b44bc4f8d1d7a0272d2c77b8d85d90b999e982e4f9 - borderless-regular.pdf1,985 bytes · SHA-256
7018b0a5f5be6177bb5c4242cbaec90044cf6255635139e7b5ce18a3f3f0f5b7 - rotated-90.pdf2,195 bytes · SHA-256
62876cd904ef60170b438073b62fd2b0dc758270938e939f55f329c9e6416a42 - image-only.pdf25,125 bytes · SHA-256
b8524f856ae512604d80ce8426966ac0664129cf15cb129ee20084396229c2ec
What these checks leave open.
These are regular English text and simple numeric cells, with one tiny fixture per layout. No OCR pipeline or model was installed or run. Camelot, Tabula, Docling and PaddleOCR were not executed. Speed, memory, security and production robustness were not measured.
No cropping, fixture-specific extraction coordinates, substitutions from expected cells or corrective row/column reordering were used. Normalization only strips cell-edge whitespace and discards wholly blank rows; raw outputs remain visible. Page joining is separate example code with an explicit continuation assumption.
All text and numbers are invented. The fixtures contain no customer documents or personal data. The reproduction guide documents provenance and scope. These measured examples leave the matcher's dataset, ranking and documentation-based labels unchanged.
Try the decision side.
A documented fit, a tool ruled out, and no qualified match. Three short examples show how the matcher handles each.
Try three examples ↗