This commit is contained in:
SheetJS 2022-06-21 08:26:53 -04:00
parent 9acdfab935
commit f3b4f8067a
8 changed files with 383 additions and 199 deletions

@ -44,7 +44,9 @@ InDesign
IndexedDB
JavaScriptCore
LocalStorage
MacOS
NestJS
NetSuite
NPM
Nuxt
PhantomJS
@ -55,6 +57,7 @@ RequireJS
Rollup
SessionStorage
SQLite
SuiteScripts
SystemJS
VueJS
WebKit

@ -45,7 +45,9 @@ Deno scripts must be invoked with `--allow-read` to read from the filesystem.
#### Examples
Here are a few common scenarios (click on each subtitle to see the code):
Here are a few common scenarios (click on each subtitle to see the code).
The [demos](../getting-started/demos) cover special deployments in more detail.
### Example: Local File
@ -63,16 +65,14 @@ var XLSX = require("xlsx");
var workbook = XLSX.readFile("test.xlsx");
```
For Node ESM, the `readFile` helper is not enabled. Instead, `fs.readFileSync`
should be used to read the file data as a `Buffer` for use with `XLSX.read`:
For Node ESM, `fs` must be loaded manually:
```js
import { readFileSync } from "fs";
import { read } from "xlsx/xlsx.mjs";
import * as fs from "fs";
import { readFile, set_fs } from "xlsx/xlsx.mjs";
set_fs(fs);
const buf = readFileSync("test.xlsx");
/* buf is a Buffer */
const workbook = read(buf);
const workbook = readFile("test.xlsx");
```
</TabItem>
@ -108,17 +108,27 @@ shows a complete example and details the required version-specific settings.
</TabItem>
<TabItem value="reactnative" label="React Native">
:::caution
React Native does not provide a way to read files from the filesystem. A
separate third-party library must be used.
Since React Native internals change between releases, libraries may only work
with specific versions of React Native. Project documentation should be
consulted before picking a library.
:::caution
The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app.
Since React Native does not provide a way to read files from the filesystem, a
third-party library must be used. The following libraries have been tested:
The following libraries have been tested:
- [`react-native-file-access`](https://npm.im/react-native-file-access)
The `base64` encoding returns strings compatible with the `base64` type:
```js
import XLSX from "xlsx";
import * as XLSX from "xlsx";
import { FileSystem } from "react-native-file-access";
const b64 = await FileSystem.readFile(path, "base64");
@ -131,7 +141,7 @@ const workbook = XLSX.read(b64, {type: "base64"});
The `ascii` encoding returns binary strings compatible with the `binary` type:
```js
import XLSX from "xlsx";
import * as XLSX from "xlsx";
import { readFile } from "react-native-fs";
const bstr = await readFile(path, "ascii");
@ -293,8 +303,11 @@ The [`server` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/server)
### Example: Remote File
<details>
<summary><b>Fetching a file in the web browser ("Ajax")</b> (click to show)</summary>
This example focuses on fetching files ("Ajax" in browser parlance) using APIs
like `XMLHttpRequest` and `fetch` as well as third-party libraries.
<Tabs>
<TabItem value="browser" label="Browser">
For modern websites targeting Chrome 42+, `fetch` is recommended:
@ -334,11 +347,8 @@ The [`xhr` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) incl
<http://oss.sheetjs.com/sheetjs/ajax.html> shows fallback approaches for IE6+.
</details>
<details>
<summary><b>Download files in a NodeJS process</b> (click to show)</summary>
</TabItem>
<TabItem value="nodejs" label="NodeJS">
Node 17.5 and 18.0 have native support for fetch:
@ -380,10 +390,8 @@ const axios = require("axios");
})();
```
</details>
<details>
<summary><b>Download files in an Electron app</b> (click to show)</summary>
</TabItem>
<TabItem value="electron" label="Electron">
The `net` module in the main process can make HTTP/HTTPS requests to external
resources. Responses should be manually concatenated using `Buffer.concat`:
@ -405,37 +413,39 @@ req.on("response", (res) => {
req.end();
```
</details>
</TabItem>
</Tabs>
### Example: Readable Streams
<details>
<summary><b>Readable Streams in NodeJS</b> (click to show)</summary>
:::caution
When dealing with Readable Streams, the easiest approach is to buffer the stream
and process the whole thing at the end:
The recommended approach is to buffer streams in memory and process once all of
the data has been collected. A proper streaming parse is technically impossible.
```js
var fs = require("fs");
var XLSX = require("xlsx");
<details><summary><b>Technical details</b> (click to show)</summary>
function process_RS(stream, cb) {
var buffers = [];
stream.on("data", function(data) { buffers.push(data); });
stream.on("end", function() {
var buffer = Buffer.concat(buffers);
var workbook = XLSX.read(buffer, {type:"buffer"});
XLSX, XLSB, NUMBERS, and ODS files are ultimately ZIP files that contain binary
and XML entries. The ZIP file format stores the table of contents ("end of
central directory" record) at the end of the file, so a proper parse of a ZIP
file requires scanning from the end. Streams do not provide random access into
the data, so the only correct approach involves buffering the entire stream.
/* DO SOMETHING WITH workbook IN THE CALLBACK */
cb(workbook);
});
}
```
XLS, XLR, QPW, and Works 4 for Mac files use the "Compound File Binary Format".
It is a container format that can hold multiple "files" and "folders". It also
has a table of contents ("directory sectors") but these can be placed anywhere
in the file! The only correct approach involves buffering enough of the stream
to find the full table of contents, but the added complexity has little benefit
when testing against real-world files generated by various versions of Excel and
other tools.
</details>
<details>
<summary><b>ReadableStream in the browser</b> (click to show)</summary>
:::
<Tabs>
<TabItem value="browser" label="Browser">
When dealing with `ReadableStream`, the easiest approach is to buffer the stream
and process the whole thing at the end:
@ -470,7 +480,31 @@ const data = await process_RS(stream);
const workbook = XLSX.read(data, {type: 'array'});
```
</details>
</TabItem>
<TabItem value="nodejs" label="NodeJS">
When dealing with Readable Streams, the easiest approach is to buffer the stream
and process the whole thing at the end:
```js
var fs = require("fs");
var XLSX = require("xlsx");
function process_RS(stream, cb) {
var buffers = [];
stream.on("data", function(data) { buffers.push(data); });
stream.on("end", function() {
var buffer = Buffer.concat(buffers);
var workbook = XLSX.read(buffer, {type:"buffer"});
/* DO SOMETHING WITH workbook IN THE CALLBACK */
cb(workbook);
});
}
```
</TabItem>
</Tabs>
More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/)
@ -538,9 +572,9 @@ from a JSON Endpoint and Generate a Workbook"
[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive
data grid for previewing and modifying structured data in the web browser. The
[`xspreadsheet` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet) includes a sample script with the
`xtos` function for converting from x-spreadsheet data object to a workbook.
<https://oss.sheetjs.com/sheetjs/x-spreadsheet> is a live demo.
[demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet)
includes a sample script with the `xtos` function for converting from
x-spreadsheet to a workbook. Live Demo: <https://oss.sheetjs.com/sheetjs/x-spreadsheet>
<details>
<summary><b>Records from a database query (SQL or no-SQL)</b> (click to show)</summary>

@ -4,9 +4,13 @@ sidebar_position: 5
# Data Export
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Writing Workbooks
#### API
### API
_Generate spreadsheet bytes (file) from data_
@ -32,9 +36,8 @@ The `writeFile` method packages the data and attempts to save the new file. The
export file format is determined by the extension of `filename` (`SheetJS.xlsx`
signals XLSX export, `SheetJS.xlsb` signals XLSB export, etc).
The `writeFile` method uses platform-specific APIs to initiate the file save. In
NodeJS, `fs.readFileSync` can create a file. In the web browser, a download is
attempted using the HTML5 `download` attribute, with fallbacks for IE.
The second `opts` argument is optional. ["Writing Options"](../api/write-options)
covers the supported properties and behaviors.
_Generate and attempt to save an XLSX file_
@ -50,71 +53,26 @@ referencing the other export functions.
The second `opts` argument is optional. ["Writing Options"](../api/write-options)
covers the supported properties and behaviors.
:::note
The `writeFile` and `writeFileXLSX` methods uses platform-specific APIs to save
files. The APIs do not generally provide feedback on whether files were created.
:::
#### Examples
<details>
<summary><b>Local file in a NodeJS server</b> (click to show)</summary>
Here are a few common scenarios (click on each subtitle to see the code).
`writeFile` uses `fs.writeFileSync` in server environments:
The [demos](../getting-started/demos) cover special deployments in more detail.
```js
var XLSX = require("xlsx");
### Example: Local File
/* output format determined by filename */
XLSX.writeFile(workbook, "out.xlsb");
```
`XLSX.writeFile` supports writing local files in platforms like NodeJS. In other
platforms like React Native, `XLSX.write` should be called with file data.
For Node ESM, the `writeFile` helper is not enabled. Instead, `fs.writeFileSync`
should be used to write the file data to a `Buffer` for use with `XLSX.write`:
```js
import { writeFileSync } from "fs";
import { write } from "xlsx/xlsx.mjs";
const buf = write(workbook, {type: "buffer", bookType: "xlsb"});
/* buf is a Buffer */
const workbook = writeFileSync("out.xlsb", buf);
```
</details>
<details>
<summary><b>Local file in a Deno application</b> (click to show)</summary>
`writeFile` uses `Deno.writeFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
XLSX.writeFile(workbook, "test.xlsx");
```
Applications writing files must be invoked with the `--allow-write` flag. The
[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples
</details>
<details>
<summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary>
`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets.
The specified path should be an absolute path:
```js
#include "xlsx.extendscript.js"
/* output format determined by filename */
XLSX.writeFile(workbook, "out.xlsx");
/* at this point, out.xlsx is a file that you can distribute */
```
The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example.
</details>
<details>
<summary><b>Download a file in the browser to the user machine</b> (click to show)</summary>
<Tabs>
<TabItem value="browser" label="Browser">
`XLSX.writeFile` wraps a few techniques for triggering a file save:
@ -132,10 +90,22 @@ XLSX.writeFile(workbook, "out.xlsb");
/* at this point, out.xlsb will have been downloaded */
```
</details>
<details>
<summary><b>Download a file in legacy browsers</b> (click to show)</summary>
<summary><b>SWF workaround for Windows 95+</b> (click to show)</summary>
:::warning
Each moving part in this solution has been deprecated years ago:
- Adobe stopped supporting Flash Player at the end of 2020
- Microsoft stopped supporting IE8 in 2019 and stopped supporting IE9 in 2020
- `Downloadify` support ended in 2010 and `SWFObject` support ended in 2016
New projects should strongly consider requiring modern browsers. This info is
provided on an "as is" basis and there is no realistic way to provide support
given that every related vendor stopped providing support for their software.
:::
`XLSX.writeFile` techniques work for most modern browsers as well as older IE.
For much older browsers, there are workarounds implemented by wrapper libraries.
@ -157,28 +127,123 @@ The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/)
</details>
<details>
<summary><b>Browser upload file (ajax)</b> (click to show)</summary>
</TabItem>
<TabItem value="nodejs" label="NodeJS">
A complete example using XHR is [included in the XHR demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/), along
with examples for fetch and wrapper libraries. This example assumes the server
can handle Base64-encoded files (see the demo for a basic nodejs server):
`writeFile` uses `fs.writeFileSync` under the hood:
```js
/* in this example, send a base64 string to the server */
var wopts = { bookType:"xlsx", bookSST:false, type:"base64" };
var XLSX = require("xlsx");
var wbout = XLSX.write(workbook,wopts);
var req = new XMLHttpRequest();
req.open("POST", "/upload", true);
var formdata = new FormData();
formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name
formdata.append("data", wbout); // <-- `data` holds the base64-encoded data
req.send(formdata);
/* output format determined by filename */
XLSX.writeFile(workbook, "out.xlsb");
```
</details>
For Node ESM, `fs` must be loaded manually:
```js
import * as fs from "fs";
import { writeFile, set_fs } from "xlsx/xlsx.mjs";
set_fs(fs);
/* output format determined by filename */
writeFile(workbook, "out.xlsb");
```
</TabItem>
<TabItem value="deno" label="Deno">
`writeFile` uses `Deno.writeFileSync` under the hood:
<pre><code parentName="pre" {...{"className": "language-ts"}}>{`\
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';
XLSX.writeFile(workbook, "test.xlsx");`}</code></pre>
Applications writing files must be invoked with the `--allow-write` flag. The
[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples
</TabItem>
<TabItem value="electron" label="Electron">
`writeFile` can be used in the renderer process:
```js
/* From the renderer process */
var XLSX = require("xlsx");
XLSX.writeFile(workbook, "out.xlsb");
```
Electron APIs have changed over time. The [`electron` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/)
shows a complete example and details the required version-specific settings.
</TabItem>
<TabItem value="reactnative" label="React Native">
:::caution
React Native does not provide a way to write files to the filesystem. A
separate third-party library must be used.
Since React Native internals change between releases, libraries may only work
with specific versions of React Native. Project documentation should be
consulted before picking a library.
:::
The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app.
The following libraries have been tested:
- [`react-native-file-access`](https://npm.im/react-native-file-access)
The `base64` encoding returns strings compatible with the `base64` type:
```js
import * as XLSX from "xlsx";
import { Dirs, FileSystem } from "react-native-file-access";
const DDP = Dirs.DocumentDir + "/";
const b64 = XLSX.write(workbook, {type:'base64', bookType:"xlsx"});
/* b64 is a base64 string */
await FileSystem.writeFile(DDP + "sheetjs.xlsx", b64, "base64");
```
- [`react-native-fs`](https://npm.im/react-native-fs)
The `ascii` encoding accepts binary strings compatible with the `binary` type:
```js
import * as XLSX from "xlsx";
import { writeFile, DocumentDirectoryPath } from "react-native-fs";
const DDP = DocumentDirectoryPath + "/";
const bstr = XLSX.write(workbook, {type:'binary', bookType:"xlsx"});
/* bstr is a binary string */
await writeFile(DDP + "sheetjs.xlsx", bstr, "ascii");
```
</TabItem>
<TabItem value="extendscript" label="Photoshop">
`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets.
The specified path should be an absolute path:
```js
#include "xlsx.extendscript.js"
/* Ask user to select path */
var thisFile = File.saveDialog("Select an output file", "*.xlsx;*.xls");
/* output format determined by filename */
XLSX.writeFile(workbook, thisFile.absoluteURI);
```
The [`extendscript` demo](../getting-started/demos/extendscript) includes a more complex example.
</TabItem>
<TabItem value="headless" label="Headless">
<details>
<summary><b>PhantomJS (Headless Webkit) File Generation</b> (click to show)</summary>
@ -203,55 +268,86 @@ to generate a workbook from HTML tables in a page in "Headless WebKit".
</details>
</TabItem>
</Tabs>
The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments.
### Example: Remote File
### Writing Examples
This example focuses on uploading files ("Ajax" in browser parlance) using APIs
like `XMLHttpRequest` and `fetch` as well as third-party libraries.
- <http://sheetjs.com/demos/table.html> exporting an HTML table
- <http://sheetjs.com/demos/writexlsx.html> generates a simple file
<Tabs>
<TabItem value="browser" label="Browser">
### Streaming Write
:::caution
The streaming write functions are available in the `XLSX.stream` object. They
take the same arguments as the normal write functions but return a NodeJS
Readable Stream.
Some platforms like Azure and AWS will attempt to parse POST request bodies as
UTF-8 strings before user code can see the data. This will result in corrupt
data parsed by the server. There are some workarounds, but the safest approach
is to adjust the server process or Lambda function to accept Base64 strings.
- `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`.
- `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`.
- `XLSX.stream.to_json` is the streaming version of `XLSX.utils.sheet_to_json`.
:::
<details>
<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary>
A complete example using XHR is [included in the XHR demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/), along
with examples for fetch and wrapper libraries. This example assumes the server
can handle Base64-encoded files (see the demo for a basic nodejs server):
```js
var output_file_name = "out.csv";
var stream = XLSX.stream.to_csv(worksheet);
stream.pipe(fs.createWriteStream(output_file_name));
/* in this example, send a base64 string to the server */
var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "base64" });
/* prepare data for POST */
var formdata = new FormData();
formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name
formdata.append("data", wbout); // <-- `data` holds the base64-encoded data
/* perform POST request */
var req = new XMLHttpRequest();
req.open("POST", "/upload", true);
req.send(formdata);
```
</details>
<details>
<summary><b>nodejs write JSON stream to screen</b> (click to show)</summary>
For servers that do not parse POST request bodies as UTF-8 strings, a `Blob` can
be generated from the `array` output:
```js
/* to_json returns an object-mode stream */
var stream = XLSX.stream.to_json(worksheet, {raw:true});
/* in this example, send a Blob to the server */
var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "array" });
/* the following stream converts JS objects to text via JSON.stringify */
var conv = new Transform({writableObjectMode:true});
conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); };
/* prepare data for POST */
var blob = new Blob([new Uint8Array(wbout)], {type:"application/octet-stream"});
var formdata = new FormData();
formdata.append("file", blob, "test.xlsx");
stream.pipe(conv); conv.pipe(process.stdout);
/* perform POST request */
fetch("/upload", { method: 'POST', body: formdata });
```
</details>
</TabItem>
<TabItem value="nodejs" label="NodeJS">
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.
`XLSX.write` with `type: "buffer"` will generate a NodeJS `Buffer` which can be
used with standard NodeJS approaches for uploading data.
### Generating JSON and JS Data
Node 17.5 and 18.0 have native support for fetch:
```js
const XLSX = require("xlsx");
const buf = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
var blob = new Blob([buf], {type:"application/octet-stream"});
var formdata = new FormData();
formdata.append("file", blob, "test.xlsx");
/* perform POST request */
fetch("https://thisis.a.test/upload", { method: 'POST', body: formdata });
```
</TabItem>
</Tabs>
## Generating JSON and JS Data
JSON and JS data tend to represent single worksheets. The utility functions in
this section work with single worksheets.
@ -263,7 +359,7 @@ names and whose values are worksheet objects.
The "first worksheet" is stored at `workbook.Sheets[workbook.SheetNames[0]]`.
#### API
### API
_Create an array of JS objects from a worksheet_
@ -287,14 +383,19 @@ With the `header: 1` option, the function exports an array of arrays of values.
#### Examples
### Example: Data Grids
<Tabs>
<TabItem value="js" label="Vanilla JS">
[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive
data grid for previewing and modifying structured data in the web browser. The
[`xspreadsheet` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet) includes a sample script with the
`stox` function for converting from a workbook to x-spreadsheet data object.
<https://oss.sheetjs.com/sheetjs/x-spreadsheet> is a live demo.
[demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet)
includes a sample script with the `stox` function for converting from
a workbook to x-spreadsheet. Live Demo: <https://oss.sheetjs.com/sheetjs/x-spreadsheet>
<details>
<summary><b>Previewing data in a React data grid</b> (click to show)</summary>
</TabItem>
<TabItem value="react" label="React">
[`react-data-grid`](https://adazzle.github.io/react-data-grid) is a data grid
built for React. It uses two properties: `rows` of data objects and `columns`
@ -314,7 +415,7 @@ export default function App() {
const [columns, setColumns] = useState([]);
const [rows, setRows] = useState([]);
useEffect(() => {(async () => {
const wb = read(await (await fetch(url)).arrayBuffer(), { WTF: 1 });
const wb = read(await (await fetch(url)).arrayBuffer());
/* use sheet_to_json with header: 1 to generate an array of arrays */
const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 });
@ -331,22 +432,23 @@ export default function App() {
}
```
</details>
<details>
<summary><b>Previewing data in a VueJS data grid</b> (click to show)</summary>
</TabItem>
<TabItem value="vue" label="VueJS">
[`vue3-table-lite`](https://linmasahiro.github.io/vue3-table-lite/dist/) is a
simple VueJS 3 data table. It is featured in the
[VueJS demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/).
</details>
</TabItem>
</Tabs>
### Example: Data Loading
<details>
<summary><b>Populating a database (SQL or no-SQL)</b> (click to show)</summary>
The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) includes examples of working with
databases and query results.
The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/)
includes examples of working with databases and query results.
</details>
@ -390,7 +492,7 @@ The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/)
</details>
### Generating HTML Tables
## Generating HTML Tables
#### API
@ -416,8 +518,10 @@ container.innerHTML = XLSX.utils.sheet_to_html(worksheet);
Combining with `fetch`, constructing a site from a workbook is straightforward:
<details>
<summary><b>Vanilla JS + HTML fetch workbook and generate table previews</b> (click to show)</summary>
<Tabs>
<TabItem value="js" label="Vanilla JS">
This example assigns the `innerHTML` of a DIV element:
```html
<body>
@ -447,15 +551,15 @@ Combining with `fetch`, constructing a site from a workbook is straightforward:
</body>
```
</details>
<details>
<summary><b>React fetch workbook and generate HTML table previews</b> (click to show)</summary>
</TabItem>
<TabItem value="react" label="React">
It is generally recommended to use a React-friendly workflow, but it is possible
to generate HTML and use it in React with `dangerouslySetInnerHTML`:
```jsx
import * as XLSX from 'xlsx';
function Tabeller(props) {
/* the workbook object is the state */
const [workbook, setWorkbook] = React.useState(XLSX.utils.book_new());
@ -479,10 +583,8 @@ function Tabeller(props) {
The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples.
</details>
<details>
<summary><b>VueJS fetch workbook and generate HTML table previews</b> (click to show)</summary>
</TabItem>
<TabItem value="vue" label="VueJS">
It is generally recommended to use a VueJS-friendly workflow, but it is possible
to generate HTML and use it in VueJS with the `v-html` directive:
@ -515,9 +617,10 @@ const S5SComponent = {
The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples.
</details>
</TabItem>
</Tabs>
### Generating Single-Worksheet Snapshots
## Generating Single-Worksheet Snapshots
The `sheet_to_*` functions accept a worksheet object.
@ -555,3 +658,42 @@ rendered in the form `cell=formula or value`. String literals are prefixed with
an apostrophe `'`, consistent with Excel's formula bar display.
["Formulae Output"](../api/utilities#formulae-output) describes the function in more detail.
## Streaming Write
The streaming write functions are available in the `XLSX.stream` object. They
take the same arguments as the normal write functions but return a NodeJS
Readable Stream.
- `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`.
- `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`.
- `XLSX.stream.to_json` is the streaming version of `XLSX.utils.sheet_to_json`.
<details>
<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary>
```js
var output_file_name = "out.csv";
var stream = XLSX.stream.to_csv(worksheet);
stream.pipe(fs.createWriteStream(output_file_name));
```
</details>
<details>
<summary><b>nodejs write JSON stream to screen</b> (click to show)</summary>
```js
/* to_json returns an object-mode stream */
var stream = XLSX.stream.to_json(worksheet, {raw:true});
/* the following stream converts JS objects to text via JSON.stringify */
var conv = new Transform({writableObjectMode:true});
conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); };
stream.pipe(conv); conv.pipe(process.stdout);
```
</details>
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.

@ -1,5 +1,5 @@
---
sidebar_position: 6
sidebar_position: 4
hide_table_of_contents: true
---

@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 5
---
# Contributing
@ -91,7 +91,7 @@ On Linux:
sudo apt-get install mercurial subversion
```
On MacOS, install using [Homebrew](https://brew.sh/):
On MacOS, install using [`brew`](https://brew.sh/):
```bash
brew install mercurial subversion
@ -128,7 +128,7 @@ cd modules; make; cd ..
make dist
```
4) (For deno testing) Install deno:
4) (For Deno testing) Install Deno:
```bash
curl -fsSL https://deno.land/install.sh | sh

@ -1,5 +1,5 @@
---
sidebar_position: 8
sidebar_position: 7
hide_table_of_contents: true
---

@ -1,5 +1,5 @@
---
sidebar_position: 9
sidebar_position: 8
hide_table_of_contents: true
---
@ -9,10 +9,9 @@ Some of our original research is documented at <https://oss.sheetjs.com/notes/>
The specifications list is non-exhaustive.
- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"
- Open Document Format for Office Applications Version 1.2 (29 September 2011)
- Worksheet File Format (From Lotus) December 1984
- Worksheet File Format (From Lotus) December 1984
- Open Document Format for Office Applications Version 1.2 (29 September 2011)
- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"
## Open Specifications Promise
@ -43,4 +42,10 @@ to sue. The documentation that falls under the promise are listed below.
- `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification
- `RTF`: Rich Text Format
</details>
</details>
## Other Resources
- ISBN 1556155212 "Excel Software Development Kit Version 4"
- ISBN 1556156324 "Excel Developer's Kit Version 5"

@ -61,7 +61,7 @@ document.getElementById("sheetjsexport").addEventListener('click', function() {
</details>
<details open><summary><b>Live Example</b> (click to show)</summary>
<details open><summary><b>Live Example</b> (click to hide)</summary>
```jsx live
/* The live editor requires this function wrapper */
@ -133,7 +133,7 @@ support for CSS styling and rich text.
</details>
<details><summary><b>Live Example</b> (click to hide)</summary>
<details><summary><b>Live Example</b> (click to show)</summary>
```jsx live
/* The live editor requires this function wrapper */