| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: Local File Access | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_prev: demos/data/index | 
					
						
							|  |  |  | pagination_next: demos/cloud/index | 
					
						
							|  |  |  | sidebar_custom_props: | 
					
						
							|  |  |  |   summary: Reading and writing files using various platform APIs | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 11:21:37 +00:00
										 |  |  | import current from '/version.js'; | 
					
						
							|  |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | Reading from and writing to files requires native platform support. | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | SheetJS `readFile` and `writeFile` methods include support for some platforms. | 
					
						
							|  |  |  | Due to sandboxing and security settings, `readFile` does not work in the web | 
					
						
							|  |  |  | browser and `writeFile` is not guaranteed to work in all cases. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | This demo looks at various web APIs for reading and writing files. We'll explore | 
					
						
							|  |  |  | how to pass data between SheetJS functions and various APIs. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | :::note pass | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Some snippets are also available in the "Common Use Cases" section: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 05:45:37 +00:00
										 |  |  | - [Data Import](/docs/solutions/input) | 
					
						
							|  |  |  | - [Data Export](/docs/solutions/output) | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | Other demos cover APIs for local file access on special platforms: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - ["iOS and Android Apps"](/docs/demos/mobile/) covers mobile app frameworks | 
					
						
							|  |  |  | - ["Desktop and CLI Tools"](/docs/demos/desktop/) covers desktop apps and CLIs | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ## Binary Data
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | JavaScript engines represent binary data in a number of structures. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ### `Uint8Array`
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | A `Uint8Array` is a Typed Array where each value is a 8-bit unsigned integer. | 
					
						
							|  |  |  | Server-side platforms including NodeJS typically use `Uint8Array`, or a subclass | 
					
						
							|  |  |  | such as `Buffer`, to represent data from files. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The SheetJS `read` method can read data from `Uint8Array` without special | 
					
						
							|  |  |  | options. The SheetJS `write` method can generate workbooks stored in | 
					
						
							|  |  |  | `Uint8Array` structures with the option `bookType: "buffer"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### `ArrayBuffer`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An `ArrayBuffer` represents an array of bytes. Unlike `Uint8Array`, the bytes | 
					
						
							|  |  |  | are not immediately available. Typically the underlying data is pulled using | 
					
						
							|  |  |  | the `Uint8Array` constructor: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ```js | 
					
						
							|  |  |  | const u8 = new Uint8Array(array_buffer); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `read` method can read data from `ArrayBuffer` without special | 
					
						
							|  |  |  | options, as it performs the aforementioned conversion. The SheetJS `write` | 
					
						
							|  |  |  | method can generate workbooks stored in `ArrayBuffer` structures with the | 
					
						
							|  |  |  | option `bookType: "array"` | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ### `Blob` and `File`
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | `Blob` is an opaque pointer to data. The data is not immediately accessible. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | `File` extends `Blob` with support for storing file names and other metadata. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The SheetJS `read` method does not handle `Blob` or `File`. The underlying data | 
					
						
							|  |  |  | must be pulled into an `ArrayBuffer` before parsing. There are two approaches: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A) Modern browsers support the `arrayBuffer` method. It returns a promise that | 
					
						
							|  |  |  | resolves to `ArrayBuffer`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | // usage: const wb = await blob_to_wb(blob); | 
					
						
							|  |  |  | async function blob_to_wb(blob) { | 
					
						
							|  |  |  |   const ab = await blob.arrayBuffer(); // pull data from Blob | 
					
						
							|  |  |  |   return XLSX.read(ab);                // parse ArrayBuffer | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | B) For broader browser support, the `FileReader` API can pull `ArrayBuffer` data | 
					
						
							|  |  |  | using the `readAsArrayBuffer` method: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | // 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); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | <details><summary><b>FileReaderSync in Web Workers</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | `FileReaderSync` is only available in Web Workers. It returns an `ArrayBuffer`: | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```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 */ | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 11:21:37 +00:00
										 |  |  | ["User-Submitted File" example](/docs/demos/bigdata/worker#user-submitted-file) | 
					
						
							|  |  |  | includes a live demo. | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The SheetJS `write` method can generate a `Uint8Array` which can be passed to | 
					
						
							|  |  |  | the `Blob` constructor: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* write workbook to Uint8Array */ | 
					
						
							|  |  |  | const u8 = XLSX.write(wb, { bookType: "xlsx", type: "buffer" }); | 
					
						
							|  |  |  | /* create array of parts */ | 
					
						
							|  |  |  | const parts = [ u8 ]; // `Blob` constructor expects this | 
					
						
							|  |  |  | /* create Blob */ | 
					
						
							|  |  |  | const blob = new Blob(parts, { type: "application/vnd.ms-excel" }); | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The `File` constructor accepts an additional `name` argument: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* write workbook to Uint8Array */ | 
					
						
							|  |  |  | const u8 = XLSX.write(wb, { bookType: "xlsx", type: "buffer" }); | 
					
						
							|  |  |  | /* create array of parts */ | 
					
						
							|  |  |  | const parts = [ u8 ]; // `Blob` constructor expects this | 
					
						
							|  |  |  | /* create Blob */ | 
					
						
							|  |  |  | const blob = new File(parts, "SheetJSFileExport.xlsx", { type: "application/vnd.ms-excel" }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Binary Strings
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Binary strings are strings where each character code is between `0` and `255`. | 
					
						
							|  |  |  | This structure is generated from the `FileReader#readAsBinaryString` method. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `read` method supports binary strings with `type: "binary"`. The | 
					
						
							|  |  |  | following snippet shows how `readAsBinaryString` can be paired with SheetJS: | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The SheetJS `write` method can generate binary strings using `type: "binary"`: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | /* write workbook to binary string */ | 
					
						
							|  |  |  | const bstr = XLSX.write(wb, { bookType: "xlsx", type: "binary" }); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ### Base64 Strings
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Base64 strings are encoded using 64 display ASCII characters. This structure is | 
					
						
							|  |  |  | generated from `btoa`, the `FileReader#readAsDataURL` method, and many platform | 
					
						
							|  |  |  | APIs in mobile and desktop app frameworks. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `read` method supports Base64 strings with `type: "base64"`. The | 
					
						
							|  |  |  | following snippet shows how `readAsDataURL` can be paired with SheetJS: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | ```js | 
					
						
							|  |  |  | // usage: file_b64_to_wb(file, function(wb) { /* wb is a workbook object */ }); | 
					
						
							|  |  |  | function file_b64_to_wb(file, callback) { | 
					
						
							|  |  |  |   var reader = new FileReader(); | 
					
						
							|  |  |  |   reader.onload = function(e) { | 
					
						
							|  |  |  |     /* e.target.result is a base64 string */ | 
					
						
							|  |  |  |     callback(XLSX.read(e.target.result, { type: "base64" })); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   reader.readAsDataURL(file); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The SheetJS `write` method can generate Base64 strings using `type: "base64"`: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | /* write workbook to Base64 string */ | 
					
						
							|  |  |  | const b64 = XLSX.write(wb, { bookType: "xlsx", type: "base64" }); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Web Browsers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::warning pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Not all web APIs are supported in all browsers.  For example, Firefox does not | 
					
						
							|  |  |  | support the "File System Access API". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Even when a browser technically supports a web API, it may be disabled in the | 
					
						
							|  |  |  | client browser. Some APIs do not give any feedback. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### HTML5 Download Attribute
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Writing Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `writeFile` will attempt a download in the browser using the attribute. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | XLSX.writeFile(wb, "SheetJS.xlsx"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details><summary><b>Implementation Details</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Under the hood, it creates a special URL and clicks a link. The library method | 
					
						
							|  |  |  | includes a few workarounds for legacy browsers | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | **`XLSX.writeFile(wb, "SheetJS.xlsx");`** is roughly equivalent to: | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | /* write data -- `writeFile` infers bookType from filename but `write` cannot */ | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | const u8 = XLSX.write(wb, { bookType: "xlsx", type: "buffer" }); | 
					
						
							|  |  |  | /* create Blob */ | 
					
						
							|  |  |  | const blob = new Blob([u8]); | 
					
						
							|  |  |  | /* create object URL */ | 
					
						
							| 
									
										
										
										
											2023-06-23 20:24:44 +00:00
										 |  |  | const url = URL.createObjectURL(blob); | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* create `A` DOM element */ | 
					
						
							|  |  |  | const a = document.createElement("a"); | 
					
						
							|  |  |  | /* set export file name */ | 
					
						
							|  |  |  | a.download = "SheetJS.xlsx"; | 
					
						
							|  |  |  | /* wire up the object URL to the DOM element */ | 
					
						
							|  |  |  | a.href = url; | 
					
						
							|  |  |  | /* add to the page */ | 
					
						
							|  |  |  | document.body.appendChild(a); | 
					
						
							|  |  |  | /* click the link */ | 
					
						
							|  |  |  | a.click(); | 
					
						
							|  |  |  | /* remove the element from the page */ | 
					
						
							|  |  |  | document.body.removeChild(a); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | :::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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 11:21:37 +00:00
										 |  |  | ["Creating a Local File"](/docs/demos/bigdata/worker#creating-a-local-file) | 
					
						
							|  |  |  | includes a live demo. | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### File API
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Reading Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | In the `change` event of `<input type="file">`, the event object will have a | 
					
						
							|  |  |  | `target` property. The `files` property of `target` is a list of `File` objects. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | async function handleFileAsync(e) { | 
					
						
							|  |  |  |   /* get first file */ | 
					
						
							|  |  |  |   const file = e.target.files[0]; | 
					
						
							|  |  |  |   /* get raw data */ | 
					
						
							|  |  |  |   const data = await file.arrayBuffer(); | 
					
						
							|  |  |  |   /* data is an ArrayBuffer */ | 
					
						
							|  |  |  |   const workbook = XLSX.read(data); | 
					
						
							|  |  |  |   /* do something with the workbook here */ | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  |   console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | input_dom_element.addEventListener("change", handleFileAsync, false); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### HTML Drag and Drop API
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Reading Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The `dataTransfer` property of the `drop` event holds a list of `File` objects: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | /* suppress default behavior for drag and drop events */ | 
					
						
							|  |  |  | function suppress(e) { e.stopPropagation(); e.preventDefault(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* handle data from drop event */ | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | async function handleDropAsync(e) { | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  |   suppress(e); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  |   /* get first file */ | 
					
						
							|  |  |  |   const f = e.dataTransfer.files[0]; | 
					
						
							|  |  |  |   /* get raw data */ | 
					
						
							|  |  |  |   const data = await f.arrayBuffer(); | 
					
						
							|  |  |  |   /* data is an ArrayBuffer */ | 
					
						
							|  |  |  |   const wb = XLSX.read(data); | 
					
						
							|  |  |  |   /* do something with the workbook here */ | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  |   console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | drop_dom_element.addEventListener("drop", handleDropAsync, false); | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | drop_dom_element.addEventListener("dragover", suppress, false); | 
					
						
							|  |  |  | drop_dom_element.addEventListener("dragenter", suppress, false); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### File System Access API
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | :::warning Limited Browser Support | 
					
						
							| 
									
										
										
										
											2022-09-05 10:00:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | At the time of writing, browser support was fairly limited.  Chrome introduced | 
					
						
							|  |  |  | the feature in version 86.  Safari did not support File System Access API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | :::caution | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When this demo was last tested, Google Chrome did not add an entry to the | 
					
						
							|  |  |  | "Downloads" list. Nevertheless the actual file was written correctly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo was last tested on 2023 August 30 in Google Chrome. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | <details><summary><b>Live Example</b> (click to show) </summary> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | This live example reads a file then tries to save as XLSX. If the File System | 
					
						
							|  |  |  | Access API is not supported, the result will be a clear message. | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | function SheetJSRoundTripFileSystemAPI() { return window.showSaveFilePicker ? ( | 
					
						
							|  |  |  | <button onClick={async () => { | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  |   /* 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(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | }}>Click to read then save as XLSX</button> | 
					
						
							|  |  |  |   ) : ( <b>This browser does not support File System Access API</b> ); } | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | _Reading Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `window.showOpenFilePicker` shows a file picker and resolves to an array of | 
					
						
							|  |  |  | file handles. When `multiple: false` is set, the array has one element. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `getFile` method resolves to a `File` object whose data can be read with | 
					
						
							|  |  |  | the `arrayBuffer` method: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* Show picker and get data */ | 
					
						
							|  |  |  | const [hFile] = await window.showOpenFilePicker({ | 
					
						
							|  |  |  |   types: [{ | 
					
						
							|  |  |  |     description: 'Spreadsheets', | 
					
						
							|  |  |  |     accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] } | 
					
						
							|  |  |  |   }], | 
					
						
							|  |  |  |   excludeAcceptAllOption: true, | 
					
						
							|  |  |  |   multiple: false | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | const ab = await (await hFile.getFile()).arrayBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* parse */ | 
					
						
							|  |  |  | const wb = XLSX.read(ab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* do something with the workbook */ | 
					
						
							|  |  |  | console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _Writing Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `window.showSaveFilePicker` shows a file picker and resolves to a file handle. | 
					
						
							|  |  |  | The `createWritable` method resolves to a `FileSystemWritableFileStream`, which | 
					
						
							|  |  |  | readily accepts `Uint8Array` data from `XLSX.write`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* Show picker and get handle to file */ | 
					
						
							|  |  |  | const hFile = await window.showSaveFilePicker({ | 
					
						
							|  |  |  |   suggestedName: "SheetJS.xlsx", | 
					
						
							|  |  |  |   types: [ | 
					
						
							|  |  |  |     { description: 'Excel 2007+ (XLSX)', accept: { 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'] } }, | 
					
						
							|  |  |  |     { description: 'Excel 97-2004 (XLS)', accept: { 'application/vnd.ms-excel': ['.xls'] } }, | 
					
						
							|  |  |  |     { description: 'Excel 2007+ Binary (XLSB)', accept: { 'application/vnd.ms-excel.sheet.binary.macroEnabled.12': ['.xlsb'] } }, | 
					
						
							|  |  |  |     /* note that each MIME type must be unique! */ | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | const wstream = await hFile.createWritable(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* get extension */ | 
					
						
							|  |  |  | const ext = hFile.name.slice(hFile.name.lastIndexOf(".")+1) | 
					
						
							|  |  |  | /* write */ | 
					
						
							|  |  |  | wstream.write(XLSX.write(wb, { bookType: ext, type: "buffer" })) | 
					
						
							|  |  |  | /* close stream to commit file */ | 
					
						
							|  |  |  | wstream.close(); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### File and Directory Entries API
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-05 10:00:35 +00:00
										 |  |  | :::caution Deprecated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In the web browser, the File and Directory Entries API has been deprecated and | 
					
						
							|  |  |  | is not recommended for new applications. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `cordova-plugin-file` still uses the API patterns. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Writing Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The API is callback-based. At a high level: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) `window.requestFileSystem` requests access to the filesystem. The callback | 
					
						
							|  |  |  | receives a `FileSystem` object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) A file is created using the `getFile` method. The callback receives a | 
					
						
							|  |  |  | `FileSystemFileEntry` object representing the file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) A writer is created using the `createWriter` method of the file object. The | 
					
						
							|  |  |  | callback receives a `FileWriter` object representing a file handle for writing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 4) Data is written using the `write` method of the `FileWriter` object. Unlike | 
					
						
							|  |  |  | the other methods, callbacks are attached to the `FileWriter` object directly. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ```js | 
					
						
							|  |  |  | // Request File System Access | 
					
						
							|  |  |  | window.requestFileSystem(window.PERSISTENT, 0, (fs) => { | 
					
						
							|  |  |  |   // Request a handle to "SheetJS.xlsx", making a new file if necessary | 
					
						
							|  |  |  |   fs.root.getFile("SheetJS.xlsx", {create: true}, entry => { | 
					
						
							|  |  |  |     // Request a FileWriter for writing data | 
					
						
							|  |  |  |     entry.createWriter(writer => { | 
					
						
							|  |  |  |       // The FileWriter API needs an actual Blob | 
					
						
							|  |  |  |       const u8 = XLSX.write(wb, { type: "buffer", bookType: "xlsx" }); | 
					
						
							|  |  |  |       const data = new Blob([u8], { type: "application/vnd.ms-excel" }); | 
					
						
							|  |  |  |       // `onwriteend` is called on success, `onerror` called on error | 
					
						
							|  |  |  |       writer.onwriteend = () => {}; writer.onerror = () => {}; | 
					
						
							|  |  |  |       // write the data | 
					
						
							|  |  |  |       writer.write(data); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 03:44:38 +00:00
										 |  |  | ### Internet Explorer
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Internet Explorer offered proprietary APIs that were not adopted by Chromium. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### Blob API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _Writing Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | IE10 and IE11 support `navigator.msSaveBlob`. `XLSX.writeFile` will use this | 
					
						
							|  |  |  | method if it is available. | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | <details><summary><b>Implementation Details</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **`XLSX.writeFile(wb, "SheetJS.xlsx");`** is roughly equivalent to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* write data -- `writeFile` infers bookType from filename but `write` cannot */ | 
					
						
							|  |  |  | const u8 = XLSX.write(wb, { bookType: "xlsx", type: "buffer" }); | 
					
						
							|  |  |  | /* create Blob */ | 
					
						
							|  |  |  | const blob = new Blob([u8]); | 
					
						
							|  |  |  | /* call msSaveBlob */ | 
					
						
							|  |  |  | navigator.msSaveBlob(blob, "SheetJS.xlsx"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | #### VBScript
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _Reading and Writing Files_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Internet Explorer 6-9 with VBScript support `Scripting.FileSystemObject`.  This | 
					
						
							|  |  |  | is not supported in modern browsers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This approach is implemented in the library `readFile` and `writeFile` methods. | 
					
						
							|  |  |  | It requires the shim script to be loaded before the main library script: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <!-- load the shim script first --> | 
					
						
							|  |  |  | <script src="shim.min.js"></script> | 
					
						
							|  |  |  | <!-- then load the main script --> | 
					
						
							|  |  |  | <script src="xlsx.full.min.js"></script> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Other Platforms
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### NodeJS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `fs.readFileSync` and `fs.writeFileSync` allow for reading and writing files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When using `require`, these are supported in `readFile` and `writeFile`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var XLSX = require("xlsx"); | 
					
						
							|  |  |  | var wb = XLSX.readFile("sheetjs.numbers"); | 
					
						
							|  |  |  | XLSX.writeFile(wb, "sheetjs.xls"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 05:45:37 +00:00
										 |  |  | [Installation](/docs/getting-started/installation/nodejs) has a special note for | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | use with NodeJS ECMAScript Modules: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | import { readFile, writeFile, set_fs } from 'xlsx'; | 
					
						
							|  |  |  | import * as fs from 'fs'; | 
					
						
							|  |  |  | set_fs(fs); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | var wb = readFile("sheetjs.numbers"); | 
					
						
							|  |  |  | writeFile(wb, "sheetjs.xlsx"); | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details><summary><b>Implementation Details</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **`XLSX.readFile(filepath)`** is equivalent to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _CommonJS_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var fs = require("fs"); | 
					
						
							|  |  |  | var buf = fs.readFileSync(filepath); | 
					
						
							|  |  |  | var wb = XLSX.read(buf); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _ECMAScript Modules_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | import { read } from "xlsx"; | 
					
						
							|  |  |  | import { readFileSync } from "fs"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var buf = readFileSync(filepath); | 
					
						
							|  |  |  | var wb = read(buf); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **`XLSX.writeFile(wb, filepath)`** is equivalent to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _CommonJS_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var fs = require("fs"), path = require("path"); | 
					
						
							|  |  |  | var buf = XLSX.write(wb, { bookType: path.extname(filepath).slice(1), type: "buffer" }); | 
					
						
							|  |  |  | fs.writeFileSync(filepath, buf); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _ECMAScript Modules_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | import { write } from "xlsx"; | 
					
						
							|  |  |  | import { writeFileSync } from "fs"; | 
					
						
							|  |  |  | import { extname } from "path"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var buf = write(wb, { bookType: extname(filepath).slice(1), type: "buffer" }); | 
					
						
							|  |  |  | writeFileSync(filepath, buf); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 22:12:52 +00:00
										 |  |  | ### ExtendScript
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Photoshop and other Adobe apps, `readFile` and `writeFile` use the `File` | 
					
						
							|  |  |  | object under the hood: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | #include "xlsx.extendscript.js"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var wb = XLSX.readFile("sheetjs.xlsx"); | 
					
						
							|  |  |  | XLSX.writeFile(wb, "sheetjs.csv"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 22:09:08 +00:00
										 |  |  | The [ExtendScript demo](/docs/demos/extensions/extendscript) also covers "Common | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | Extensibility Platform" (CEP) and "Unified Extensibility Platform" (UXP) details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Chrome Extensions
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Manifest v2 Chrome extensions, `writeFile` calls `chrome.downloads.download`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This approach uses `URL.createObjectURL`, an API that is not supported in a | 
					
						
							|  |  |  | Manifest v3 Background Service Worker. For small exports, raw Base64 URLs can be | 
					
						
							|  |  |  | generated and downloaded. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [Chromium demo](/docs/demos/extensions/chromium) covers the details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ### Deno
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | `readFile` uses `Deno.readFileSync` and `writeFile` uses `Deno.writeFileSync`: | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 11:21:37 +00:00
										 |  |  | <CodeBlock 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'; | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | const wb: XLSX.WorkBook = XLSX.readFile("sheetjs.numbers"); | 
					
						
							|  |  |  | XLSX.writeFile(wb, "sheetjs.xlsx");`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | :::caution Deno entitlements | 
					
						
							| 
									
										
										
										
											2022-09-02 05:52:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | Any Deno script using `XLSX.readFile` requires the `--allow-read` entitlement. | 
					
						
							| 
									
										
										
										
											2022-09-02 05:52:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | Any Deno script using `XLSX.writeFile` requires the `--allow-write` entitlement. | 
					
						
							| 
									
										
										
										
											2022-09-02 05:52:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details><summary><b>Implementation Details</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **`XLSX.readFile(filepath)`** is equivalent to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _ECMAScript Modules_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <CodeBlock 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'; | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | const u8: Uint8Array = Deno.readFileSync(filepath); | 
					
						
							|  |  |  | const wb: XLSX.WorkBook = XLSX.read(u8);`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **`XLSX.writeFile(wb, filepath)`** is equivalent to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _ECMAScript Modules_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <CodeBlock 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'; | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | const u8 = XLSX.write(wb, { bookType: filepath.slice(filepath.lastIndexOf(".")+1), type: "buffer" }); | 
					
						
							|  |  |  | Deno.writeFileSync(filepath, u8);`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-26 19:21:53 +00:00
										 |  |  | ### Bun
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Bun requires the `fs` module: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | import { readFile, writeFile, set_fs } from 'xlsx'; | 
					
						
							| 
									
										
										
										
											2022-08-26 19:21:53 +00:00
										 |  |  | import * as fs from 'fs'; | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | set_fs(fs); | 
					
						
							| 
									
										
										
										
											2022-08-26 19:21:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-19 21:12:12 +00:00
										 |  |  | var wb = readFile("sheetjs.numbers"); | 
					
						
							|  |  |  | writeFile(wb, "sheetjs.xlsx"); | 
					
						
							| 
									
										
										
										
											2022-08-26 19:21:53 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | The implementation is identical to [NodeJS ECMAScript Modules](#nodejs). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | ### Apps
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Desktop and mobile apps have their own specific APIs covered in separate demos: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 05:45:37 +00:00
										 |  |  | - [Electron and other desktop apps](/docs/demos/desktop) | 
					
						
							|  |  |  | - [React Native and other mobile apps](/docs/demos/mobile) |