nits
This commit is contained in:
parent
a6a981226f
commit
22720fd7a6
@ -202,7 +202,7 @@ many additional features including massive data streaming, sorting and styling.
|
||||
|
||||
### Tabulator
|
||||
|
||||
[Tabulator](http://tabulator.info/docs/5.3/download#xlsx) includes deep support
|
||||
[Tabulator](https://tabulator.info/docs/5.4/download#xlsx) includes deep support
|
||||
through a special Export button. It handles the SheetJS operations internally.
|
||||
|
||||
|
||||
|
@ -100,7 +100,8 @@ In the following example, the script:
|
||||
|
||||
- generates a workbook object in the Web Worker
|
||||
- generates a XLSB file using `XLSX.write` in the Web Worker
|
||||
- sends the file (`Uint8Array`) to the main browser context
|
||||
- generates an object URL in the Web Worker
|
||||
- sends the object URL to the main browser context
|
||||
- performs a download action in the main browser context
|
||||
|
||||
```jsx live
|
||||
@ -124,11 +125,14 @@ SheetJS,in,Web,Workers
|
||||
1,2,3,4\`;
|
||||
const wb = XLSX.read(csv, { type: "string" });
|
||||
|
||||
/* Write XLSB data */
|
||||
/* Write XLSB data (Uint8Array) */
|
||||
const u8 = XLSX.write(wb, { bookType: "xlsb", type: "buffer" });
|
||||
|
||||
/* Generate URL */
|
||||
const url = URL.createObjectURL(new Blob([u8]));
|
||||
|
||||
/* Reply with result */
|
||||
postMessage({data: u8});
|
||||
postMessage({ url });
|
||||
} catch(e) {
|
||||
/* Pass the error message back */
|
||||
postMessage({error: String(e.message || e).bold() });
|
||||
@ -142,7 +146,7 @@ SheetJS,in,Web,Workers
|
||||
/* this mantra is the standard HTML5 download attribute technique */
|
||||
const a = document.createElement("a");
|
||||
a.download = "SheetJSWriteFileWorker.xlsb";
|
||||
a.href = URL.createObjectURL(new Blob([e.data.data]));
|
||||
a.href = e.data.url;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
@ -176,10 +180,10 @@ In the following example, the script:
|
||||
```jsx live
|
||||
function SheetJSDragDropWorker() {
|
||||
const [html, setHTML] = React.useState("");
|
||||
/* suppress default behavior for dragover and drop */
|
||||
/* suppress default behavior for drag and drop */
|
||||
function suppress(e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return ( <>
|
||||
<div onDragOver={suppress} onDrop={(e) => {
|
||||
<div onDragOver={suppress} onDragEnter={suppress} onDrop={(e) => {
|
||||
suppress(e);
|
||||
|
||||
/* this mantra embeds the worker source in the function */
|
||||
@ -188,7 +192,7 @@ function SheetJSDragDropWorker() {
|
||||
importScripts("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js");
|
||||
|
||||
/* this callback will run once the main context sends a message */
|
||||
self.addEventListener('message', async(e) => {
|
||||
self.addEventListener('message', (e) => {
|
||||
try {
|
||||
/* Read file data */
|
||||
const ab = new FileReaderSync().readAsArrayBuffer(e.data.file);
|
||||
|
@ -2,10 +2,11 @@
|
||||
title: Local File Access
|
||||
---
|
||||
|
||||
Reading and writing files require native support. `readFile` and `writeFile`
|
||||
include support for some approaches but do not support every API. When an API
|
||||
is not supported by `readFile` or `writeFile`, the underlying `read` and
|
||||
`write` methods can be used.
|
||||
Reading and writing files require native platform support. `XLSX.readFile` and
|
||||
`XLSX.writeFile` include support for some APIs.
|
||||
|
||||
For other APIs, user code can pass data to `XLSX.read` or use data generated by
|
||||
`XLSX.write` directly. Both methods work with a number of common storage types.
|
||||
|
||||
This demo looks at various web APIs. More specific approaches for deployments
|
||||
like mobile apps are covered in their respective demos.
|
||||
@ -35,20 +36,63 @@ Modern browser APIs typically use typed arrays or `Blob` or `File` structures.
|
||||
|
||||
_Reading Binary Data_
|
||||
|
||||
Given a `Blob` or `File`, the underlying data cannot be read synchronously!
|
||||
`XLSX.read` supports `Uint8Array` and `ArrayBuffer` data. For `Blob` or `File`
|
||||
objects, the underlying data must be pulled into an `ArrayBuffer`.
|
||||
|
||||
The callback-based approach uses a `FileReader`:
|
||||
|
||||
```js
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
/* e.target.result is an ArrayBuffer */
|
||||
const wb = XLSX.read(e.target.result);
|
||||
console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
|
||||
// usage: file_to_wb(file, function(wb) { /* wb is a workbook object */ });
|
||||
function file_to_wb(file, callback) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
/* e.target.result is an ArrayBuffer */
|
||||
callback(XLSX.read(e.target.result));
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
reader.readAsArrayBuffer(file);
|
||||
```
|
||||
|
||||
<details><summary><b>FileReaderSync in Web Workers</b> (click to show)</summary>
|
||||
|
||||
`FileReaderSync` is only available in Web Workers:
|
||||
|
||||
```js
|
||||
// assuming main thread called worker.postMessage({ file: file_object })
|
||||
self.addEventListener('message', (e) => {
|
||||
/* get file object from message */
|
||||
var file = e.data.file;
|
||||
/* Read file data */
|
||||
const ab = new FileReaderSync().readAsArrayBuffer(file);
|
||||
/* Parse file */
|
||||
const wb = XLSX.read(ab);
|
||||
/* DO SOMETHING WITH wb HERE */
|
||||
});
|
||||
```
|
||||
|
||||
["User-Submitted File" example](./worker#user-submitted-file) has a live demo.
|
||||
|
||||
</details>
|
||||
|
||||
<details><summary><b>IE10 Binary Strings</b> (click to show)</summary>
|
||||
|
||||
In IE10, binary strings are more performant than `ArrayBuffer`. `XLSX.read`
|
||||
supports binary strings with `type: "binary"`:
|
||||
|
||||
```js
|
||||
// usage: file_bs_to_wb(file, function(wb) { /* wb is a workbook object */ });
|
||||
function file_bs_to_wb(file, callback) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
/* e.target.result is a binary string */
|
||||
callback(XLSX.read(e.target.result, { type: "binary" }));
|
||||
};
|
||||
reader.readAsBinaryString(file);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
The Promise-based approach uses `Blob#arrayBuffer`:
|
||||
|
||||
```js
|
||||
@ -60,8 +104,9 @@ async function blob_to_wb(blob) {
|
||||
|
||||
_Writing Binary Data_
|
||||
|
||||
`XLSX.write` can generate `Uint8Array` results by passing `type: "buffer"`. A
|
||||
`Blob` can be created by using the constructor:
|
||||
`XLSX.write` can generate `Uint8Array` results by passing `type: "buffer"`.
|
||||
|
||||
A `Blob` can be created by using the constructor:
|
||||
|
||||
```js
|
||||
const u8 = XLSX.write(workbook, { type: "buffer", bookType: "xlsx" });
|
||||
@ -78,6 +123,17 @@ _Writing Files_
|
||||
XLSX.writeFile(wb, "SheetJS.xlsx");
|
||||
```
|
||||
|
||||
:::caution Web Workers
|
||||
|
||||
`XLSX.writeFile` requires DOM access and will not work in a Web Worker!
|
||||
|
||||
The workaround is to generate the file data from the Worker (using `XLSX.write`)
|
||||
and send the data back to the main context for the actual download action.
|
||||
|
||||
["Creating a Local File" includes a live demo](./worker#creating-a-local-file).
|
||||
|
||||
:::
|
||||
|
||||
## File API
|
||||
|
||||
_Reading Files_
|
||||
@ -93,7 +149,7 @@ async function handleFileAsync(e) {
|
||||
/* data is an ArrayBuffer */
|
||||
const workbook = XLSX.read(data);
|
||||
/* do something with the workbook here */
|
||||
console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]))
|
||||
console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
|
||||
}
|
||||
input_dom_element.addEventListener("change", handleFileAsync, false);
|
||||
```
|
||||
@ -105,8 +161,12 @@ _Reading Files_
|
||||
The `dataTransfer` property of the `drop` event holds a list of files:
|
||||
|
||||
```js
|
||||
/* suppress default behavior for drag and drop events */
|
||||
function suppress(e) { e.stopPropagation(); e.preventDefault(); }
|
||||
|
||||
/* handle data from drop event */
|
||||
async function handleDropAsync(e) {
|
||||
e.stopPropagation(); e.preventDefault();
|
||||
suppress(e);
|
||||
/* get first file */
|
||||
const f = e.dataTransfer.files[0];
|
||||
/* get raw data */
|
||||
@ -114,9 +174,12 @@ async function handleDropAsync(e) {
|
||||
/* data is an ArrayBuffer */
|
||||
const wb = XLSX.read(data);
|
||||
/* do something with the workbook here */
|
||||
console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]))
|
||||
console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
|
||||
}
|
||||
|
||||
drop_dom_element.addEventListener("drop", handleDropAsync, false);
|
||||
drop_dom_element.addEventListener("dragover", suppress, false);
|
||||
drop_dom_element.addEventListener("dragenter", suppress, false);
|
||||
```
|
||||
|
||||
## File System Access API
|
||||
@ -128,6 +191,45 @@ the feature in version 86. Safari did not support File System Access API.
|
||||
|
||||
:::
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show) </summary>
|
||||
|
||||
This live example reads a file then tries to save as XLSX.
|
||||
|
||||
```jsx live
|
||||
function SheetJSRoundTripFileSystemAPI() { return ( <button onClick={async () => {
|
||||
/* Show picker and get data */
|
||||
const [rFile] = await window.showOpenFilePicker({
|
||||
types: [{
|
||||
description: 'Spreadsheets',
|
||||
accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] }
|
||||
}],
|
||||
excludeAcceptAllOption: true,
|
||||
multiple: false
|
||||
});
|
||||
const ab = await (await rFile.getFile()).arrayBuffer();
|
||||
|
||||
/* parse */
|
||||
const wb = XLSX.read(ab);
|
||||
|
||||
/* Show picker and get handle to file */
|
||||
const wFile = await window.showSaveFilePicker({
|
||||
suggestedName: "SheetJSRT.xlsx",
|
||||
types: [ { description: 'XLSX', accept: { 'application/vnd.ms-excel': ['.xlsx'] } } ]
|
||||
});
|
||||
const wstream = await wFile.createWritable();
|
||||
|
||||
/* write */
|
||||
const buf = XLSX.write(wb, { bookType: "xlsx", type: "buffer" });
|
||||
wstream.write(buf);
|
||||
|
||||
/* close stream to commit file */
|
||||
wstream.close();
|
||||
|
||||
}}>Click to read then save as XLSX</button> ) }
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
_Reading Files_
|
||||
|
||||
`window.showOpenFilePicker` shows a file picker and resolves to an array of
|
||||
@ -182,47 +284,6 @@ wstream.write(XLSX.write(wb, { bookType: ext, type: "buffer" }))
|
||||
wstream.close();
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show) </summary>
|
||||
|
||||
This live example reads a file then tries to save as XLSX.
|
||||
|
||||
```jsx live
|
||||
function SheetJSRoundTripFileSystemAPI() { return ( <button onClick={async () => {
|
||||
/* Show picker and get data */
|
||||
const [rFile] = await window.showOpenFilePicker({
|
||||
types: [{
|
||||
description: 'Spreadsheets',
|
||||
accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] }
|
||||
}],
|
||||
excludeAcceptAllOption: true,
|
||||
multiple: false
|
||||
});
|
||||
const ab = await (await rFile.getFile()).arrayBuffer();
|
||||
|
||||
/* parse */
|
||||
const wb = XLSX.read(ab);
|
||||
|
||||
/* Show picker and get handle to file */
|
||||
const wFile = await window.showSaveFilePicker({
|
||||
suggestedName: "SheetJSRT.xlsx",
|
||||
types: [ { description: 'XLSX', accept: { 'application/vnd.ms-excel': ['.xlsx'] } } ]
|
||||
});
|
||||
const wstream = await wFile.createWritable();
|
||||
|
||||
/* write */
|
||||
const buf = XLSX.write(wb, { bookType: "xlsx", type: "buffer" });
|
||||
wstream.write(buf);
|
||||
|
||||
/* close stream to commit file */
|
||||
wstream.close();
|
||||
|
||||
}}>Click to read then save as XLSX</button> ) }
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## File and Directory Entries API
|
||||
|
||||
:::caution Deprecated
|
||||
@ -263,7 +324,8 @@ Internet Explorer offered proprietary APIs that were not adopted by Chromium.
|
||||
|
||||
_Writing Files_
|
||||
|
||||
IE10 and IE11 support `navigator.msSaveBlob`. `writeFile` will use the method.
|
||||
IE10 and IE11 support `navigator.msSaveBlob`. `XLSX.writeFile` will use this
|
||||
method if it is available.
|
||||
|
||||
#### VBScript
|
||||
|
||||
@ -304,8 +366,8 @@ import { readFile, writeFile, set_fs } from 'xlsx';
|
||||
import * as fs from 'fs';
|
||||
set_fs(fs);
|
||||
|
||||
var wb = XLSX.readFile("sheetjs.numbers");
|
||||
XLSX.writeFile(wb, "sheetjs.xlsx");
|
||||
var wb = readFile("sheetjs.numbers");
|
||||
writeFile(wb, "sheetjs.xlsx");
|
||||
```
|
||||
|
||||
### ExtendScript
|
||||
@ -322,8 +384,7 @@ XLSX.writeFile(wb, "sheetjs.csv");
|
||||
|
||||
### Deno
|
||||
|
||||
`Deno.readFileSync` and `Deno.writeFileSync` are supported by `readFile` and
|
||||
`writeFile` out of the box:
|
||||
`readFile` uses `Deno.readFileSync` and `writeFile` uses `Deno.writeFileSync`:
|
||||
|
||||
```js
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
|
||||
@ -333,11 +394,11 @@ const wb = XLSX.readFile("sheetjs.numbers");
|
||||
XLSX.writeFile(wb, "sheetjs.xlsx");
|
||||
```
|
||||
|
||||
:::note
|
||||
:::caution Deno entitlements
|
||||
|
||||
Any script using `XLSX.readFile` requires the `--allow-read` permission.
|
||||
Any Deno script using `XLSX.readFile` requires the `--allow-read` entitlement.
|
||||
|
||||
Any script using `XLSX.writeFile` requires the `--allow-write` permission.
|
||||
Any Deno script using `XLSX.writeFile` requires the `--allow-write` entitlement.
|
||||
|
||||
:::
|
||||
|
||||
@ -346,12 +407,12 @@ Any script using `XLSX.writeFile` requires the `--allow-write` permission.
|
||||
Bun requires the `fs` module:
|
||||
|
||||
```js
|
||||
import * as XLSX from 'xlsx';
|
||||
import { readFile, writeFile, set_fs } from 'xlsx';
|
||||
import * as fs from 'fs';
|
||||
XLSX.set_fs(fs);
|
||||
set_fs(fs);
|
||||
|
||||
var wb = XLSX.readFile("sheetjs.numbers");
|
||||
XLSX.writeFile(wb, "sheetjs.xlsx");
|
||||
var wb = readFile("sheetjs.numbers");
|
||||
writeFile(wb, "sheetjs.xlsx");
|
||||
```
|
||||
|
||||
### Apps
|
||||
|
Loading…
Reference in New Issue
Block a user