# Spreadsheet

Read or write an .xlsx spreadsheet.

## Do things in Spreadsheet

Add a **Spreadsheet** step and choose an **Operation**. Choose the row to see the fields of each.

- [Spreadsheet](https://docs.gorunner.io/apps/spreadsheet#fields-f-convert): Read xlsx → rows · Write rows → xlsx

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

**What changed in version 2?**

New steps use version 2.0.0. A step made before keeps 1.0.0 and works as it always has. The step’s panel shows its version at the top right. On an older step it reads **v1.0.0 · 2.0.0 available**: press it to choose the version.

In 2.0.0: **Typed Cell Values** reads the value a cell holds (`1234.5`, not `"1,234.50"`) and gives dates as `2025-12-09`. Version 1.0.0 reads the text the cell shows.

## Limits

- A read takes an `.xlsx` only. An older `.xls`, a text file such as a CSV, or any other file that isn’t an `.xlsx` fails the step and says so. So does a damaged workbook.
- A workbook that unzips to more than 512 MiB fails the step, and so does one that could take more than 1,792 MiB of memory to read.
- A read holds at most 6 million cells, counting the empty ones between values. With **Typed Cell Values**, at most 1 million, or about 700,000 cells with values.
- A result over what one step may pass on, 16 MB unless an installation changes it, fails the step before it is built. Use **Max Rows** to read part of the sheet.
- Reads share a worker’s memory, so a large one can wait for others. It waits only as long as the step’s time limit.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, Spreadsheet is `pieceId: "spreadsheet"` with `actionId: "convert"`, set by `operation`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

It computes from its inputs only (`pure`). See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### Spreadsheet › Spreadsheet

Read an .xlsx into rows, or write rows to an .xlsx file.

### Read xlsx → rows

- **Spreadsheet File · Required**: Upload an .xlsx, or switch to an expression to use one from a previous step (such as {{steps.http.result}}).
- **Sheet Name · Optional**: Name of the tab to read (such as Sheet1). Leave blank to read the first tab.
- **First row is a header · Optional**: Turn on if the top row holds column names, so each row becomes labeled values instead of a plain list. On by default.
- **Typed Cell Values · Optional**: Return numbers and booleans as their real types (such as 42 not "42") instead of the displayed text. Off by default.
- **Start Row · Optional**: 1-based row to begin reading from (skips the rows above it). Leave blank/1 to read from the top. When a header is on, it is taken from this row.
- **Max Rows · Optional**: Maximum number of data rows to return. Leave blank or 0 for all.

### Write rows → xlsx

- **Rows · Required**: An array of row objects (keyed by column) to write. You can also pass a reading step's whole result (such as {{steps.read_sheet.result}}), and its column order is then reused.
- **Sheet Name · Optional**: Name to give the tab in the new spreadsheet (such as Sheet1). Default: Sheet1.
- **Output Filename · Optional**: Name for the spreadsheet file that gets created (such as report.xlsx). Default: spreadsheet.xlsx.
- **Column Order · Optional**: Optional list of column names in the order you want them, such as ["name","score","city"] or {{steps.parse_csv.headers}}. Columns you don't list are added after the ones you do, so nothing is dropped. Leave this blank and columns come out in alphabetical order. A row object has no order of its own to preserve, so this field is the only way to choose one.

Source: https://docs.gorunner.io/apps/spreadsheet
