Sheet Generation
Generate CSV, Markdown, and XLSX spreadsheets from a single API call. Send column definitions and row data as structured JSON, and receive the rendered spreadsheet as base64-encoded JSON in the response.
Key Features
- Three Output Formats – Generate CSV, Markdown tables, or XLSX from one unified input structure.
- Positional Rows – Rows are arrays of cells matching column order. No key mapping needed.
- Cell Formatting – 9 format types: text, number, decimal, currency, percentage, date, datetime, time, custom.
- Currency Support – ISO 4217 currency codes with configurable number separator styles.
- Rich Styling – Base styles for headers and body, with per-cell overrides for font, color, alignment, and more (XLSX).
- Custom Fonts – Upload font files (base64-encoded) with weight and style metadata (XLSX).
- Multiple Sheets – XLSX supports multiple worksheets. Markdown renders each sheet as a headed table. CSV supports a single sheet.
- Merged Cells – Combine cells across rows and columns using from/to ranges on individual cells (XLSX).
-
Formulas – Any cell value starting with
=is treated as a formula. Native in XLSX, server-evaluated for CSV and Markdown.
Overview
The Sheet Generation API creates spreadsheets from a JSON definition. You send a format, column definitions, row data, and optional styles, and receive the rendered spreadsheet as base64-encoded JSON.
Endpoint: POST /sheet-generation/v1/generate
Supported output formats: CSV, Markdown, XLSX
Request Format
curl -X POST \
https://api.iterationlayer.com/sheet-generation/v1/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "xlsx",
"sheets": [
{
"name": "Invoices",
"columns": [
{
"name": "Company",
"width": 20
},
{
"name": "Total",
"width": 15
}
],
"rows": [
[
{
"value": "Acme Corp"
},
{
"value": 1500.50,
"format": "currency",
"currency_code": "EUR"
}
]
]
}
]
}'{
"success": true,
"data": {
"buffer": "UEsDBBQAAAAIAA...",
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
}import { IterationLayer } from "iterationlayer";
const client = new IterationLayer({
apiKey: "YOUR_API_KEY",
});
const result = await client.generateSheet({
format: "xlsx",
sheets: [
{
name: "Invoices",
columns: [
{
name: "Company",
width: 20,
},
{
name: "Total",
width: 15,
},
],
rows: [
[
{
value: "Acme Corp",
},
{
value: 1500.50,
format: "currency",
currency_code: "EUR",
},
],
],
},
],
});
// result.data.buffer is base64-encoded
// result.data.mime_type is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"{
"success": true,
"data": {
"buffer": "UEsDBBQAAAAIAA...",
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
}from iterationlayer import IterationLayer
client = IterationLayer(api_key="YOUR_API_KEY")
result = client.generate_sheet(
format="xlsx",
sheets=[
{
"name": "Invoices",
"columns": [
{
"name": "Company",
"width": 20
},
{
"name": "Total",
"width": 15
},
],
"rows": [
[
{
"value": "Acme Corp"
},
{
"value": 1500.50,
"format": "currency",
"currency_code": "EUR",
},
],
],
},
],
)
# result["data"]["buffer"] is base64-encoded
# result["data"]["mime_type"] is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"{
"success": true,
"data": {
"buffer": "UEsDBBQAAAAIAA...",
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
}import il "github.com/iterationlayer/sdk-go"
client := il.NewClient("YOUR_API_KEY")
result, err := client.GenerateSheet(
il.GenerateSheetRequest{
Format: "xlsx",
Sheets: []il.Sheet{
{
Name: "Invoices",
Columns: []il.SheetColumn{
{
Name: "Company",
Width: 20,
},
{
Name: "Total",
Width: 15,
},
},
Rows: [][]il.SheetCell{
{
{
Value: "Acme Corp",
},
{
Value: 1500.50,
Format: "currency",
CurrencyCode: "EUR",
},
},
},
},
},
},
)
// result.Data.Buffer is base64-encoded
// result.Data.MimeType is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"{
"success": true,
"data": {
"buffer": "UEsDBBQAAAAIAA...",
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
}Request Structure
The top-level request has the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
format |
string | Yes |
Output format: csv, markdown, or xlsx |
sheets |
array | Yes | Array of sheet definitions (see below) |
styles |
object | No | Base styles for headers and body cells |
fonts |
array | No | Custom font definitions (base64-encoded font files, XLSX only) |
webhook_url |
string | No | HTTPS URL to receive results asynchronously. If provided, returns 201 immediately. See Webhooks. |
Async Mode
Add a webhook_url parameter to process the request in the background. The API returns 201 Accepted immediately and delivers the result to your webhook URL when processing completes. See Webhooks for payload format and retry behavior.
Sheets
Each sheet definition contains:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | No | Sheet name (default: “Sheet1”) |
columns |
array | Yes | Column definitions (see below) |
rows |
array | No | Positional array of rows. Each row is an array of cells matching column order. |
Columns
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display header name (min 1 character) |
width |
number | No | Column width (XLSX only, must be greater than 0) |
Rows and Cells
Each row is an array of cells, where each cell’s position corresponds to the column at the same index. A cell can be a bare value (string, number, boolean, or null) or a structured object with formatting:
Bare value:
[
"Acme Corp",
1500.50
]Structured cells with format and styles:
[
{
"value": "Acme Corp"
},
{
"value": 1500.50,
"format": "currency",
"currency_code": "EUR",
"styles": {
"is_bold": true,
"font_color": "#008000"
}
}
]You can mix bare values and structured cells in the same row. A row may have fewer cells than columns – trailing cells default to empty.
Cell Fields
| Field | Type | Required | Description |
|---|---|---|---|
value |
any | No |
Cell value. Strings starting with = are treated as formulas. |
format |
string | No |
Cell format (default: text). See Cell Formats below. |
currency_code |
string | No |
ISO 4217 currency code (default: USD). Used with currency format. |
number_style |
string | No |
Number separator style (default: comma_period). Used with number, decimal, and currency formats. |
styles |
object | No | Per-cell style overrides (XLSX only). See Cell Styles below. |
from_col |
integer | No | Start column for merge range (0-based). See Merged Cells. |
to_col |
integer | No | End column for merge range (0-based). See Merged Cells. |
from_row |
integer | No | Start row for merge range (0-based). See Merged Cells. |
to_row |
integer | No | End row for merge range (0-based). See Merged Cells. |
Cell Formats
| Format | Description | CSV/Markdown Example | XLSX Format Code |
|---|---|---|---|
text |
Plain text (default) |
Acme Corp |
– |
number |
Integer with thousands separator |
1,500 |
#,##0 |
decimal |
Two decimal places |
1,500.50 |
#,##0.00 |
currency |
Currency symbol with decimals |
$1,500.50 |
$#,##0.00 |
percentage |
Multiplied by 100 with % |
75.00% |
0.00% |
date |
Date string |
2026-01-15 |
yyyy-mm-dd |
datetime |
Date and time string |
2026-01-15 10:30:00 |
yyyy-mm-dd hh:mm:ss |
time |
Time string |
10:30:00 |
hh:mm:ss |
custom |
Custom Excel format code | (as-is) |
Via number_format in styles |
Cell Styles
Cell-level style overrides (XLSX only, ignored for CSV/Markdown):
| Field | Type | Description |
|---|---|---|
font_family |
string | Font family name |
font_size_in_pt |
number | Font size in points (>= 1) |
is_bold |
boolean | Bold text |
is_italic |
boolean | Italic text |
font_color |
string |
Font color as hex (e.g., #FF0000) |
background_color |
string | Cell background color as hex |
horizontal_alignment |
string |
One of: left, center, right |
number_format |
string |
Custom Excel number format code (used with format: "custom") |
Styles
The top-level styles object defines base styles for header and body cells:
{
"styles": {
"header": {
"font_family": "Helvetica",
"font_size_in_pt": 12,
"is_bold": true,
"background_color": "#4472C4",
"font_color": "#FFFFFF"
},
"body": {
"font_family": "Helvetica",
"font_size_in_pt": 11,
"font_color": "#000000"
}
}
}
Header styles apply to the column header row. Body styles apply to all data cells. Per-cell styles overrides take precedence.
Custom Fonts
Upload custom fonts as base64-encoded buffers (XLSX only). Each font definition requires a name, weight, style, and the font file data.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Font family name (min 1 character) |
weight |
string | Yes |
One of: thin, extralight, light, regular, medium, semibold, bold, extrabold, black |
style |
string | Yes |
One of: normal, italic |
buffer |
string | Yes | Base64-encoded font file (TTF, OTF, WOFF, or WOFF2) |
Merged Cells
Merge a range of cells by setting from_col, to_col, from_row, and to_row on the cell itself (XLSX only). The merge range is 0-based and inclusive. The cell’s value is displayed in the merged area.
{
"format": "xlsx",
"sheets": [
{
"name": "Report",
"columns": [
{
"name": "A",
"width": 20
},
{
"name": "B",
"width": 20
},
{
"name": "C",
"width": 20
}
],
"rows": [
[
{
"value": "Summary",
"from_col": 0,
"to_col": 2,
"from_row": 0,
"to_row": 0,
"styles": {
"is_bold": true,
"horizontal_alignment": "center"
}
}
],
[
"Detail A",
"Detail B",
"Detail C"
]
]
}
]
}In this example, the first row’s single cell spans all three columns (columns 0 through 2). The second row has three separate cells.
Formulas
Any cell whose value is a string starting with = is treated as a formula. No separate formula array is needed – formulas are just cells.
{
"format": "xlsx",
"sheets": [
{
"name": "Totals",
"columns": [
{
"name": "Item",
"width": 20
},
{
"name": "Amount",
"width": 15
}
],
"rows": [
[
"Widget A",
{
"value": 100.00,
"format": "currency"
}
],
[
"Widget B",
{
"value": 250.00,
"format": "currency"
}
],
[
{
"value": "Total",
"styles": {
"is_bold": true
}
},
{
"value": "=SUM(B2:B3)",
"format": "currency"
}
]
]
}
]
}For XLSX, formulas are written natively and evaluated by Excel. For CSV and Markdown, simple aggregation formulas (SUM, AVERAGE, COUNT, MIN, MAX) are evaluated server-side. Unsupported formulas are written as raw strings.
Multiple Sheets
XLSX and Markdown support multiple sheets. CSV supports only one sheet.
XLSX: Each sheet becomes a separate worksheet in the workbook.
Markdown: Each sheet is rendered as a ## Sheet Name heading followed by a markdown table:
## Invoices
| Company | Total |
| --- | --- |
| Acme Corp | EUR 1,500.50 |
## Payments
| Date | Amount |
| --- | --- |
| 2026-01-15 | $500.00 |CSV: If more than one sheet is provided, the API returns a 400 error.
Currency Codes
The currency_code field accepts any ISO 4217 currency code. It is used with the currency format to determine the currency symbol displayed in the cell. Defaults to USD if not specified.
[
{
"value": 1500.50,
"format": "currency",
"currency_code": "EUR"
},
{
"value": 2400.00,
"format": "currency",
"currency_code": "JPY"
},
{
"value": 899.99,
"format": "currency",
"currency_code": "GBP"
}
]Number Styles
The number_style field controls the thousands and decimal separators for number, decimal, and currency formats. Defaults to comma_period if not specified.
| Style | Thousands Separator | Decimal Separator | Example |
|---|---|---|---|
comma_period |
, |
. |
1,500.50 |
period_comma |
. |
, |
1.500,50 |
space_comma |
|
, |
1 500,50 |
space_period |
|
. |
1 500.50 |
[
{
"value": 1500.50,
"format": "decimal",
"number_style": "period_comma"
}
]Feature Comparison by Format
| Feature | XLSX | CSV | Markdown |
|---|---|---|---|
| Multiple Sheets | ✅ | ❌ | ✅ |
| Cell Formatting | ✅ | ❌ | ❌ |
| Custom Fonts | ✅ | ❌ | ❌ |
| Merged Cells | ✅ | ❌ | ❌ |
| Formulas | ✅ (native) | ✅ (server-evaluated) | ✅ (server-evaluated) |
| Number Formats | ✅ (native) | ✅ (string rendering) | ✅ (string rendering) |
| Currency Codes | ✅ | ✅ | ✅ |
| Number Styles | ✅ | ✅ | ✅ |
| Column Widths | ✅ | ❌ | ❌ |
| Header/Body Styles | ✅ | ❌ | ❌ |
Recipes
For complete, runnable examples see the Recipes page.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid request (validation errors, missing required fields, CSV with multiple sheets) |
| 401 | Missing or invalid API key |
| 422 | Processing error (spreadsheet rendering failure) |
| 429 | Rate limit exceeded |