Examples

TypeScript Examples Source

JavaScript Examples Source

Alternate delimiter

You can change the default delimiter , by specifying the delimiter option

import { format } from '@fast-csv/format';
const stream = format({ delimiter: '\t' });
stream.pipe(process.stdout);
stream.write(['a', 'b']);
stream.write(['a1', 'b1']);
stream.write(['a2', 'b2']);
stream.end();

Alternate rowDelimiter

You can change the default row delimiter \n by specifying the rowDelimiter option.

import { format } from '@fast-csv/format';
const stream = format({ rowDelimiter: '||' });
stream.pipe(process.stdout);
stream.write(['a', 'b']);
stream.write(['a1', 'b1']);
stream.write(['a2', 'b2']);
stream.end();

Alternate quote

You change change the default quote " option by specifying the quote option.

import { format } from '@fast-csv/format';
const stream = format({ quote: "'" });
stream.pipe(process.stdout);
// each field will be quoted because it contains a delimiter
stream.write(['a,a', 'b,b']);
stream.write(['a1,a1', 'b1,b1']);
stream.write(['a2,a2', 'b2,b2']);
stream.end();

Alternate escape

You change change the default escape " option by specifying the escpae option.

import { format } from '@fast-csv/format';
const stream = format({ escape: "'" });
stream.pipe(process.stdout);
// wrap each field in a quote so it is escaped and quoted
stream.write(['"a"', '"b"']);
stream.write(['"a1"', '"b1"']);
stream.write(['"a2"', '"b2"']);
stream.end();

Headers

Auto Discovery

fast-csv will auto-discover headers when the headers option is set to true.

info

When working with one-dimensional array rows (e.g. ['a', 'b', 'c']) this is a no-op.

In this example the headers are auto-discovered from the objects passed in.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value1b' });
csvStream.write({ header1: 'value2a', header2: 'value2b' });
csvStream.write({ header1: 'value3a', header2: 'value3b' });
csvStream.write({ header1: 'value4a', header2: 'value4b' });
csvStream.end();

In this example the headers are auto-discovered from the hash arrays passed in.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write([
['header1', 'value1a'],
['header2', 'value1b'],
]);
csvStream.write([
['header1', 'value2a'],
['header2', 'value2b'],
]);
csvStream.write([
['header1', 'value3a'],
['header2', 'value3b'],
]);
csvStream.write([
['header1', 'value4a'],
['header2', 'value4b'],
]);
csvStream.end();

Provided Headers

You can also provide a set of headers by providing an array. This allows you to

  • Reorder and/or exclude columns when working with object rows.
  • Rename and/or exclude columns when working with hash array rows.
  • Specify headers or remove columns when working with array rows.
  • Enforce column order, when rows are objects.

In this example a custom set of headers is provided for rows that are arrays.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header1', 'header2'] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write(['value1a', 'value1b']);
csvStream.write(['value2a', 'value2b']);
csvStream.write(['value3a', 'value3b']);
csvStream.write(['value4a', 'value4b']);
csvStream.end();

In this example the headers are overridden with a custom set of headers

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header1', 'header2'] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write([
['h1', 'value1a'],
['h2', 'value1b'],
]);
csvStream.write([
['h1', 'value2a'],
['h2', 'value2b'],
]);
csvStream.write([
['h1', 'value3a'],
['h2', 'value3b'],
]);
csvStream.write([
['h1', 'value4a'],
['h2', 'value4b'],
]);
csvStream.end();

In this example the columns are reordered.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header2', 'header1'] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value1b' });
csvStream.write({ header1: 'value2a', header2: 'value2b' });
csvStream.write({ header1: 'value3a', header2: 'value3b' });
csvStream.write({ header1: 'value4a', header2: 'value4b' });
csvStream.end();

In this example one of the columns is removed.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header2'] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value1b' });
csvStream.write({ header1: 'value2a', header2: 'value2b' });
csvStream.write({ header1: 'value3a', header2: 'value3b' });
csvStream.write({ header1: 'value4a', header2: 'value4b' });
csvStream.end();

Write Headers

The writeHeaders option can be used to prevent writing headers, while still auto discovering them or providing them.

The writeHeaders option can be useful when appending to a csv to prevent writing headers twice. See the append example

note

If writeHeaders is set to false, headers is set to true, and your rows are arrays, the first row will not be written.

Do not write headers.

In this example the auto discovered headers are not written.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, writeHeaders: false });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

Specify column order without headers

In this example the headers are provided to specify order of columns but they are not written.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header2', 'header1'], writeHeaders: false });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

quoteColumns

Sometimes you may need to quote columns in a certain ways in order to meet certain requirements. fast-csv can quote columns and headers almost anyway you may need.

