# Image Table to Excel & CSV (`adhistory/image-tables-to-excel`) Actor

Turn a screenshot, photo or scan of a table into rows, a CSV and an Excel file. OCR runs inside the Actor, no API key needed. Billed only for tables delivered: $2 per 1,000.

- **URL**: https://apify.com/adhistory/image-tables-to-excel.md
- **Developed by:** [Brandon Ob](https://apify.com/adhistory) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 tables

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Image Table to Excel & CSV: turn a screenshot or photo of a table into rows

This image to Excel converter turns a picture of a table (a screenshot, a phone photo of a printed page, a scanned sheet) into rows you can export, plus an Excel file and a CSV file per picture. OCR (text recognition) runs inside the Actor, so there is no API key to set up and no image is sent to another service. You are charged per table delivered, never for a picture that failed or had no table.

### What does Image Table to Excel & CSV do?

- Reads **pictures of tables** from public links: PNG, JPG, WEBP, BMP or TIFF.
- Runs **OCR inside the Actor** and rebuilds the rows and columns from the layout.
- Returns each table as a dataset item with every row keyed by the column header.
- Writes **one Excel file (frozen header row) and one CSV file per picture**, each with a download link.
- Reports an **OCR confidence** score per table, and returns stray text above or below the table (a title, a footnote) in `textOutsideTable`.
- Lets you tune the column gap and a minimum confidence when a layout is tricky.
- Includes a **built-in demo table** (input `sample`) so you can see the output before using your own pictures.

### Use cases

- **Analysts:** turn a chart's data table or a dashboard screenshot into a spreadsheet you can work with.
- **Operations and admin teams:** digitize printed price lists, schedules or inventory sheets photographed on a phone.
- **Researchers and students:** capture tables from slides, posters or book pages as rows.
- **Finance and bookkeeping:** convert screenshots of statements or reports that cannot be exported.
- **Automation builders:** add an "image table to rows" step after a screenshot or file upload, and send the rows on to Google Sheets.

### How to use it

1. Open the Actor in Apify Console. The default input, `sample`, runs the built-in demo table; replace it with your image links, one per line. Each file must open in a browser without a login.
2. Click **Start**.
3. Open the **Tables** view, or use the `excelUrl` column for one spreadsheet per picture. Check the `confidence` value on your first run.
4. If columns come back merged or split, adjust **Column gap** and run again.
5. To process new pictures regularly, save the input as a task and schedule it, or call the Actor from the API.

### Input

| Field | What it does |
|---|---|
| `imageUrls` | Direct links to pictures of tables, one per line. `sample` runs the demo table. |
| `firstRowIsHeader` | Use the first row as column names (on by default); off gives Column 1, Column 2, … |
| `columnGap` | How wide the empty space between columns must be, in text heights (default 0.6). Raise it if a column splits, lower it if two columns merge. |
| `minConfidence` | Ignore text the OCR is less sure of than this, 0 to 1 (default 0.5). |
| `minRows` | Ignore pictures with fewer data rows than this (default 2). |
| `maxItems` | Stop after this many tables (default 100). |

Example input:

```json
{
  "imageUrls": ["sample"],
  "firstRowIsHeader": true,
  "columnGap": "0.6",
  "minConfidence": "0.5",
  "minRows": 2
}
```

### Output

One dataset item per picture. Real output from the default run (built-in demo table, 4 rows, OCR confidence 0.99), shortened:

```json
{
  "imageUrl": "built-in sample table",
  "columns": ["Item", "Qty", "Unit price", "Total"],
  "rowCount": 4,
  "rows": [
    {"Item": "Standing desk", "Qty": "2", "Unit price": "349.00", "Total": "698.00"},
    {"Item": "Monitor arm", "Qty": "4", "Unit price": "45.50", "Total": "182.00"},
    {"Item": "USB-C dock", "Qty": "3", "Unit price": "129.99", "Total": "389.97"}
  ],
  "textOutsideTable": [],
  "confidence": 0.99,
  "csvUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/01-sample.csv",
  "excelUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/01-sample.xlsx",
  "extractedAt": "2026-10-26T11:00:36+00:00"
}
```

The key-value store record `SUMMARY` lists pictures that could not be read and pictures where no table was found. The dataset can be downloaded as JSON, CSV, Excel, XML or HTML, or read through the API.

### Pricing

Pay per event: **$2.00 per 1,000 tables** delivered, plus a $0.00005 charge per Actor start. One picture with one table is one event, whatever its size. Pictures that fail or contain no table are not charged. You can set a maximum cost per run.

Example: 100 screenshots of tables cost about **$0.20**.

### Integrations and API

Run it and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/adhistory~image-tables-to-excel/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"imageUrls": ["https://example.com/table.png"]}'
```

Python, with the `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("adhistory/image-tables-to-excel").call(run_input={
    "imageUrls": ["https://example.com/table.png"],
})
for table in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(table["rowCount"], table["confidence"], table["excelUrl"])
```

Like every Apify Actor, it also works with Make, Zapier and n8n, with webhooks and schedules, and as a tool for AI agents through the Apify MCP server.

### FAQ

**How accurate is it?** Best on sharp, straight, printed text with clear spaces between columns. Skewed photos, handwriting, very small text and low contrast give wrong or missing characters. Check the `confidence` value and spot-check your first run.

**Can one picture hold several tables?** One table per picture is supported. Two tables side by side or stacked come back as one, so crop them first.

**My table came back merged or in pieces.** Use a larger or sharper picture, then try a different `columnGap` (0.3 to 1.5).

**Which languages work?** Text recognition is tuned for Latin script and Chinese; other scripts are not supported.

**Are there size limits?** Files up to 20 MB from public links. Pictures are scaled down to 4,000 pixels on the longest side.

**Is my image sent to a third-party OCR service?** No. OCR runs inside the Actor's own container.

**Do you read PDFs?** Not this Actor. For PDFs with real text, use [PDF Table to Excel & CSV](https://apify.com/adhistory/pdf-tables-to-excel).

### Related tools

- [PDF Table to Excel & CSV](https://apify.com/adhistory/pdf-tables-to-excel): tables from text-based PDFs.
- [Invoice PDF to Excel & CSV](https://apify.com/adhistory/invoice-pdf-to-excel): invoice data and line items from PDFs.
- [Website Screenshot API](https://apify.com/adhistory/website-screenshot-api): capture a web page before extracting its table.
- [Google Sheets Export & Import](https://apify.com/adhistory/google-sheets-export-actor): send the rows straight into a Google Sheet.

Found a bug or need a feature? Open an issue on the Issues tab — I usually reply within a day.

# Actor input Schema

## `imageUrls` (type: `array`):

Direct links to PNG, JPG, WEBP, BMP or TIFF pictures of tables, one per line. The file must open without a login. The word sample runs the built-in demo table.

## `firstRowIsHeader` (type: `boolean`):

Use the first row as column names. Turn off to get Column 1, Column 2 and so on.

## `columnGap` (type: `string`):

How wide the empty space between columns must be, in text heights. Raise it if one column comes back split in two, lower it if two columns come back merged.

## `minConfidence` (type: `string`):

Ignore text the OCR is less sure of than this (0 to 1).

## `minRows` (type: `integer`):

Ignore pictures with fewer data rows than this.

## `maxItems` (type: `integer`):

Stop after this many tables. You are charged per table delivered.

## Actor input object example

```json
{
  "imageUrls": [
    "sample"
  ],
  "firstRowIsHeader": true,
  "columnGap": "0.6",
  "minConfidence": "0.5",
  "minRows": 2,
  "maxItems": 100
}
```

# Actor output Schema

## `tables` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        "sample"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("adhistory/image-tables-to-excel").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "imageUrls": ["sample"] }

# Run the Actor and wait for it to finish
run = client.actor("adhistory/image-tables-to-excel").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    "sample"
  ]
}' |
apify call adhistory/image-tables-to-excel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,adhistory/image-tables-to-excel"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YbRty4eItAhvRHd23/builds/ynqhD1rDiPhnbNHxe/openapi.json
