# HTML Tables to Excel Exporter (`automation-lab/html-table-to-excel-exporter`) Actor

Convert native HTML tables from public webpages into one formatted XLSX workbook with a worksheet per page.

- **URL**: https://apify.com/automation-lab/html-table-to-excel-exporter.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## HTML Tables to Excel Exporter

Convert **HTML tables to Excel** from anonymous public webpages. Supply one or more URLs and receive a formatted XLSX workbook with one worksheet per page, plus structured dataset records for automation.

The Actor preserves table order, expands `rowspan` and `colspan` cells into a rectangular grid, detects headers, converts plain numeric cells to Excel numbers, and can add sum or average formulas. Multiple tables from one page are stacked in their original order on that page's worksheet.

### What does HTML Tables to Excel Exporter do?

The Actor downloads server-rendered HTML and finds native `<table>` elements using a configurable CSS selector. For each page it:

1. validates that the URL resolves to a public HTTP(S) address;
2. follows a bounded number of safe redirects;
3. extracts matching captions, headers, rows, and cells;
4. creates one uniquely named worksheet for that page;
5. writes every matching table in document order;
6. saves the complete workbook as `OUTPUT.xlsx`;
7. returns source metadata and extracted rows in the default dataset.

It processes URLs independently. A failed URL or a page without matching tables produces a bounded status record while other URLs continue.

### Who is it for?

- Analysts turning public statistical tables into reporting workbooks
- Researchers combining tables from several reference pages
- Operations teams replacing repeated copy-and-paste work
- Developers feeding ordered web-table rows into data pipelines
- Finance and reporting teams that need optional sum or average formulas
- Apify users scheduling snapshots of server-rendered public tables

### What data is exported?

| Field | Meaning |
| --- | --- |
| `sourceUrl` | URL supplied in the input |
| `finalUrl` | URL after safe redirects |
| `pageTitle` | Downloaded page's HTML title |
| `status` | `exported`, `no_tables`, or `error` |
| `sheetName` | Unique worksheet name for that page |
| `tableCount` | Number of matching tables exported |
| `rowCount` | Total extracted data rows on the page |
| `columnCount` | Largest table width on the page |
| `tables` | Ordered captions, headers, and cell-row arrays |
| `workbookKey` | Key-value store record name, `OUTPUT.xlsx` |
| `error` | Page-level error or no-table explanation |
| `processedAt` | ISO timestamp for the page result |

The Excel workbook is the primary file deliverable. The dataset provides a JSON-friendly representation of the same extracted tables and a result for every attempted URL.

### How are worksheets organized?

Each successfully exported webpage gets one worksheet. The page title becomes the worksheet name, shortened to Excel's 31-character limit and made unique when titles repeat.

The first rows contain the page title and clickable source URL. Each table then contains:

- its caption, or a deterministic `Table N` label;
- a styled header row;
- ordered data rows;
- an optional formula row;
- a blank separator before the next table.

Column widths are adjusted for readability. Large cell text is capped visually by a practical maximum width but remains in the workbook.

### How much does it cost to export HTML tables to Excel?

The Actor uses pay-per-event pricing:

- **$0.005 start fee** once per run
- **$0.0010688 per successfully exported page** at the Bronze tier
- lower per-page rates at higher platform tiers
- no per-page fee when a webpage is not successfully exported

Example Bronze-tier costs with the current pricing are approximately:

| Successful pages | Estimated Actor charge |
| ---: | ---: |
| 1 | $0.0061 |
| 10 | $0.0157 |
| 25 | $0.0317 |
| 100 | $0.1169 |

Actual platform billing can also include Apify compute and storage according to your plan. The input is capped at 50 pages per run; the 100-page example represents two full runs and includes two start events.

### Getting started

1. Open the Actor in Apify Console.
2. Add one or more public webpage URLs under **Webpage URLs**.
3. Keep `table` as the selector to export all native tables, or enter a narrower selector such as `table.wikitable`.
4. Choose whether numeric columns need sum or average formulas.
5. Adjust page, table, row, or timeout limits if necessary.
6. Click **Start**.
7. Download **Excel workbook** from the run's Output tab.
8. Inspect **Page results** for source mapping, ordered JSON rows, or bounded errors.

The prefilled W3Schools URL returns a real customer table and is suitable for a first run.

### Input parameters

#### `startUrls`

Required array of public HTTP(S) webpage URLs. The Actor supports anonymous pages only. URLs containing credentials and addresses resolving to local or private networks are rejected.

#### `tableSelector`

CSS selector applied to each page. The default `table` matches every native HTML table. Useful examples include:

- `#customers`
- `table.wikitable`
- `main table.data`

The selector must resolve to `<table>` elements. A valid selector with no matching native tables returns `no_tables`.

#### `summaryMode`

- `none`: no summary formula
- `sum`: `SUM` formula below numeric columns
- `average`: `AVERAGE` formula below numeric columns

