array
This commit is contained in:
parent
063aec617b
commit
21e8d777ed
@ -64,9 +64,9 @@ The raw data is an Array of objects. This is the data for John Adams:
|
||||
"gender": "M"
|
||||
},
|
||||
"terms": [
|
||||
{ "type": "viceprez", /* (other fields omitted) */ },
|
||||
{ "type": "viceprez", /* (other fields omitted) */ },
|
||||
{ "type": "prez", /* (other fields omitted) */ }
|
||||
{ "type": "viceprez", "start": "1789-04-21", /* (other fields omitted) */ },
|
||||
{ "type": "viceprez", "start": "1793-03-04", /* (other fields omitted) */ },
|
||||
{ "type": "prez", "start": "1797-03-04", /* (other fields omitted) */ }
|
||||
]
|
||||
}
|
||||
```
|
||||
@ -89,7 +89,7 @@ const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")
|
||||
The dataset is sorted in chronological order by the first presidential or vice
|
||||
presidential term. The Vice President and President in a given term are sorted
|
||||
alphabetically. Joe Biden and Barack Obama were Vice President and President
|
||||
respectively in 2009. Since "Biden" is lexicographically before "Obama", Biden's
|
||||
respectively in 2009. Since "Biden" is alphabetically before "Obama", Biden's
|
||||
data point appears first. The goal is to sort the presidents in order of their
|
||||
presidential term.
|
||||
|
||||
|
@ -6,6 +6,8 @@ sidebar_position: 1
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
ReactJS is a JS library for building user interfaces.
|
||||
@ -42,28 +44,19 @@ depends on the application.
|
||||
### Array of Objects
|
||||
|
||||
Typically, some users will create a spreadsheet with source data that should be
|
||||
loaded into the site. This sheet will have known columns. For example, our
|
||||
[presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns:
|
||||
loaded into the site. This sheet will have known columns.
|
||||
|
||||
#### State
|
||||
|
||||
The example [presidents sheet](https://sheetjs.com/pres.xlsx) has one header row
|
||||
with "Name" and "Index" columns. The natural JS representation is an object for
|
||||
each row, using the values in the first rows as keys:
|
||||
|
||||
<table><thead><tr><th>Spreadsheet</th><th>State</th></tr></thead><tbody><tr><td>
|
||||
|
||||
![`pres.xlsx` data](pathname:///pres.png)
|
||||
|
||||
This naturally maps to an array of typed objects, as in the TS example below:
|
||||
|
||||
```ts
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
|
||||
const wb = read(f);
|
||||
const data = utils.sheet_to_json<President>(wb.Sheets[wb.SheetNames[0]]);
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
`data` will be an array of objects:
|
||||
</td><td>
|
||||
|
||||
```js
|
||||
[
|
||||
@ -75,8 +68,177 @@ console.log(data);
|
||||
]
|
||||
```
|
||||
|
||||
A component will typically map over the data. The following example generates
|
||||
a TABLE with a row for each President:
|
||||
</td></tr></tbody></table>
|
||||
|
||||
The React `useState` hook can configure the state:
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
|
||||
```ts
|
||||
import { useState } from 'react';
|
||||
|
||||
/* the component state is an array of presidents */
|
||||
const [pres, setPres] = useState([]);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript" default>
|
||||
|
||||
```ts
|
||||
import { useState } from 'react';
|
||||
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
/* the component state is an array of presidents */
|
||||
const [pres, setPres] = useState<President[]>([]);
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
The types are informative. They do not enforce that worksheets include the named
|
||||
columns. A runtime data validation library should be used to verify the dataset.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Updating State
|
||||
|
||||
The [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output)
|
||||
functions simplify state updates. They are best used in the function bodies of
|
||||
`useEffect` and `useCallback` hooks.
|
||||
|
||||
A `useEffect` hook can download and update state when a person loads the site:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
url[(Remote\nFile)]
|
||||
ab[(Data\nArrayBuffer)]
|
||||
wb(SheetJS\nWorkbook)
|
||||
ws(SheetJS\nWorksheet)
|
||||
aoo(array of\nobjects)
|
||||
state((component\nstate))
|
||||
url --> |fetch\n\n| ab
|
||||
ab --> |read\n\n| wb
|
||||
wb --> |wb.Sheets\nselect sheet| ws
|
||||
ws --> |sheet_to_json\n\n| aoo
|
||||
aoo --> |setPres\nfrom `setState`| state
|
||||
```
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
|
||||
```ts
|
||||
import { useEffect } from 'react';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (async() => {
|
||||
/* Download file */
|
||||
const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
|
||||
// highlight-start
|
||||
const wb = read(f); // parse the array buffer
|
||||
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
|
||||
const data = utils.sheet_to_json(ws); // generate objects
|
||||
setPres(data); // update state
|
||||
// highlight-end
|
||||
})(); }, []);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript" default>
|
||||
|
||||
```ts
|
||||
import { useEffect } from 'react';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (async() => {
|
||||
/* Download file */
|
||||
const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
|
||||
// highlight-start
|
||||
const wb = read(f); // parse the array buffer
|
||||
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
|
||||
const data: President[] = utils.sheet_to_json<President>(ws); // generate objects
|
||||
setPres(data); // update state
|
||||
// highlight-end
|
||||
})(); }, []);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Rendering Data
|
||||
|
||||
Components typically render HTML tables from arrays of objects. The `<tr>` table
|
||||
row elements are typically generated by mapping over the state array, as shown
|
||||
in the example JSX code:
|
||||
|
||||
```jsx title="Example JSX for displaying arrays of objects"
|
||||
<table>
|
||||
{/* The `thead` section includes the table header row */}
|
||||
<thead><th>Name</th><th>Index</th></thead>
|
||||
{/* The `tbody` section includes the data rows */}
|
||||
<tbody>
|
||||
{/* generate row (TR) for each president */}
|
||||
// highlight-start
|
||||
{pres.map(row => (
|
||||
<tr>
|
||||
{/* Generate cell (TD) for name / index */}
|
||||
<td>{row.Name}</td>
|
||||
<td>{row.Index}</td>
|
||||
</tr>
|
||||
))}
|
||||
// highlight-end
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
#### Exporting Data
|
||||
|
||||
The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
functions simplify exporting data. They are best used in the function bodies of
|
||||
`useCallback` hooks attached to button or other elements.
|
||||
|
||||
A callback can generate a local file when a user clicks a button:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
state((component\nstate))
|
||||
ws(SheetJS\nWorksheet)
|
||||
wb(SheetJS\nWorkbook)
|
||||
file[(XLSX\nexport)]
|
||||
state --> |json_to_sheet\n\n| ws
|
||||
ws --> |book_new\nbook_append_sheet| wb
|
||||
wb --> |writeFile\n\n| file
|
||||
```
|
||||
|
||||
```ts
|
||||
import { useCallback } from 'react';
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
|
||||
/* get state data and export to XLSX */
|
||||
const exportFile = useCallback(() => {
|
||||
/* generate worksheet from state */
|
||||
// highlight-next-line
|
||||
const ws = utils.json_to_sheet(pres);
|
||||
/* create workbook and append worksheet */
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "Data");
|
||||
/* export to XLSX */
|
||||
writeFile(wb, "SheetJSReactAoO.xlsx");
|
||||
}, [pres]);
|
||||
```
|
||||
|
||||
#### Complete Component
|
||||
|
||||
This complete component example fetches a test file and displays the contents in
|
||||
a HTML table. When the export button is clicked, a callback will export a file:
|
||||
|
||||
```jsx title="src/SheetJSReactAoO.js"
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
@ -2,6 +2,9 @@
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Sheet Objects
|
||||
|
||||
Excel supports 4 different types of "sheets":
|
||||
@ -36,19 +39,49 @@ large worksheets, dense sheets use less memory and tend to be more efficient.
|
||||
sparse and dense worksheets. Functions that accept worksheet or workbook objects
|
||||
(e.g. `writeFile` and `sheet_to_json`) will detect dense sheets.
|
||||
|
||||
The option `dense: true` should be used when creating worksheet or book objects:
|
||||
The option `dense: true` should be used when creating worksheet or book objects.
|
||||
|
||||
**Update code that manually searches for cells** (adding dense mode support):
|
||||
|
||||
_Addressing Cells_
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="es3" label="Works everywhere">
|
||||
|
||||
```diff
|
||||
-var workbook = XLSX.read(data, {...opts});
|
||||
+var workbook = XLSX.read(data, {...opts, dense: true});
|
||||
|
||||
-var sheet = XLSX.utils.aoa_to_sheet([[1,2,3],[4,5,6]], {...opts});
|
||||
+var sheet = XLSX.utils.aoa_to_sheet([[1,2,3],[4,5,6]], {...opts, dense: true});
|
||||
|
||||
-var sheet = XLSX.utils.json_to_sheet([{x:1,y:2}], {...opts});
|
||||
+var sheet = XLSX.utils.json_to_sheet([{x:1,y:2}], {...opts, dense: true});
|
||||
-var cell = sheet["B7"];
|
||||
+var cell = sheet["!data"] != null ? (sheet["!data"][6]||[])[1] : sheet["B3"];
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="es2020" label="New in 2020">
|
||||
|
||||
```diff
|
||||
-var cell = sheet["B7"];
|
||||
+var cell = sheet["!data"] != null ? sheet["!data"]?.[6]?.[1] : sheet["B3"];
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The row and column can be calculated using `XLSX.utils.decode_cell`:
|
||||
|
||||
```diff
|
||||
var addr = "B7";
|
||||
-var cell = sheet[addr];
|
||||
+var _addr = XLSX.utils.decode_cell(addr);
|
||||
+var cell = sheet["!data"] != null ? sheet["!data"]?.[_addr.r]?.[_addr.c] : sheet[addr];
|
||||
```
|
||||
|
||||
`XLSX.utils.encode_cell` will be using the desired row and column indices:
|
||||
|
||||
```diff
|
||||
-var cell = sheet[XLSX.utils.encode_cell({r:R, c:C})];
|
||||
+var cell = sheet["!data"] != null ? sheet["!data"]?.[R]?.[C] : sheet[XLSX.utils.encode_cell({r:R, c:C})];
|
||||
```
|
||||
|
||||
_Looping across a Worksheet_
|
||||
|
||||
Code that manually loops over worksheet objects should test for `"!data"` key:
|
||||
|
||||
```js
|
||||
@ -68,6 +101,34 @@ function log_all_cells(ws) {
|
||||
}
|
||||
```
|
||||
|
||||
**Update workbook and worksheet generation code**
|
||||
|
||||
_`read`_
|
||||
```diff
|
||||
-var workbook = XLSX.read(data, {...opts});
|
||||
+var workbook = XLSX.read(data, {...opts, dense: true});
|
||||
```
|
||||
|
||||
_`readFile`_
|
||||
```diff
|
||||
-var workbook = XLSX.readFile(data, {...opts});
|
||||
+var workbook = XLSX.readFile(data, {...opts, dense: true});
|
||||
```
|
||||
|
||||
_`aoa_to_sheet`_
|
||||
```diff
|
||||
-var sheet = XLSX.utils.aoa_to_sheet([[1,2,3],[4,5,6]], {...opts});
|
||||
+var sheet = XLSX.utils.aoa_to_sheet([[1,2,3],[4,5,6]], {...opts, dense: true});
|
||||
```
|
||||
|
||||
_`json_to_sheet`_
|
||||
```diff
|
||||
-var sheet = XLSX.utils.json_to_sheet([{x:1,y:2}], {...opts});
|
||||
+var sheet = XLSX.utils.json_to_sheet([{x:1,y:2}], {...opts, dense: true});
|
||||
```
|
||||
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
### Sheet Properties
|
||||
|
@ -7,27 +7,39 @@ sidebar_position: 4
|
||||
<details>
|
||||
<summary><b>File Format Support</b> (click to show)</summary>
|
||||
|
||||
Comments and Notes have evolved over the years. "Notes" (powered by VML) were
|
||||
the original comments. "Comments" were added later.
|
||||
Comments and Notes have evolved over the years.
|
||||
|
||||
Excel 2.0 - '95 "Notes" were displayed in a master list.
|
||||
|
||||
Excel '97 - 2019 "Comments" float over the sheet and support styling.
|
||||
|
||||
Excel 365 introduced "Threaded Comments" which do not support rich text but do
|
||||
allow users to "reply". The original "Comments" were renamed to "Notes".
|
||||
|
||||
| Formats | Notes | Comment | Threaded |
|
||||
|:------------------|:-----:|:-------:|:--------:|
|
||||
| XLSX / XLSM | ✔ | ✔ | ✔ |
|
||||
| XLSB | ✔ | ✔ | R |
|
||||
| XLS | R | R | * |
|
||||
| XLML | ✔ | ✔ | * |
|
||||
| SYLK | | * | * |
|
||||
| ODS / FODS / UOS | ✔ | R | * |
|
||||
| NUMBERS | * | * | |
|
||||
| XLSX / XLSM | ✕ | ✔ | ✔ |
|
||||
| XLSB | ✕ | R | R |
|
||||
| NUMBERS | ✕ | ✕ | R |
|
||||
| XLS (BIFF8) | ✕ | ✔ | ✕ |
|
||||
| XLML | ✕ | ✔ | ✕ |
|
||||
| ODS / FODS / UOS | ✕ | ✔ | ✕ |
|
||||
| SYLK | ✔ | ✕ | ✕ |
|
||||
| XLS (BIFF5) | ✔ | ✕ | ✕ |
|
||||
| XLS (BIFF 2/3/4) | ✔ | ✕ | ✕ |
|
||||
|
||||
Asterisks (*) mark features that are not supported by the file formats. Numbers
|
||||
supports plaintext threaded comments but does not support Excel styled comments.
|
||||
X (✕) marks features that are not supported by the file formats. For example,
|
||||
the NUMBERS file format supports plaintext threaded comments but does not
|
||||
support Excel styled comments or Excel legacy notes.
|
||||
|
||||
The letter R (R) marks features parsed but not written in the format.
|
||||
|
||||
:::note
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) supports comment rich text and styling.
|
||||
|
||||
:::
|
||||
|
||||
</details>
|
||||
|
||||
## Basic Structure
|
||||
@ -45,12 +57,12 @@ For example, the following snippet appends a cell comment into cell `A1`:
|
||||
var cell = ws["A1"];
|
||||
|
||||
/* create comment array if it does not exist */
|
||||
if(!cell.c) ws.A1.c = [];
|
||||
if(!cell.c) cell.c = [];
|
||||
|
||||
/* create a comment part */
|
||||
var comment_part = {
|
||||
a:"SheetJS",
|
||||
t:"I'm a little comment, short and stout!"
|
||||
a: "SheetJS",
|
||||
t: "I'm a little comment, short and stout!"
|
||||
};
|
||||
|
||||
/* Add comment part to the comment array */
|
||||
|
@ -27,6 +27,18 @@ It also supports NodeJS, ExtendScript applications, and Chromium extensions.
|
||||
If `options` is omitted or if `bookType` is missing from the `options` object,
|
||||
the output file format will be deduced from the filename extension.
|
||||
|
||||
**`XLSX.writeXLSX(wb, options)`**
|
||||
|
||||
**`XLSX.writeFileXLSX(wb, filename, options)`**
|
||||
|
||||
`writeXLSX` and `writeFileXLSX` are limited versions of `write` and `writeFile`.
|
||||
They support writing to the XLSX file format.
|
||||
|
||||
For websites that exclusively export to XLSX, these functions can reduce the
|
||||
size of the production site. The general `write` and `writeFile` functions are
|
||||
more appropriate when exporting to XLS or XLSB or other formats.
|
||||
|
||||
|
||||
<details><summary><b>NodeJS-specific methods</b> (click to show)</summary>
|
||||
|
||||
**`XLSX.writeFileAsync(filename, wb, cb)`**
|
||||
|
407
docz/docs/08-api/07-utilities/01-array.md
Normal file
407
docz/docs/08-api/07-utilities/01-array.md
Normal file
@ -0,0 +1,407 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
title: Arrays of Data
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
Arrays of objects are a common data format in JavaScript database connectors
|
||||
and other general data sources.
|
||||
|
||||
Numeric datasets commonly use arrays of arrays of numbers.
|
||||
|
||||
:::note
|
||||
|
||||
The examples are based on the following worksheet:
|
||||
|
||||
<table>
|
||||
<tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr>
|
||||
<tr><td>1</td><td>2</td><td> </td><td> </td><td>5</td><td>6</td><td>7</td></tr>
|
||||
<tr><td>2</td><td>3</td><td> </td><td> </td><td>6</td><td>7</td><td>8</td></tr>
|
||||
<tr><td>3</td><td>4</td><td> </td><td> </td><td>7</td><td>8</td><td>9</td></tr>
|
||||
<tr><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td></tr>
|
||||
</table>
|
||||
|
||||
:::
|
||||
|
||||
## Array of Arrays Input
|
||||
|
||||
**Create a worksheet from an array of arrays**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|
||||
The example worksheet can be generated with:
|
||||
|
||||
```js
|
||||
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**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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) |
|
||||
| -1 | Append 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`:
|
||||
|
||||
```js
|
||||
/* 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**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`header` | | Use specified field order (default `Object.keys`) ** |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`nullError` | false | If 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:
|
||||
|
||||
```js
|
||||
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:
|
||||
|
||||
```js
|
||||
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:
|
||||
|
||||
```js
|
||||
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`:
|
||||
|
||||
```js
|
||||
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`:
|
||||
|
||||
```js
|
||||
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**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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) |
|
||||
| -1 | Append 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`:
|
||||
|
||||
```js
|
||||
/* 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:
|
||||
|
||||
```jsx live
|
||||
function SheetJSHeaderOrder() {
|
||||
/* Use shared header */
|
||||
const header = [];
|
||||
const ws1 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header});
|
||||
XLSX.utils.sheet_add_json(ws1, [ {D: 1, C: 4}, ], {header, origin: -1, skipHeader: true});
|
||||
|
||||
/* only use header in first call */
|
||||
const ws2 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header:[]});
|
||||
XLSX.utils.sheet_add_json(ws2, [ {D: 1, C: 4}, ], {origin: -1, skipHeader: true});
|
||||
|
||||
return (<pre>
|
||||
<b>Objects</b>
|
||||
{"\n[\n { C: 2, D: 3 },\n { D: 1, C: 4 } // different key order\n]\n"}<br/>
|
||||
<b>Worksheet when same `header` array is passed to `sheet_add_json`</b>
|
||||
<div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws1)}}/>
|
||||
<i>New contents of `header`</i><br/>
|
||||
{JSON.stringify(header)}<br/>
|
||||
<br/>
|
||||
<b>Worksheet when no `header` property is passed to `sheet_add_json`</b>
|
||||
<div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws2)}}/>
|
||||
</pre>)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Array Output
|
||||
|
||||
<Tabs>
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
|
||||
```js
|
||||
var arr = XLSX.utils.sheet_to_json(ws, opts);
|
||||
|
||||
var aoa = XLSX.utils.sheet_to_json(ws, {header: 1, ...other_opts});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript">
|
||||
|
||||
:::caution
|
||||
|
||||
TypeScript types are purely informational. They are not included at run time
|
||||
and do not influence the behavior of the `sheet_to_json` function.
|
||||
|
||||
**`sheet_to_json` does not perform field validation!**
|
||||
|
||||
:::
|
||||
|
||||
The main type signature treats each row as `any`:
|
||||
|
||||
```ts
|
||||
const data: any[] = XLSX.utils.sheet_to_json(ws, opts);
|
||||
```
|
||||
|
||||
The `any[][]` overload is designed for use with `header: 1` (array of arrays):
|
||||
|
||||
```ts
|
||||
const aoa: any[][] = XLSX.utils.sheet_to_json(ws, { header: 1, ...other_opts });
|
||||
```
|
||||
|
||||
An interface can be passed as a generic parameter. `sheet_to_json` will still
|
||||
return an array of plain objects (the types do not affect runtime behavior):
|
||||
|
||||
```ts
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
const data: President[] = XLSX.utils.sheet_to_json<President>(ws);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
`XLSX.utils.sheet_to_json` generates an array of JS objects. The function takes
|
||||
an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`raw` | `true` | Use raw values (true) or formatted strings (false) |
|
||||
|`range` | ** | Override Range (see table below) |
|
||||
|`header` | | Control output format (see table below) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`defval` | | Use 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:
|
||||
|
||||
| `range` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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:
|
||||
|
||||
| `header` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| `1` | Generate an array of arrays |
|
||||
| `"A"` | Row object keys are literal column labels |
|
||||
| array of strings | Use 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:
|
||||
|
||||
```jsx live
|
||||
function SheetJSToJSON() {
|
||||
/* original data */
|
||||
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]
|
||||
]);
|
||||
|
||||
/* display JS objects with some whitespace */
|
||||
const aoo = o => o.map(r => " " + JSON.stringify(r).replace(/,"/g, ', "').replace(/:/g, ": ").replace(/"([A-Za-z_]\w*)":/g, '$1:')).join("\n");
|
||||
const aoa = o => o.map(r => " " + JSON.stringify(r).replace(/,/g, ', ').replace(/null/g, "")).join("\n");
|
||||
|
||||
return ( <pre>
|
||||
<b>Worksheet (as HTML)</b>
|
||||
<div dangerouslySetInnerHTML={{__html: XLSX.utils.sheet_to_html(ws)}}/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: 1 {'}'}) [array of arrays]</b><br/>
|
||||
[<br/>{aoa(XLSX.utils.sheet_to_json(ws, { header: 1 }))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws) [objects with header disambiguation]</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: "A" {'}'}) [column names as keys]</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: "A" }))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: ["A","E","I","O","U","6","9"] {'}'})</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: ["A","E","I","O","U","6","9"] }))}<br/>]<br/>
|
||||
</pre> );
|
||||
}
|
||||
```
|
@ -19,6 +19,8 @@ HTML format and HTML table utilities.
|
||||
|
||||
## HTML Table Output
|
||||
|
||||
**Display worksheet data in a HTML table**
|
||||
|
||||
```js
|
||||
var html = XLSX.utils.sheet_to_html(ws, opts);
|
||||
```
|
||||
|
@ -4,25 +4,57 @@ title: Utility Functions
|
||||
pagination_prev: api/write-options
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
The utility functions in this section fall into two categories:
|
||||
|
||||
The `sheet_to_*` functions accept a worksheet and an optional options object.
|
||||
**Data Packaging**
|
||||
|
||||
The `*_to_sheet` functions accept a data object and an optional options object.
|
||||
The "Input" functions create SheetJS data structures (worksheets or workbooks)
|
||||
from rows of data or other common JS data representations
|
||||
|
||||
The `sheet_add_*` functions accept worksheet, data, and optional options.
|
||||
These functions are paired with `write` or `writeFile` to create exports. For
|
||||
example, the following diagram shows the steps to export an HTML TABLE to XLSX:
|
||||
|
||||
The examples are based on the following worksheet:
|
||||
```mermaid
|
||||
flowchart LR
|
||||
html{{HTML\nTABLE}}
|
||||
ws(SheetJS\nWorksheet)
|
||||
wb(SheetJS\nWorkbook)
|
||||
file[(workbook\nfile)]
|
||||
html --> |table_to_sheet\n\n| ws
|
||||
ws --> |book_new\nbook_append_sheet| wb
|
||||
wb --> |writeFile\n\n| file
|
||||
```
|
||||
|
||||
<table>
|
||||
<tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr>
|
||||
<tr><td>1</td><td>2</td><td> </td><td> </td><td>5</td><td>6</td><td>7</td></tr>
|
||||
<tr><td>2</td><td>3</td><td> </td><td> </td><td>6</td><td>7</td><td>8</td></tr>
|
||||
<tr><td>3</td><td>4</td><td> </td><td> </td><td>7</td><td>8</td><td>9</td></tr>
|
||||
<tr><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td></tr>
|
||||
</table>
|
||||
**Data Extraction**
|
||||
|
||||
The "Output" functions extract data from worksheets to friendlier structures.
|
||||
|
||||
These functions are paired with `read` or `readFile` to process data from files.
|
||||
The following diagram shows the steps to generate an HTML TABLE from a URL:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
url[(Remote\nFile)]
|
||||
ab[(Data\nArrayBuffer)]
|
||||
wb(SheetJS\nWorkbook)
|
||||
ws(SheetJS\nWorksheet)
|
||||
html{{HTML\nTABLE}}
|
||||
url --> |fetch\n\n| ab
|
||||
ab --> |read\n\n| wb
|
||||
wb --> |wb.Sheets\nselect sheet| ws
|
||||
ws --> |sheet_to_html\nfirst worksheet| html
|
||||
```
|
||||
|
||||
|
||||
## Array Output
|
||||
|
||||
**Generate rows of data from a worksheet**
|
||||
|
||||
```js
|
||||
var arr = XLSX.utils.sheet_to_json(ws, opts);
|
||||
```
|
||||
|
||||
[**This functions is described in a dedicated page**](/docs/api/utilities/array#array-of-objects-input)
|
||||
|
||||
## Array of Arrays Input
|
||||
|
||||
@ -32,80 +64,13 @@ The examples are based on the following worksheet:
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|
||||
The example worksheet can be generated with:
|
||||
|
||||
```js
|
||||
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**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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) |
|
||||
| -1 | Append 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`:
|
||||
|
||||
```js
|
||||
/* 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});
|
||||
```
|
||||
[**These functions are described in a dedicated page**](/docs/api/utilities/array#array-of-arrays-input)
|
||||
|
||||
## Array of Objects Input
|
||||
|
||||
@ -115,312 +80,63 @@ XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`header` | | Use specified field order (default `Object.keys`) ** |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`nullError` | false | If 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:
|
||||
|
||||
```js
|
||||
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:
|
||||
|
||||
```js
|
||||
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:
|
||||
|
||||
```js
|
||||
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`:
|
||||
|
||||
```js
|
||||
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`:
|
||||
|
||||
```js
|
||||
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**
|
||||
|
||||
```js
|
||||
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 Name | Default | Description |
|
||||
| :---------- | :-----: | :--------------------------------------------------- |
|
||||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`nullError` | false | If true, emit `#NULL!` error cells for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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) |
|
||||
| -1 | Append 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`:
|
||||
|
||||
```js
|
||||
/* 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:
|
||||
|
||||
```jsx live
|
||||
function SheetJSHeaderOrder() {
|
||||
/* Use shared header */
|
||||
const header = [];
|
||||
const ws1 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header});
|
||||
XLSX.utils.sheet_add_json(ws1, [ {D: 1, C: 4}, ], {header, origin: -1, skipHeader: true});
|
||||
|
||||
/* only use header in first call */
|
||||
const ws2 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header:[]});
|
||||
XLSX.utils.sheet_add_json(ws2, [ {D: 1, C: 4}, ], {origin: -1, skipHeader: true});
|
||||
|
||||
return (<pre>
|
||||
<b>Objects</b>
|
||||
{"\n[\n { C: 2, D: 3 },\n { D: 1, C: 4 } // different key order\n]\n"}<br/>
|
||||
<b>Worksheet when same `header` array is passed to `sheet_add_json`</b>
|
||||
<div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws1)}}/>
|
||||
<i>New contents of `header`</i><br/>
|
||||
{JSON.stringify(header)}<br/>
|
||||
<br/>
|
||||
<b>Worksheet when no `header` property is passed to `sheet_add_json`</b>
|
||||
<div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws2)}}/>
|
||||
</pre>)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
[**These functions are described in a dedicated page**](/docs/api/utilities/array#array-of-objects-input)
|
||||
|
||||
## HTML Table Input
|
||||
|
||||
[**This has been moved to a separate page**](/docs/api/utilities/html#html-table-input)
|
||||
**Create a worksheet or workbook from a TABLE element**
|
||||
|
||||
### Value Override
|
||||
```js
|
||||
var ws = XLSX.utils.table_to_sheet(elt, opts);
|
||||
var wb = XLSX.utils.table_to_book(elt, opts);
|
||||
```
|
||||
|
||||
[**This has been moved to a separate page**](/docs/api/utilities/html#value-override)
|
||||
**Add data from a TABLE element to an existing worksheet**
|
||||
|
||||
## Delimiter-Separated Output
|
||||
```js
|
||||
XLSX.utils.sheet_add_dom(ws, elt, opts);
|
||||
```
|
||||
|
||||
[**This has been moved to a separate page**](/docs/api/utilities/csv)
|
||||
[**These functions are described in a dedicated page**](/docs/api/utilities/html#html-table-input)
|
||||
|
||||
## HTML Output
|
||||
|
||||
[**This has been moved to a separate page**](/docs/api/utilities/html#html-table-output)
|
||||
|
||||
## Array Output
|
||||
|
||||
<Tabs>
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
**Display worksheet data in a HTML table**
|
||||
|
||||
```js
|
||||
var arr = XLSX.utils.sheet_to_json(ws, opts);
|
||||
|
||||
var aoa = XLSX.utils.sheet_to_json(ws, {header: 1, ...other_opts});
|
||||
var html = XLSX.utils.sheet_to_html(ws, opts);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript">
|
||||
[**This function are described in a dedicated page**](/docs/api/utilities/html#html-table-output)
|
||||
|
||||
:::caution
|
||||
## Delimiter-Separated Output
|
||||
|
||||
TypeScript types are purely informational. They are not included at run time
|
||||
and do not influence the behavior of the `sheet_to_json` method.
|
||||
**Generate CSV from a Worksheet**
|
||||
|
||||
**`sheet_to_json` does not perform field validation!**
|
||||
|
||||
:::
|
||||
|
||||
The main type signature treats each row as `any`:
|
||||
|
||||
```ts
|
||||
const data: any[] = XLSX.utils.sheet_to_json(ws, opts);
|
||||
```js
|
||||
var csv = XLSX.utils.sheet_to_csv(ws, opts);
|
||||
```
|
||||
|
||||
The `any[][]` overload is designed for use with `header: 1` (array of arrays):
|
||||
**Export worksheet data in "UTF-16 Text" or Tab-Separated Values (TSV)**
|
||||
|
||||
```ts
|
||||
const aoa: any[][] = XLSX.utils.sheet_to_json(ws, { header: 1, ...other_opts });
|
||||
```js
|
||||
var txt = XLSX.utils.sheet_to_txt(ws, opts);
|
||||
```
|
||||
|
||||
An interface can be passed as a generic parameter. `sheet_to_json` will still
|
||||
return an array of plain objects (the types do not affect runtime behavior):
|
||||
|
||||
```ts
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
const data: President[] = XLSX.utils.sheet_to_json<President>(ws);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
`XLSX.utils.sheet_to_json` generates an array of JS objects. The function takes
|
||||
an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`raw` | `true` | Use raw values (true) or formatted strings (false) |
|
||||
|`range` | ** | Override Range (see table below) |
|
||||
|`header` | | Control output format (see table below) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`defval` | | Use 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:
|
||||
|
||||
| `range` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (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:
|
||||
|
||||
| `header` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| `1` | Generate an array of arrays |
|
||||
| `"A"` | Row object keys are literal column labels |
|
||||
| array of strings | Use 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:
|
||||
|
||||
```jsx live
|
||||
function SheetJSToJSON() {
|
||||
/* original data */
|
||||
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]
|
||||
]);
|
||||
|
||||
/* display JS objects with some whitespace */
|
||||
const aoo = o => o.map(r => " " + JSON.stringify(r).replace(/,"/g, ', "').replace(/:/g, ": ").replace(/"([A-Za-z_]\w*)":/g, '$1:')).join("\n");
|
||||
const aoa = o => o.map(r => " " + JSON.stringify(r).replace(/,/g, ', ').replace(/null/g, "")).join("\n");
|
||||
|
||||
return ( <pre>
|
||||
<b>Worksheet (as HTML)</b>
|
||||
<div dangerouslySetInnerHTML={{__html: XLSX.utils.sheet_to_html(ws)}}/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: 1 {'}'}) [array of arrays]</b><br/>
|
||||
[<br/>{aoa(XLSX.utils.sheet_to_json(ws, { header: 1 }))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws) [objects with header disambiguation]</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: "A" {'}'}) [column names as keys]</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: "A" }))}<br/>]<br/><br/>
|
||||
<b>XLSX.utils.sheet_to_json(ws, {'{'} header: ["A","E","I","O","U","6","9"] {'}'})</b><br/>
|
||||
[<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: ["A","E","I","O","U","6","9"] }))}<br/>]<br/>
|
||||
</pre> );
|
||||
}
|
||||
```
|
||||
[**These functions are described in a dedicated page**](/docs/api/utilities/csv)
|
||||
|
||||
## Formulae Output
|
||||
|
||||
[**This has been moved to a separate page**](/docs/api/utilities/formulae)
|
||||
**Extract all formulae from a worksheet**
|
||||
|
||||
```js
|
||||
var fmla_arr = XLSX.utils.sheet_to_formulae(ws);
|
||||
```
|
||||
|
||||
[**This function is described in a dedicated page**](/docs/api/utilities/formulae)
|
@ -53,6 +53,19 @@ _Cell and cell address manipulation:_
|
||||
- `encode_cell / decode_cell` converts cell addresses.
|
||||
- `encode_range / decode_range` converts cell ranges.
|
||||
|
||||
**["Arrays of Data" section of "Utility Functions"](/docs/api/utilities/array)**
|
||||
|
||||
_Importing Data:_
|
||||
|
||||
- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet.
|
||||
- `json_to_sheet` converts an array of JS objects to a worksheet.
|
||||
- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet.
|
||||
- `sheet_add_json` adds an array of JS objects to an existing worksheet.
|
||||
|
||||
_Exporting Data:_
|
||||
|
||||
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
|
||||
|
||||
**["HTML" section of "Utility Functions"](/docs/api/utilities/html)**
|
||||
|
||||
_Reading from HTML:_
|
||||
@ -85,17 +98,6 @@ _Workbook Operations:_
|
||||
- `book_new` creates an empty workbook
|
||||
- `book_append_sheet` adds a worksheet to a workbook
|
||||
|
||||
_Importing Data:_
|
||||
|
||||
- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet.
|
||||
- `json_to_sheet` converts an array of JS objects to a worksheet.
|
||||
- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet.
|
||||
- `sheet_add_json` adds an array of JS objects to an existing worksheet.
|
||||
|
||||
_Exporting Data:_
|
||||
|
||||
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
|
||||
|
||||
_Miscellaneous_
|
||||
|
||||
- `format_cell` generates the text value for a cell (using number formats).
|
||||
|
@ -48,6 +48,10 @@ const config = {
|
||||
googleAnalytics: {
|
||||
trackingID: 'UA-36810333-1',
|
||||
anonymizeIP: true
|
||||
},
|
||||
gtag: {
|
||||
trackingID: 'G-0TSXVXRHM6',
|
||||
anonymizeIP: true
|
||||
}
|
||||
}),
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user