SAGEA LogoDocs & API
CookbooksOCR Cookbooks

Extract Tables to CSV

Convert bordered and borderless tables in PDFs and scans into clean CSV files with pandas.

  • Enable bbox=true to get cell positions for every block
  • Sort table blocks into rows and columns by coordinates
  • Export a validated CSV with pandas

Time to complete: ~15 minutes

Prerequisites

  • A SAGEA_API_KEY exported as an environment variable
  • A document with tables in PDF, PNG, JPG, TIFF, or WEBP format, max 100MB, ideally 300 DPI
  • Python 3.9+ with requests and pandas installed
  • Set up document processing
  • ARVA OCR model card

Step 1: Request OCR with bounding boxes

Set bbox=true and output_format="json" so each table block includes coordinates.

curl -X POST https://api.sagea.space/v1/ocr/process \
  -H "Authorization: Bearer $SAGEA_API_KEY" \
  -F model="arva-ocr" \
  -F [email protected] \
  -F output_format="json" \
  -F bbox=true \
  -o tables.json

Response shape:

{"text": "...", "pages": 2, "confidence": 0.992, "blocks": [{"type": "table", "page": 1, "bbox": [x0,y0,x1,y1], "confidence": 0.99, "text": "..."}], "model_used": "arva-ocr"}

Complex pages with tables cost $2.50 per 1000 pages. Accuracy is 99.2% on clean 300 DPI scans.

Step 2: Reconstruct rows and columns

Group table blocks by vertical position, then sort by horizontal position.

curl -X POST https://api.sagea.space/v1/ocr/process \
  -H "Authorization: Bearer $SAGEA_API_KEY" \
  -F model="arva-ocr" \
  -F [email protected] \
  -F output_format="text"

Step 3: Export to CSV with pandas

Normalize column counts and write a clean CSV file.

import pandas as pd
 
grid = [[c["text"].strip() for c in r] for r in rows]
width = max(len(r) for r in grid)
grid = [r + [""] * (width - len(r)) for r in grid]
 
df = pd.DataFrame(grid[1:], columns=grid[0])
print(df.head())
df.to_csv("extracted_table.csv", index=False)
print("wrote extracted_table.csv with shape", df.shape)

Verify

ErrorCauseFix
401 UnauthorizedMissing or invalid API keyExport a valid key as SAGEA_API_KEY and retry
400 unsupported_formatFile type not in PDF, PNG, JPG, TIFF, WEBPConvert the file to PDF or PNG and retry
413 Payload Too LargeFile is over 100MBCompress or split the file, then retry
429 rate_limit_exceededToo many requests at onceBack off with retries and reduce concurrency

What's next

On this page