Formulas are added only to columns containing at least one parsed numeric cell.

#### Processing limits

- `maxPages`: 1–50, default 10
- `maxTablesPerPage`: 1–50, default 20
- `maxRowsPerTable`: 1–5,000, default 2,000
- `requestTimeoutSecs`: 5–120, default 30

These explicit limits keep workbook size, runtime, and failure behavior predictable.

### Input example

```json
{
  "startUrls": [
    { "url": "https://www.w3schools.com/html/html_tables.asp" },
    { "url": "https://en.wikipedia.org/wiki/List_of_chemical_elements" }
  ],
  "tableSelector": "table",
  "summaryMode": "average",
  "maxPages": 2,
  "maxTablesPerPage": 3,
  "maxRowsPerTable": 2000,
  "requestTimeoutSecs": 30
}
```

### Output example

A successful page produces a record like this:

```json
{
  "sourceUrl": "https://www.w3schools.com/html/html_tables.asp",
  "finalUrl": "https://www.w3schools.com/html/html_tables.asp",
  "pageTitle": "HTML Tables",
  "status": "exported",
  "sheetName": "HTML Tables",
  "tableCount": 1,
  "rowCount": 6,
  "columnCount": 3,
  "tables": [
    {
      "tableIndex": 1,
      "caption": null,
      "headers": ["Company", "Contact", "Country"],
      "rows": [["Alfreds Futterkiste", "Maria Anders", "Germany"]],
      "rowCount": 6,
      "columnCount": 3
    }
  ],
  "workbookKey": "OUTPUT.xlsx",
  "error": null,
  "processedAt": "2026-01-15T12:00:00.000Z"
}
```

The actual `rows` array contains every accepted row up to `maxRowsPerTable`.

### Download the XLSX workbook

The run stores the workbook in its default key-value store under:

```text
OUTPUT.xlsx
```

Use the Output tab's **Excel workbook** link or request the record directly:

```text
https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/OUTPUT.xlsx
```

The MIME type is the standard Office Open XML workbook type, so the file opens in Microsoft Excel, LibreOffice Calc, Google Sheets, and compatible tools.

### Schedule recurring table exports

Apify schedules can run the same input hourly, daily, or weekly. A useful recurring workflow is:

1. schedule the Actor with stable source URLs;
2. download each run's `OUTPUT.xlsx` through an integration;
3. store the file with the run timestamp;
4. compare dataset rows or workbooks downstream.

The Actor creates snapshots. It does not itself diff old runs, send change alerts, or merge historical workbooks.

### Use the Actor through the Apify API

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~html-table-to-excel-exporter/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url":"https://www.w3schools.com/html/html_tables.asp"}],
    "tableSelector": "#customers",
    "summaryMode": "none",
    "maxPages": 1
  }'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/html-table-to-excel-exporter').call({
  startUrls: [{ url: 'https://www.w3schools.com/html/html_tables.asp' }],
  tableSelector: '#customers',
  summaryMode: 'none',
  maxPages: 1,
});
console.log(run.defaultKeyValueStoreId, run.defaultDatasetId);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/html-table-to-excel-exporter').call(run_input={
    'startUrls': [{'url': 'https://www.w3schools.com/html/html_tables.asp'}],
    'tableSelector': '#customers',
    'summaryMode': 'none',
    'maxPages': 1,
})
print(run['defaultKeyValueStoreId'], run['defaultDatasetId'])
```

### Connect with webhooks and integrations

After a successful run, connect the dataset or workbook to:

- Google Drive or Dropbox for workbook archiving
- Slack or email for completion notifications
- Make, Zapier, or n8n for downstream workflows
- Python, pandas, or BI tools through the dataset API
- Apify webhooks for event-driven processing

Use the dataset status field to distinguish exported pages from bounded errors before downstream ingestion.

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/html-table-to-excel-exporter"
```

#### Claude Desktop, Cursor, and VS Code setup

