# CSV / XLSX Converter: CSV, TSV, JSON, NDJSON (`ucchiii/csv-xlsx-converter`) Actor

Convert CSV, TSV, XLSX, JSON and NDJSON files from URLs or Apify datasets. Auto-detects encoding (UTF-8, Shift_JIS, cp1252), flattens nested JSON, selects and renames columns. Empty input = free demo. $0.05 per 1,000 rows.

- **URL**: https://apify.com/ucchiii/csv-xlsx-converter.md
- **Developed by:** [Actor Factory](https://apify.com/ucchiii) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.00 / 1,000 1,000 rows converteds

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/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

## CSV / XLSX Converter — CSV, TSV, Excel, JSON and NDJSON in any direction

**For anyone who gets a file in the wrong format: a CSV that Excel shows as garbage, an Excel sheet a script cannot read, a JSON export you need as a table, or a scraper dataset that has to become a spreadsheet.** Give this Actor file URLs (or an Apify dataset), pick the output format, and get **the converted file plus a public download link**, with encoding, delimiter and nested JSON handled for you.
**$0.05 per 1,000 rows converted** (rounded up per file). Failed files and the demo are free. No scraping, no API keys.

### What it does

- **Converts between CSV, TSV, XLSX, JSON and NDJSON**: any of them in, any of them out
- **Detects the input format** from the file extension, content type or content; you can also set it
- **Detects the text encoding**: UTF-8 (with or without BOM), Shift_JIS and Windows-1252 (cp1252); or choose one. Output is always UTF-8
- **Detects the delimiter** (comma, semicolon, tab, pipe) or lets you set it; choose the CSV output delimiter and an optional UTF-8 BOM so Excel opens non-English text correctly
- **Reads a chosen XLSX sheet** by name (first sheet by default) and tells you the sheet names if yours is missing
- **Flattens nested JSON** into dot-key columns (`address.city`); arrays stay as JSON text or are joined (`a; b; c`)
- **Selects and renames columns** (selecting `address` keeps every column under it)
- **Turns CSV numbers into real numbers** (so XLSX and JSON get numbers, not text); ZIP codes with leading zeros stay text
- **Safe by default**: text starting with `=`, `+`, `-`, `@` is stored as plain text in XLSX, never as a formula
- Several files per run; each file gets its own output file and one summary row

### Input example

```json
{
  "fileUrls": ["https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"],
  "outputFormat": "xlsx",
  "select": ["species", "sepal_length", "petal_length"],
  "rename": {"sepal_length": "sepalLength"}
}
```

To convert an Apify dataset instead, use `datasetIds` (pick it from your runs). **Empty input runs a free demo** on a built-in sample CSV (not charged, rows carry `_demo: true`).

### Output

- **Dataset**: one row per source file with `status`, `inputFormat`, `outputFormat`, `encoding`, `rows`, `columns`, `columnNames`, `outputKey`, `outputUrl` and, for failures, a plain-language `error`.
- **Key-value store**: the converted file, saved under `outputKey` (for example `iris.xlsx`). `outputUrl` is Apify's signed public link, so you can share the file without sharing your token.
- **STATS** record: files converted and failed, rows converted and the number of 1,000-row units charged.

```json
{
  "source": "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv",
  "status": "ok", "inputFormat": "csv", "encoding": "utf-8", "outputFormat": "xlsx",
  "rows": 150, "columns": 3, "columnNames": ["species", "sepalLength", "petal_length"],
  "outputKey": "iris.xlsx", "outputBytes": 7312, "chargedUnits": 1,
  "outputUrl": "https://api.apify.com/v2/key-value-stores/…/records/iris.xlsx?signature=…"
}
```

### Limits (cannot be raised by input)

- 50 MB per source file; 50 files or datasets per run
- 500,000 data rows per file or dataset, 1,000 columns, 100 MB per output file. A file over a limit **fails with a clear message and is not charged**; rows are never silently cut
- XLSX input: `.xlsx` / `.xlsm` only (not old `.xls`, not password-protected). Formulas are read as their last saved values
- Source URLs must be public `http` or `https` links. Addresses on internal networks (localhost, private ranges, cloud metadata) are blocked, also after redirects
- Empty rows are skipped; the first non-empty row is the header (duplicate or empty header names become `name_2`, `column_3`)

### Pricing

Pay per event: **$0.05 per 1,000 rows converted** (event `rows-1000`). Rows are counted per file and rounded up: a 2,500-row file costs 3 units ($0.15), a 150-row file 1 unit ($0.05). A file that fails (download error, bad format, over a limit) is not charged. Set a maximum charge per run to cap spend; the Actor stops cleanly before the next file when it is reached.

### Use cases

- Re-save a Shift_JIS or Windows-1252 CSV as UTF-8 so Excel, Sheets and databases show the text correctly
- Turn a CSV export into an XLSX workbook with real numbers, or an XLSX sheet into NDJSON for a script
- Convert a nested JSON API export into a flat table for a spreadsheet
- Hand a scraper dataset to a colleague as an Excel file with a download link

### FAQ

**Which encoding does `auto` choose?** UTF-8 first. If that fails, Shift_JIS when the text contains Japanese kana, otherwise Windows-1252. The detected encoding is in the result row; set `encoding` if it guesses wrong.
**Why is my ID still text?** Numbers with leading zeros, more than 15 digits or exponents stay text on purpose. Turn `inferTypes` off to keep every CSV value as text.
**Excel shows broken characters in my CSV.** Turn on `csvBom`.
**Does it change my source?** No. It only reads the file or dataset and writes a new file.
**Is the file link private?** Anyone holding the signed link can download that file; it gives no access to anything else in your account.

### More tools from the same developer

- [Dataset Transform](https://apify.com/ucchiii/dataset-transform) — flatten, filter, rename and convert any Apify dataset, export CSV / JSON / JSONL with a link
- [Dataset Merge & Dedup](https://apify.com/ucchiii/dataset-dedup-merge) — merge Apify datasets and remove duplicates by the fields you choose
- [Google Sheets Import](https://apify.com/ucchiii/google-sheets-import) — read Google Sheet rows into a dataset as JSON/CSV, public link or your service account
- [Google Sheets Export](https://apify.com/ucchiii/google-sheets-export) — export an Apify dataset to Google Sheets
- [PDF Extractor](https://apify.com/ucchiii/pdf-extractor) — PDF to text, tables and metadata from public PDF URLs, page by page

# Actor input Schema

## `fileUrls` (type: `array`):

Public http(s) links to CSV, TSV, XLSX, JSON or NDJSON files, one per entry (up to 50 files and 50 MB each). Links to internal networks are blocked. Leave this AND 'Apify datasets' empty to run a free demo on a built-in sample (not charged).

## `datasetIds` (type: `array`):

Dataset IDs (the 'defaultDatasetId' of a finished run) to convert to a file. Each dataset becomes one output file. You can paste a dataset URL from Apify Console too. Up to 500,000 rows per dataset.

## `outputFormat` (type: `string`):

Format of the converted file saved to the key-value store. Default: xlsx.

## `inputFormat` (type: `string`):

Format of the source files. 'auto' uses the file extension, the content type and the file content. Ignored for Apify datasets. Default: auto.

## `inputDelimiter` (type: `string`):

Column separator of CSV-like source files. 'auto' picks the most frequent separator in the header line. Default: auto.

## `encoding` (type: `string`):

Character encoding of CSV, TSV and JSON source files. 'auto' tries UTF-8 (with or without BOM), then Shift_JIS (only when it finds Japanese kana), then Windows-1252. Output is always UTF-8. Default: auto.

## `sheetName` (type: `string`):

Name of the worksheet to read from an XLSX source (case-insensitive). Empty = the first sheet. Also used as the sheet name of an XLSX output. A missing sheet fails with the list of available names.

## `select` (type: `array`):

Columns to output, in this order. For flattened JSON use dot names such as 'address.city'; a parent name such as 'address' keeps everything under it. Empty = all columns.

## `rename` (type: `object`):

Map of current column name to new name, e.g. {"sepal_length": "sepalLength"}. Use names as they are after flattening and before renaming. Two columns cannot share a new name.

## `flatten` (type: `boolean`):

For JSON, NDJSON and dataset sources: turn nested objects into columns with dot keys (address.city). Turn off to keep nested values as JSON text in one cell (CSV, TSV, XLSX) or as nested JSON (JSON, NDJSON). Default: on.

## `flattenSeparator` (type: `string`):

Text that joins nested key names, e.g. '.' gives address.city and '\_' gives address_city. Max 5 characters. Default: '.'.

## `arrayMode` (type: `string`):

How arrays inside nested JSON become cells. 'join' only joins numbers and text; arrays of objects stay as JSON text. Default: json.

## `outputDelimiter` (type: `string`):

Column separator when the output format is CSV. Default: comma.

## `csvBom` (type: `boolean`):

Adds a byte-order mark to CSV and TSV output so Excel opens non-English text (for example Japanese) correctly. Leave off for pandas, databases and most code.

## `csvEscapeFormulas` (type: `boolean`):

Prefix CSV and TSV text cells that start with =, +, @ (or - followed by text) with an apostrophe so Excel never runs them. XLSX output always stores such cells as plain text.

## `inferTypes` (type: `boolean`):

Turn plain numbers in CSV and TSV sources into real numbers (important for XLSX and JSON output). Values with leading zeros (ZIP codes), more than 15 digits or exponents stay text. Default: on.

## `maxRows` (type: `integer`):

A file or dataset with more data rows than this fails with a clear message and is not charged (rows are never silently cut). Default and maximum 500,000.

## `fileName` (type: `string`):

File name without extension for the output. With several sources a number is added (name-2). Only letters, digits, dot, dash and underscore are kept. Empty = derived from each source name.

## Actor input object example

```json
{
  "fileUrls": [
    "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"
  ],
  "outputFormat": "xlsx",
  "inputFormat": "auto",
  "inputDelimiter": "auto",
  "encoding": "auto",
  "flatten": true,
  "flattenSeparator": ".",
  "arrayMode": "json",
  "outputDelimiter": ",",
  "csvBom": false,
  "csvEscapeFormulas": false,
  "inferTypes": true,
  "maxRows": 500000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per source file: status, rows, columns, the output file key and its public URL (outputUrl), or the error. Download as CSV, JSON, Excel and more.

## `stats` (type: `string`):

Record STATS: files converted and failed, rows converted and the number of 1,000-row units charged.

## `files` (type: `string`):

The key-value store that holds the converted output files.

# 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 = {
    "fileUrls": [
        "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ucchiii/csv-xlsx-converter").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 = { "fileUrls": ["https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"] }

# Run the Actor and wait for it to finish
run = client.actor("ucchiii/csv-xlsx-converter").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 '{
  "fileUrls": [
    "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"
  ]
}' |
apify call ucchiii/csv-xlsx-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ucchiii/csv-xlsx-converter"
        }
    }
}
```

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/MWnF5WSV1xehWABVd/builds/sGG51QPzJdCZ2crtK/openapi.json