boolean

Setting quoteColumns to true will by default quote all columns and headers.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, quoteColumns: true });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

boolean[]

Setting quoteColumns to a boolean[] will quote the columns that are set to true at each index in the array.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header1', 'header2'], quoteColumns: [false, true] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

object

Setting quoteColumns to a {[string]: boolean} will quote the columns that are in the object with a value of true

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, quoteColumns: { header2: true } });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

Quote Columns NOT headers

If you need to quote columns and not headers you can set quoteHeaders to false.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, quoteColumns: { header2: true }, quoteHeaders: false });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

quoteHeaders option

The quoteHeaders option uses the same types as quoteColumns.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, quoteHeaders: true });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

In this example we specify the headers to quote by passing in an array to specify which headers to quote

import { format } from '@fast-csv/format';
const csvStream = format({ headers: ['header1', 'header2'], quoteHeaders: [false, true] });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

In this example we specify the headers to quote by passing in an object where the key is the header name and the value is a boolean.

import { format } from '@fast-csv/format';
const csvStream = format({ headers: true, quoteHeaders: { header2: true } });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

Transforming Rows

You can transform rows by using the .transform method.

import { format } from '@fast-csv/format';
interface CsvRow {
header1: string;
header2: string;
}
const csvStream = format<CsvRow, CsvRow>({ headers: true }).transform((row: CsvRow) => ({
header1: row.header1.toUpperCase(),
header2: row.header2.toUpperCase(),
}));
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

You can also specify your transform method as an option.

import { format } from '@fast-csv/format';
interface CsvRow {
header1: string;
header2: string;
}
const transform = (row: CsvRow): CsvRow => ({
header1: row.header1.toUpperCase(),
header2: row.header2.toUpperCase(),
});
const csvStream = format({ headers: true, transform });
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

Transform can also be async by accepting a callback.

import { format } from '@fast-csv/format';
interface CsvRow {
header1: string;
header2: string;
}
const csvStream = format<CsvRow, CsvRow>({ headers: true })
.transform((row, cb) => {
setImmediate(() => cb(null, {
header1: row.header1.toUpperCase(),
header2: row.header2.toUpperCase(),
}));
});
csvStream.pipe(process.stdout).on('end', () => process.exit());
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.write({ header1: 'value1a', header2: 'value2a' });
csvStream.end();

Appending To A CSV

In this example a new csv is created then appended to.

import * as path from 'path';
import * as fs from 'fs';
import { FormatterOptionsArgs, Row, writeToStream } from '@fast-csv/format';
type CsvFileOpts = {
headers: string[];
path: string;
};
class CsvFile {
static write(stream: NodeJS.WritableStream, rows: Row[], options: FormatterOptionsArgs<Row, Row>): Promise<void> {
return new Promise((res, rej) => {
writeToStream(stream, rows, options)
.on('error', (err: Error) => rej(err))
.on('finish', () => res());
});
}
private readonly headers: string[];
private readonly path: string;
private readonly writeOpts: FormatterOptionsArgs<Row, Row>;
constructor(opts: CsvFileOpts) {
this.headers = opts.headers;
this.path = opts.path;
this.writeOpts = { headers: this.headers, includeEndRowDelimiter: true };
}
create(rows: Row[]): Promise<void> {
return CsvFile.write(fs.createWriteStream(this.path), rows, { ...this.writeOpts });
}
append(rows: Row[]): Promise<void> {
return CsvFile.write(fs.createWriteStream(this.path, { flags: 'a' }), rows, {
...this.writeOpts,
// dont write the headers when appending
writeHeaders: false,
} as FormatterOptionsArgs<Row, Row>);
}
read(): Promise<Buffer> {
return new Promise((res, rej) => {
fs.readFile(this.path, (err, contents) => {
if (err) {
return rej(err);
}
return res(contents);
});
});
}
}
const csvFile = new CsvFile({
path: path.resolve(__dirname, 'append.tmp.csv'),
// headers to write
headers: ['c', 'b', 'a'],
});
// 1. create the csv
csvFile
.create([
{ a: 'a1', b: 'b1', c: 'c1' },
{ b: 'b2', a: 'a2', c: 'c2' },
{ a: 'a3', b: 'b3', c: 'c3' },
])
// append rows to file
.then(() =>
csvFile.append([
{ a: 'a4', b: 'b4', c: 'c4' },
{ a: 'a5', b: 'b5', c: 'c5' },
]),
)
// append another row
.then(() => csvFile.append([{ a: 'a6', b: 'b6', c: 'c6' }]))
.then(() => csvFile.read())
.then(contents => {
console.log(`${contents}`);
})
.catch(err => {
console.error(err.stack);
process.exit(1);
});