Skip to main content

Utility Functions

The sheet_to_* functions accept a worksheet and an optional options object.

The *_to_sheet functions accept a data object and an optional options object.

The sheet_add_* functions accept worksheet, data, and optional options.

The examples are based on the following worksheet:

SheetJS
12 567
23 678
34 789
4567890

Array of Arrays Input

Create a worksheet from an array of arrays

var ws = XLSX.utils.aoa_to_sheet(aoa, opts);

XLSX.utils.aoa_to_sheet takes an array of arrays of JS values and returns a worksheet resembling the input data. Values are interpreted as follows:

  • Numbers, Booleans and Strings are stored as the corresponding types.
  • Date objects are stored as Date cells or date codes (see cellDates option)
  • Array holes and explicit undefined values are skipped.
  • null values may be stubbed (see sheetStubs and nullError options)
  • Cell objects are used as-is.

The function takes an options argument:

Option NameDefaultDescription
dateNFFMT 14Use specified date format in string output
cellDatesfalseStore dates as type d (default is n)
sheetStubsfalseCreate cell objects of type z for null values
nullErrorfalseIf true, emit #NULL! error cells for null values

The example worksheet can be generated with:

var ws = XLSX.utils.aoa_to_sheet([
["S", "h", "e", "e", "t", "J", "S"],
[ 1, 2, , , 5, 6, 7],
[ 2, 3, , , 6, 7, 8],
[ 3, 4, , , 7, 8, 9],
[ 4, 5, 6, 7, 8, 9, 0]
]);

Add data from an array of arrays to an existing worksheet

XLSX.utils.sheet_add_aoa(ws, aoa, opts);

XLSX.utils.sheet_add_aoa takes an array of arrays of JS values and updates an existing worksheet object. It follows the same process as aoa_to_sheet and accepts an options argument:

Option NameDefaultDescription
dateNFFMT 14Use specified date format in string output
cellDatesfalseStore dates as type d (default is n)
sheetStubsfalseCreate cell objects of type z for null values
nullErrorfalseIf true, emit #NULL! error cells for null values
originUse specified cell as starting point (see below)

origin is expected to be one of:

originDescription
(cell object)Use specified cell (cell object)
(string)Use specified cell (A1-Style cell)
(number >= 0)Start from the first column at specified row (0-indexed)
-1Append to bottom of worksheet starting on first column
(default)Start from cell A1

The example worksheet can be built up in the order A1:G1, A2:B4, E2:G4, A5:G5:

/* Initial row */
var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);

/* Write data starting at A2 */
XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});

/* Write data starting at E2 */
XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});

/* Append row */
XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});

Array of Objects Input

Create a worksheet from an array of objects

var ws = XLSX.utils.json_to_sheet(aoo, opts);

XLSX.utils.json_to_sheet takes an array of objects and returns a worksheet with automatically-generated "headers" based on the keys of the objects. The default column order is determined by the first appearance of the field using Object.keys. The function accepts an options argument:

Option NameDefaultDescription
headerUse specified field order (default Object.keys) **
dateNFFMT 14Use specified date format in string output
cellDatesfalseStore dates as type d (default is n)
skipHeaderfalseIf true, do not include header row in output
nullErrorfalseIf true, emit #NULL! error cells for null values
caution

All fields from each row will be written! header hints at a particular order but is not exclusive. To remove fields from the export, filter the data source.

Some data sources have special options to filter properties. For example, MongoDB will add the _id field when finding data from a collection:

const aoo_with_id = await coll.find({}).toArray();
const ws = XLSX.utils.json_to_sheet(aoo_with_id); // includes _id column

This can be filtered out through the projection property:

const aoo = await coll.find({}, {projection:{_id:0}}).toArray(); // no _id !
const ws = XLSX.utils.json_to_sheet(aoo);

If a data source does not provide a filter option, it can be filtered manually:

const aoo = data.map(obj => Object.fromEntries(Object.entries(obj).filter(r => headers.indexOf(r[0]) > -1)));
  • If header is an array, missing keys will be added in order of first use.
  • Cell types are deduced from the type of each value. For example, a Date object will generate a Date cell, while a string will generate a Text cell.
  • Null values will be skipped by default. If nullError is true, an error cell corresponding to #NULL! will be written to the worksheet.

The example sheet cannot be reproduced using plain objects since JS object keys must be unique. After replacing the second e and S with e_1 and S_1:

