Skip to content

CSV Output

Output

Write the incoming row stream to a .csv file. Pick the column delimiter, decide whether to write a header row, and choose between Unix (LF) or Windows (CRLF) line endings. Values containing the delimiter, quotes, or newlines are quoted automatically.

CSV Output is a sink node — it consumes a row stream and produces a text/csv Blob the user can download. The headers are taken from the keys of the first row in the stream, in insertion order. Subsequent rows are written by reading those same keys; columns that appear later in the stream but not in the first row are silently dropped.

Each cell is converted to a string with the shared cellToString helper (null and undefined become empty strings, numbers and booleans use String()). A cell is quoted only if it contains the delimiter, a double quote, \n, or \r. Inside a quoted cell, embedded double quotes are doubled ("""). Otherwise the raw string is written.

Input: A row stream from any upstream transform. Output: A CSV Blob with MIME type text/csv.

OptionTypeDefaultDescription
delimiterstring (1 char),Single character used to separate columns. Common values: ,, ;, \t, |.
includeHeaderbooleantrueWrite the column names as the first row.
lineEnding"LF" | "CRLF""LF"Line terminator. LF for Unix/Mac, CRLF for Windows.

Default comma-separated output with header

Section titled “Default comma-separated output with header”

A standard CSV download — comma delimiter, header row, Unix line endings.

Before:

order_idcustomeramount
1001Acme Corp2400
1002Beta Inc750

Configuration: defaults — delimiter: ",", includeHeader: true, lineEnding: "LF".

After (raw file content):

order_id,customer,amount
1001,Acme Corp,2400
1002,Beta Inc,750

A row contains a comma in the customer name and embedded quotes in the note.

Before:

order_idcustomernote
2001Acme, CorpHe said “ship today”
2002Beta Incpriority

Configuration: defaults.

After (raw file content):

order_id,customer,note
2001,"Acme, Corp","He said ""ship today"""
2002,Beta Inc,priority

The customer cell is wrapped in quotes because of the embedded comma. The note cell is wrapped because of the embedded quotes, and each " is escaped as "".

Tab-separated, no header, Windows line endings

Section titled “Tab-separated, no header, Windows line endings”

A TSV export aimed at a Windows tool that expects CRLF and no header line.

Before:

datelabelamount
2025-04-01rent1200
2025-04-02groceries87

Configuration: delimiter: "\t", includeHeader: false, lineEnding: "CRLF".

After (raw file content, with shown for tab and ␍␊ for CRLF):

2025-04-01→rent→1200␍␊2025-04-02→groceries→87
  • Header columns are locked to the first row. The output uses Object.keys(firstRow) as the column list and applies it to every subsequent row. If a later row introduces a new key, that key is omitted from the output. Normalise keys upstream (e.g. via Add Column with a default value) before serialisation. See apps/web/src/transforms/output-csv/logic.ts:96-114.
  • null and undefined become empty strings. There is no null literal in CSV. Distinguishing missing data from empty strings is impossible after this step — record the distinction upstream if you need to recover it. See apps/web/src/transforms/output-csv/logic.ts:107-114 and apps/web/src/transforms/shared/cell-utils.ts.
  • delimiter must be exactly one character. Multi-character separators are rejected at config-validation time. See apps/web/src/transforms/output-csv/logic.ts:18-22.
  • Excel Output — write .xlsx workbooks instead of plain CSV.
  • JSON Output — write a JSON array or NDJSON when the consumer expects structured data.
  • Reorder Columns — set the column order before serialisation, since CSV Output uses first-row key order.