forked from sheetjs/docs.sheetjs.com
		
	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