forked from sheetjs/docs.sheetjs.com
inout
This commit is contained in:
parent
9acdfab935
commit
f3b4f8067a
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user