var ws = XLSX.utils.json_to_sheet([
{ S:1, h:2, t:5, J:6, S_1:7 },
{ S:2, h:3, t:6, J:7, S_1:8 },
{ S:3, h:4, t:7, J:8, S_1:9 },
{ S:4, h:5, e:6, e_1:7, t:8, J:9, S_1:0 },
], {header:["S","h","e","e_1","t","J","S_1"]});

Alternatively, a different set of unique headers can be used with skipHeader:

var ws = XLSX.utils.json_to_sheet([
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" },
{ A: 1, B: 2, E: 5, F: 6, G: 7 },
{ A: 2, B: 3, E: 6, F: 7, G: 8 },
{ A: 3, B: 4, E: 7, F: 8, G: 9 },
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 },
], {header:["A","B","C","D","E","F","G"], skipHeader:true});

Add data from an array of objects to an existing worksheet

XLSX.utils.sheet_add_json(ws, aoo, opts);

XLSX.utils.sheet_add_json takes an array of objects and updates an existing worksheet object. It follows the same process as json_to_sheet and accepts an options argument:

Option NameDefaultDescription
headerUse specified column order (default Object.keys)
dateNFFMT 14Use specified date format in string output
cellDatesfalseStore dates as type d (default is n)
skipHeaderfalseIf true, do not include header row in output
nullErrorfalseIf true, emit #NULL! error cells for null values
originUse specified cell as starting point (see below)

origin is expected to be one of:

originDescription
(cell object)Use specified cell (cell object)
(string)Use specified cell (A1-Style cell)
(number >= 0)Start from the first column at specified row (0-indexed)
-1Append to bottom of worksheet starting on first column
(default)Start from cell A1

This example worksheet can be built up in the order A1:G1, A2:B4, E2:G4, A5:G5:

/* Initial row */
var ws = XLSX.utils.json_to_sheet([
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});

/* Write data starting at A2 */
XLSX.utils.sheet_add_json(ws, [
{ A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }
], {skipHeader: true, origin: "A2"});

/* Write data starting at E2 */
XLSX.utils.sheet_add_json(ws, [
{ A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }
], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});

/* Append row */
XLSX.utils.sheet_add_json(ws, [
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});
note

If the header option is an array, sheet_add_json and sheet_to_json will append missing elements.

This design enables consistent header order across calls:

Result
Loading...
Live Editor

HTML Table Input

This has been moved to a separate page

Value Override

This has been moved to a separate page

Delimiter-Separated Output

This has been moved to a separate page

HTML Output

This has been moved to a separate page

Array Output

var arr = XLSX.utils.sheet_to_json(ws, opts);

var aoa = XLSX.utils.sheet_to_json(ws, {header: 1, ...other_opts});

XLSX.utils.sheet_to_json generates an array of JS objects. The function takes an options argument:

Option NameDefaultDescription
rawtrueUse raw values (true) or formatted strings (false)
range**Override Range (see table below)
headerControl output format (see table below)
dateNFFMT 14Use specified date format in string output
defvalUse specified value in place of null or undefined
blankrows**Include blank lines in the output **
  • raw only affects cells which have a format code (.z) field or a formatted text (.w) field.
  • If header is specified, the first row is considered a data row; if header is not specified, the first row is the header row and not considered data.
  • When header is not specified, the conversion will automatically disambiguate header entries by affixing _ and a count starting at 1. For example, if three columns have header foo the output fields are foo, foo_1, foo_2
  • null values are returned when raw is true but are skipped when false.
  • If defval is not specified, null and undefined values are skipped normally. If specified, all null and undefined points will be filled with defval
  • When header is 1, the default is to generate blank rows. blankrows must be set to false to skip blank rows.
  • When header is not 1, the default is to skip blank rows. blankrows must be true to generate blank rows

range is expected to be one of:

rangeDescription
(number)Use worksheet range but set starting row to the value
(string)Use specified range (A1-Style bounded range string)
(default)Use worksheet range (ws['!ref'])

header is expected to be one of:

headerDescription
1Generate an array of arrays
"A"Row object keys are literal column labels
array of stringsUse specified strings as keys in row objects
(default)Read and disambiguate first row as keys
  • If header is not 1, the row object will contain the non-enumerable property __rowNum__ that represents the row of the sheet corresponding to the entry.
  • If header is an array, the keys will not be disambiguated. This can lead to unexpected results if the array values are not unique!

For the example worksheet:

Result
Loading...
Live Editor

Formulae Output

This has been moved to a separate page