Use this equivalent MCP JSON configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/html-table-to-excel-exporter"
    }
  }
}
```

Example prompts:

- “Export the native tables on these three public URLs into one Excel workbook.”
- “Use `table.wikitable` and create average formulas for numeric columns.”
- “Run the HTML table exporter and summarize any URLs that returned no tables.”

### Limits and supported pages

The Actor intentionally supports native, server-rendered HTML tables. It does not render JavaScript-only grids, sign in, solve CAPTCHAs, click pagination controls, or reconstruct visual layouts made from `<div>` elements.

Other limits:

- 5 MB maximum downloaded HTML response per page
- 5 safe redirects per URL
- 50 pages, 50 tables per page, and 5,000 data rows per table
- 100 expanded columns per source cell's `colspan`
- one shared CSS selector for all supplied pages
- one worksheet per successful page, not one worksheet per table

If a site blocks anonymous HTTP access, the URL returns an `error` record and does not stop other pages.

### Tips for reliable exports

- Inspect the page source to confirm the data uses actual `<table>` elements.
- Start with a narrow selector when a page contains navigation or layout tables.
- Use `maxTablesPerPage: 1` when only the primary table matters.
- Keep source pages grouped by a selector they share.
- Use `none` when text that resembles numbers must remain exactly textual.
- Review formulas before using a generated workbook for financial decisions.
- Schedule at a respectful frequency and follow the source website's terms.

### HTML table to CSV, JSON, and Markdown

The default dataset can be downloaded from Apify as JSON, CSV, Excel, XML, or other platform-supported formats. The Actor's custom file deliverable is XLSX.

It does **not** generate a bespoke Markdown file or preserve visual CSS styling from the source page. If your job is specifically HTML table to CSV, the dataset's CSV export may be useful, but nested multi-table records are best consumed as JSON or through `OUTPUT.xlsx`.

### Legality and responsible use

Only process public pages you are authorized to access. Respect website terms, robots policies where applicable, intellectual-property rights, database rights, privacy law, and rate limits. Avoid collecting personal or sensitive information without a lawful purpose.

The Actor blocks local and private network destinations to reduce server-side request forgery risk. It does not bypass authentication or access controls.

### FAQ and troubleshooting

#### Why did I receive `no_tables`?

The page downloaded successfully, but no native `<table>` matched `tableSelector`. Confirm the selector in browser developer tools and check whether the visible grid is rendered later by JavaScript.

#### Why did one URL fail while the run succeeded?

Errors are bounded per URL by design. Check that record's `error` field for HTTP status, timeout, content type, private-address rejection, response-size limit, or redirect details.

#### Why are some numbers still text?

Values containing units, footnotes, dates, ranges, or nonstandard separators remain text to avoid destructive guessing. Plain currencies, percentages, and conventional numbers are converted conservatively.

#### Why does a merged source cell repeat?

`rowspan` and `colspan` are expanded into rectangular workbook cells so row and column positions remain machine-readable. The repeated value represents the source cell's covered grid area.

#### Can it export pages requiring login?

No. The supported scope is anonymous public webpages with server-rendered native HTML tables.

### Related automation-lab Actors

- [CSV & Excel Data Quality Cleaner](https://apify.com/automation-lab/csv-excel-data-quality-cleaner) — normalize, validate, and deduplicate tabular files after export.
- [Dataset Dedup](https://apify.com/automation-lab/dataset-dedup) — remove duplicate records from downstream datasets.

Use this Actor for webpage-table extraction, then apply a related utility only when the downstream workflow requires additional cleanup.

### Changelog

See the Actor's **Changelog** tab for customer-facing release notes.

# Actor input Schema

## `startUrls` (type: `array`):

Public HTTP(S) webpages containing native HTML table elements. Pages requiring login or browser interaction are not supported.

## `tableSelector` (type: `string`):

Optional CSS selector used to choose tables on every page. Keep the default to export all native HTML tables.

## `summaryMode` (type: `string`):

Add sum or average formulas below numeric columns in every exported table, or add no summary row.

## `maxPages` (type: `integer`):

Maximum number of supplied URLs processed in this run. Extra URLs are ignored.

## `maxTablesPerPage` (type: `integer`):

Maximum number of matching tables exported from each webpage.

## `maxRowsPerTable` (type: `integer`):

Maximum data rows exported from each table, excluding detected header rows.

## `requestTimeoutSecs` (type: `integer`):

Seconds allowed for each webpage request before it is recorded as a bounded URL error.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.w3schools.com/html/html_tables.asp"
    }
  ],
  "tableSelector": "table",
  "summaryMode": "none",
  "maxPages": 10,
  "maxTablesPerPage": 20,
  "maxRowsPerTable": 20,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

## `workbook` (type: `string`):

Download the generated XLSX workbook.

## `dataset` (type: `string`):

Dataset containing source metadata, ordered table data, and bounded per-URL errors.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.w3schools.com/html/html_tables.asp"
        }
    ],
    "tableSelector": "table",
    "summaryMode": "none",
    "maxRowsPerTable": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/html-table-to-excel-exporter").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 = {
    "startUrls": [{ "url": "https://www.w3schools.com/html/html_tables.asp" }],
    "tableSelector": "table",
    "summaryMode": "none",
    "maxRowsPerTable": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/html-table-to-excel-exporter").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 '{
  "startUrls": [
    {
      "url": "https://www.w3schools.com/html/html_tables.asp"
    }
  ],
  "tableSelector": "table",
  "summaryMode": "none",
  "maxRowsPerTable": 20
}' |
apify call automation-lab/html-table-to-excel-exporter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/html-table-to-excel-exporter"
        }
    }
}

```

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/UBFi6TWFEUBbcaywO/builds/0OTucARJf8aycLhAZ/openapi.json
