Batch from a spreadsheet
The Batch from spreadsheet dialog turns every row of a CSV or Excel file into one document: one certificate per participant, one letter per customer, one badge per guest. You map the sheet's columns to the fields of a published template, and the app queues all rows as one batch. When it is done, you download the documents as one zip.
Before you start
- A published template. The dialog renders the published version of a template of the current workspace. Publish the template first; drafts are not offered.
- A role that may render. Owners, admins and editors see the button; viewers do not.
- Units. Every row is a live render and costs units like a render through the API: a PDF of up to 5 pages costs 1 unit, an image 1 unit. The dialog never uses the test environment, so the documents carry no test mark. To try the template first, use True render in the editor or a test key.
An example
A certificate template whose sample data looks like this:
{
"name": "Max Mustermann",
"course": { "title": "Data Basics", "date": "2026-10-01" },
"score": 92,
"passed": true
}
and a sheet with one participant per row (here as CSV; an Excel file with the same first row works the same way):
name,course.title,date,score,passed,file
Max Mustermann,Data Basics,2026-10-01,92,yes,max-mustermann
Erika Mustermann,Data Basics,2026-10-01,88,yes,erika-mustermann
John Doe,Data Basics,2026-10-01,61,no,john-doe
The dialog maps name, course.title, score and passed by their names and date to course.date by its last part, and sends the first row as:
{
"name": "Max Mustermann",
"course": { "title": "Data Basics", "date": "2026-10-01" },
"score": 92,
"passed": true
}
With File name from column set to file, the three documents are called max-mustermann.pdf, erika-mustermann.pdf and john-doe.pdf.
Step by step
Open Renders and choose Batch from spreadsheet.
- Template. Pick one of the workspace's published templates (the list shows each with its published version,
Invoice · v7). The fields come from the template's stored data schema, or, without one, from the sample data of the published version. - File. Choose a CSV, TSV or Excel file (
.csv,.tsv,.txt,.xlsx,.xls,.ods). The first row holds the column names; a column without a name is calledcolumn_1,column_2and so on. Empty rows are skipped. A workbook with several sheets shows a Sheet picker with each sheet's row count; sheets without data rows are left out. - Map columns to fields. The table lists every field of the template with its type. A column is mapped automatically when its name matches the field's full path (
course.title) or its last part (title), ignoring case, spaces and punctuation. For every other field, pick a column under Source, choose constant and type a value that applies to every row, or leave it on — skip —. - Options.
- File name from column: the column that names each document. Characters other than ASCII letters, digits,
_,.and-become_(Müller GmbHbecomesM_ller_GmbH), and the extension of the output is added. With row number (the default) the documents are calledrow-1,row-2and so on, padded with zeros to the width of the row count (row-001in a sheet of 100 rows or more). An empty cell in the name column falls back to the row number too. - Output: As the template (PDF for a PDF template, the image format of an image template, the document of a Word or PowerPoint template), or one of the formats the template can make: PDF, PNG, JPG or WebP for HTML templates; Word or PowerPoint and PDF for office templates.
- Bundle as zip: on by default; packs all documents into one zip when the batch is done.
- File name from column: the column that names each document. Characters other than ASCII letters, digits,
- First row as data. The data object the first row becomes, exactly as the template receives it. Below it, Not mapped names the fields that stay empty in every document.
- Queue n renders sends the batch.
How cells become values
| Field type | A cell becomes | Example |
|---|---|---|
| string | The cell's text as the sheet shows it, trimmed; an empty cell is "" | Data Basics |
| number, integer | A number; a decimal comma is accepted. Text that is no number (1.234,56 with a thousands separator, n/a) stays text | 92, 4,5 → 4.5 |
| boolean | true for true, yes, 1, ja; false for false, no, 0, nein (any case); anything else stays text | yes → true |
| array | JSON ([{"qty": 2}]), or values separated by ; or |, which become a list of strings | red; green → ["red", "green"] |
| object | JSON ({"city": "Musterstadt"}); anything else stays text |
An empty cell in a field that is not a string becomes null. A constant is converted the same way. Fields inside the items of an array (items[].qty) are not offered one by one; map the whole array from a column with JSON.
Dates are not converted: a date cell arrives as the text the sheet shows, in its cell format. Format date columns as text in the form your template expects, for example 2026-10-01, which the date helpers read.
Limits
| Limit | |
|---|---|
| Rows per batch | 1,000. Above that the Queue button stays disabled; split the sheet, or send several batches from code. |
| Templates in the list | The first 100 published templates of the workspace, by name |
| Units | Free plan: the batch is refused unless at least one unit per row is left in the period. Paid plans render rows beyond the included units as overage, up to the hard cap. |
| Word and PowerPoint templates | Live renders of them need Starter or above |
When there are not enough units, the dialog says Not enough units left for this batch and queues nothing; buy a pack or change the plan under Billing.
Follow the batch and download the zip
The Batches panel on the Renders page lists the last 20 batches of the workspace, also those sent through the API, with their progress (2 of 3 done, 1 failed) and status: queued, rendering, completed, partly failed or failed. Select a batch to see only its documents in the render log below; every document is a render of its own there, with its output and, when it failed, its error.
When the last document is done and Bundle as zip was on, Download zip appears. The zip holds every document that succeeded, numbered by its row so the names stay unique: 0001-max-mustermann.pdf, 0002-erika-mustermann.pdf. A failed row is not in the zip and its number is missing; fix the data or the template and send those rows again.
From code
The dialog calls POST /v1/renders/batch with one item per row, { "data": {…}, "filename": "max-mustermann.pdf" }, plus zip and the chosen output, and meta with "source": "spreadsheet", the file name and the sheet. To do the same from a script, read the file yourself and send the rows as items; the SDKs have renders.batch() for it. See Async and batch for the request shape and for more than 1,000 rows.