From 155b88ff3c2c5ca440ed998abb9c99ac5ef61353 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Thu, 31 Aug 2023 18:09:08 -0400 Subject: [PATCH] file --- docz/docs/03-demos/06-desktop/09-cli.md | 34 ++- docz/docs/03-demos/08-local/01-file.md | 222 ++++++++++++++++---- docz/docs/03-demos/42-engines/01_duktape.md | 1 + docz/docs/03-demos/42-engines/02_v8.md | 1 + docz/docs/03-demos/42-engines/06_goja.md | 4 + docz/docs/03-demos/42-engines/09_hermes.md | 7 + docz/docs/03-demos/42-engines/21_boa.md | 16 +- docz/docs/09-miscellany/05-contributing.md | 18 +- docz/static/cli/Cargo.toml | 2 +- docz/static/hermes/Makefile | 2 +- 10 files changed, 244 insertions(+), 63 deletions(-) diff --git a/docz/docs/03-demos/06-desktop/09-cli.md b/docz/docs/03-demos/06-desktop/09-cli.md index 8aa1d7f..92c3579 100644 --- a/docz/docs/03-demos/06-desktop/09-cli.md +++ b/docz/docs/03-demos/06-desktop/09-cli.md @@ -218,12 +218,31 @@ V8 engine. This demo uses the Rust integration to generate a command line tool. This demo was last tested in the following deployments: -| Architecture | V8 Version | Date | -|:-------------|:-------------|:-----------| -| `darwin-x64` | `11.4.183.2` | 2023-05-22 | -| `darwin-mac` | `11.4.183.2` | 2023-05-22 | -| `linux-x64` | `11.4.183.2` | 2023-05-23 | -| `win10-x64` | `11.4.183.2` | 2023-05-23 | +| Architecture | V8 Version | Crate | Date | +|:-------------|:-------------|:---------|:-----------| +| `darwin-x64` | `11.4.183.2` | `0.71.2` | 2023-05-22 | +| `darwin-arm` | `11.4.183.2` | `0.71.2` | 2023-05-22 | +| `linux-x64` | `11.4.183.2` | `0.71.2` | 2023-05-23 | +| `linux-arm` | `11.7.439.6` | `0.75.1` | 2023-08-30 | +| `win10-x64` | `11.4.183.2` | `0.71.2` | 2023-05-23 | +| `win11-x64` | `11.7.439.6` | `0.75.1` | 2023-08-31 | + +:::caution pass + +Using crate version `0.71.2`, the Linux AArch64 build failed with an error: + +``` +error[E0080]: evaluation of constant value failed + + | +1715 | assert!(size_of::() == size_of::()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: size_of::() == size_of::()' +``` + +This was fixed in version `0.75.1` of the crate. + +::: + @@ -286,7 +305,7 @@ mv target/release/sheet2csv . ```bash mv target/release/sheet2csv.exe . -./sheet2csv pres.numbers +.\sheet2csv.exe pres.numbers ``` @@ -312,6 +331,7 @@ This demo was last tested in the following deployments: | `darwin-arm` | `1.34.1` | 2023-06-05 | | `win10-x64` | `1.33.2` | 2023-05-08 | | `linux-x64` | `1.33.2` | 2023-05-08 | +| `linux-arm` | `1.36.3` | 2023-08-30 | diff --git a/docz/docs/03-demos/08-local/01-file.md b/docz/docs/03-demos/08-local/01-file.md index 84a2f52..8ff5cb5 100644 --- a/docz/docs/03-demos/08-local/01-file.md +++ b/docz/docs/03-demos/08-local/01-file.md @@ -9,14 +9,14 @@ sidebar_custom_props: import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; -Reading and writing files require native platform support. `XLSX.readFile` and -`XLSX.writeFile` include support for some APIs. +Reading from and writing to files requires native platform support. -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. +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. -This demo looks at various web APIs. More specific approaches for deployments -like mobile apps are covered in their respective demos. +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. :::note pass @@ -25,30 +25,65 @@ Some snippets are also available in the "Common Use Cases" section: - [Data Import](/docs/solutions/input) - [Data Export](/docs/solutions/output) -::: +Other demos cover APIs for local file access on special platforms: -## 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. +- ["iOS and Android Apps"](/docs/demos/mobile/) covers mobile app frameworks +- ["Desktop and CLI Tools"](/docs/demos/desktop/) covers desktop apps and CLIs ::: -### Binary Data +## Binary Data -Modern browser APIs typically use typed arrays or `Blob` or `File` structures. +JavaScript engines represent binary data in a number of structures. -_Reading Binary Data_ +### `Uint8Array` -`XLSX.read` supports `Uint8Array` and `ArrayBuffer` data. For `Blob` or `File` -objects, the underlying data must be pulled into an `ArrayBuffer`. +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. -The callback-based approach uses a `FileReader`: +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: + +```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"` + +### `Blob` and `File` + +`Blob` is an opaque pointer to data. The data is not immediately accessible. + +`File` extends `Blob` with support for storing file names and other metadata. + +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: ```js // usage: file_to_wb(file, function(wb) { /* wb is a workbook object */ }); @@ -64,7 +99,7 @@ function file_to_wb(file, callback) {
FileReaderSync in Web Workers (click to show) -`FileReaderSync` is only available in Web Workers: +`FileReaderSync` is only available in Web Workers. It returns an `ArrayBuffer`: ```js // assuming main thread called worker.postMessage({ file: file_object }) @@ -84,9 +119,36 @@ includes a live demo.
-
IE10 Binary Strings (click to show) +The SheetJS `write` method can generate a `Uint8Array` which can be passed to +the `Blob` constructor: -`XLSX.read` supports binary strings with `type: "binary"`: +```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" }); +``` + +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: ```js // usage: file_bs_to_wb(file, function(wb) { /* wb is a workbook object */ }); @@ -100,28 +162,54 @@ function file_bs_to_wb(file, callback) { } ``` -
- -The Promise-based approach uses `Blob#arrayBuffer`: +The SheetJS `write` method can generate binary strings using `type: "binary"`: ```js -// usage: const wb = await blob_to_wb(blob); -async function blob_to_wb(blob) { - return XLSX.read(await blob.arrayBuffer()); +/* write workbook to binary string */ +const bstr = XLSX.write(wb, { bookType: "xlsx", type: "binary" }); +``` + +### 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: + +```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); } ``` -_Writing Binary Data_ - -`XLSX.write` can generate `Uint8Array` results by passing `type: "buffer"`. - -A `Blob` can be created by using the constructor: +The SheetJS `write` method can generate Base64 strings using `type: "base64"`: ```js -const u8 = XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }); -const blob = new Blob([u8], { type: "application/vnd.ms-excel" }); +/* write workbook to Base64 string */ +const b64 = XLSX.write(wb, { bookType: "xlsx", type: "base64" }); ``` + +## 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. + +::: + ### HTML5 Download Attribute _Writing Files_ @@ -137,10 +225,10 @@ XLSX.writeFile(wb, "SheetJS.xlsx"); Under the hood, it creates a special URL and clicks a link. The library method includes a few workarounds for legacy browsers -`XLSX.writeFile(wb, "SheetJS.xlsx");` is roughly equivalent to: +**`XLSX.writeFile(wb, "SheetJS.xlsx");`** is roughly equivalent to: ```js -/* write data -- note that writeFile infers bookType from filename */ +/* 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]); @@ -179,7 +267,8 @@ includes a live demo. _Reading Files_ -In the `change` event of ``, `target` hold a list of files: +In the `change` event of ``, the event object will have a +`target` property. The `files` property of `target` is a list of `File` objects. ```js async function handleFileAsync(e) { @@ -199,7 +288,7 @@ input_dom_element.addEventListener("change", handleFileAsync, false); _Reading Files_ -The `dataTransfer` property of the `drop` event holds a list of files: +The `dataTransfer` property of the `drop` event holds a list of `File` objects: ```js /* suppress default behavior for drag and drop events */ @@ -225,16 +314,30 @@ drop_dom_element.addEventListener("dragenter", suppress, false); ### File System Access API -:::caution Limited Browser Support +:::warning Limited Browser Support 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. ::: +:::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. + +::: +
Live Example (click to show) -This live example reads a file then tries to save as XLSX. +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. ```jsx live function SheetJSRoundTripFileSystemAPI() { return window.showSaveFilePicker ? ( @@ -340,6 +443,20 @@ is not recommended for new applications. _Writing Files_ +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. + ```js // Request File System Access window.requestFileSystem(window.PERSISTENT, 0, (fs) => { @@ -370,6 +487,21 @@ _Writing Files_ IE10 and IE11 support `navigator.msSaveBlob`. `XLSX.writeFile` will use this method if it is available. +
Implementation Details (click to show) + +**`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"); +``` + +
+ #### VBScript _Reading and Writing Files_ @@ -470,7 +602,7 @@ var wb = XLSX.readFile("sheetjs.xlsx"); XLSX.writeFile(wb, "sheetjs.csv"); ``` -The [ExtendScript demo](/docs/demos/extensions/extendscript) covers the "Common +The [ExtendScript demo](/docs/demos/extensions/extendscript) also covers "Common Extensibility Platform" (CEP) and "Unified Extensibility Platform" (UXP) details. ### Chrome Extensions diff --git a/docz/docs/03-demos/42-engines/01_duktape.md b/docz/docs/03-demos/42-engines/01_duktape.md index 00bfc0d..874425e 100644 --- a/docz/docs/03-demos/42-engines/01_duktape.md +++ b/docz/docs/03-demos/42-engines/01_duktape.md @@ -120,6 +120,7 @@ This demo was tested in the following deployments: | `darwin-x64` | `2.7.0` | 2023-07-24 | | `darwin-arm` | `2.7.0` | 2023-06-05 | | `linux-x64` | `2.7.0` | 2023-06-02 | +| `linux-arm` | `2.7.0` | 2023-08-30 | | `win10-x64` | `2.7.0` | 2023-07-24 | ::: diff --git a/docz/docs/03-demos/42-engines/02_v8.md b/docz/docs/03-demos/42-engines/02_v8.md index d58f58c..c135caa 100644 --- a/docz/docs/03-demos/42-engines/02_v8.md +++ b/docz/docs/03-demos/42-engines/02_v8.md @@ -723,6 +723,7 @@ This demo was last tested in the following deployments: | `darwin-x64` | `0.75.1` | 2023-08-26 | | `darwin-arm` | `0.73.0` | 2023-06-05 | | `linux-x64` | `0.71.2` | 2023-05-23 | +| `linux-arm` | `0.75.1` | 2023-08-30 | | `win10-x64` | `0.71.2` | 2023-05-23 | ::: diff --git a/docz/docs/03-demos/42-engines/06_goja.md b/docz/docs/03-demos/42-engines/06_goja.md index 725dd9e..5e99b08 100644 --- a/docz/docs/03-demos/42-engines/06_goja.md +++ b/docz/docs/03-demos/42-engines/06_goja.md @@ -98,6 +98,10 @@ This demo was tested in the following deployments: | `darwin-arm` | `28ee0ee` | `1.20.4` | 2023-06-05 | | `win10-x64` | `81d7606` | `1.20.2` | 2023-08-27 | | `linux-x64` | `81d7606` | `1.21.0` | 2023-08-27 | +| `linux-arm` | `3dbe69d` | `1.21.1` | 2023-08-30 | + +At the time of writing, Goja did not have proper version numbers. Versions are +identified by Git commit hashes. ::: diff --git a/docz/docs/03-demos/42-engines/09_hermes.md b/docz/docs/03-demos/42-engines/09_hermes.md index fea4c9b..ad0fcaa 100644 --- a/docz/docs/03-demos/42-engines/09_hermes.md +++ b/docz/docs/03-demos/42-engines/09_hermes.md @@ -341,6 +341,7 @@ This demo was tested in the following deployments: | `darwin-x64` | `70af78b` | 2023-08-27 | | `darwin-arm` | `869312f` | 2023-06-05 | | `linux-x64` | `70af78b` | 2023-08-27 | +| `linux-arm` | `70af78b` | 2023-08-27 | ::: @@ -362,6 +363,12 @@ On HoloOS (and other Arch Linux distros): sudo pacman -Syu cmake git ninja icu python zip readline ``` +On Debian and Ubuntu: + +```bash +sudo apt install cmake git ninja-build libicu-dev python zip libreadline-dev +``` +
1) Make a project directory: diff --git a/docz/docs/03-demos/42-engines/21_boa.md b/docz/docs/03-demos/42-engines/21_boa.md index 2eee50f..9d829d7 100644 --- a/docz/docs/03-demos/42-engines/21_boa.md +++ b/docz/docs/03-demos/42-engines/21_boa.md @@ -7,7 +7,7 @@ pagination_next: solutions/input import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; -:::warning +:::warning pass In a production application, it is strongly recommended to use a binding for a more performant engine like [`v8`](/docs/demos/engines/v8#rust) @@ -19,7 +19,6 @@ Boa is a pure-Rust JavaScript engine. The [Standalone scripts](/docs/getting-started/installation/standalone) can be parsed and evaluated in a Boa context. - ## Integration Details _Initialize Engine_ @@ -115,9 +114,11 @@ This demo was tested in the following deployments: | Architecture | Date | |:-------------|:-----------| -| `darwin-x64` | 2023-07-19 | +| `darwin-x64` | 2023-08-31 | | `darwin-arm` | 2023-07-05 | | `linux-x64` | 2023-07-05 | +| `linux-arm` | 2023-08-30 | +| `win10-x64` | 2023-08-31 | ::: @@ -151,7 +152,14 @@ curl -L -o src/main.rs https://docs.sheetjs.com/boa/main.rs ```bash curl -LO https://sheetjs.com/pres.xlsx -cargo run +cargo run --release ``` After a short wait, the contents will be displayed in CSV form. + +:::caution pass + +The default debug build is not optimized and can elicit stack overflow errors. +It is strongly encouraged to use `--release` when possible. + +::: diff --git a/docz/docs/09-miscellany/05-contributing.md b/docz/docs/09-miscellany/05-contributing.md index 118c622..598b5f9 100644 --- a/docz/docs/09-miscellany/05-contributing.md +++ b/docz/docs/09-miscellany/05-contributing.md @@ -44,7 +44,7 @@ These instructions were tested on the following platforms: | MacOS 10.13 (x64) | 2023-04-04 | | MacOS 13.0 (ARM64) | 2023-04-13 | | Windows 10 (x64) + WSL Ubuntu | 2023-07-23 | -| Windows 11 (x64) + WSL Ubuntu | 2023-04-04 | +| Windows 11 (x64) + WSL Ubuntu | 2023-08-31 | With some additional dependencies, the unminified build is reproducible and tests will pass in Windows XP with NodeJS 5.10.0. @@ -75,6 +75,17 @@ sudo add-apt-repository --remove ppa:mercurial-ppa/releases C) Install NodeJS +:::info pass + +When this was last tested, the script showed a deprecation notice. + +**The script worked as expected.** + +The official workaround does not currently work with WSL. When the issues are +resolved, the instructions will be updated. + +::: + ```bash # Install bootstrap NodeJS and NPM within the WSL curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - @@ -250,13 +261,10 @@ git clone https://git.sheetjs.com/sheetjs/sheetjs cd sheetjs ``` -1) Install NodeJS modules for building the scripts +1) Install NodeJS modules for building the scripts: ```bash -# Install dev dependencies npm i - -# Install global dependencies sudo npm i -g mocha@2.5.3 voc @sheetjs/uglify-js ``` diff --git a/docz/static/cli/Cargo.toml b/docz/static/cli/Cargo.toml index 957c392..4a269ed 100644 --- a/docz/static/cli/Cargo.toml +++ b/docz/static/cli/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -v8 = "0.71.2" +v8 = "0.75.1" [[bin]] name = "sheet2csv" diff --git a/docz/static/hermes/Makefile b/docz/static/hermes/Makefile index 46c09ab..bb07ff4 100644 --- a/docz/static/hermes/Makefile +++ b/docz/static/hermes/Makefile @@ -7,7 +7,7 @@ POSTAMBLE=-framework CoreFoundation UNAME__S := $(shell uname -s) ifeq ($(UNAME__S),Linux) MYCC=g++ -POSTAMBLE=-licuuc -licudata -licuio -licutu -licui18n +POSTAMBLE=-pthread -licuuc -licudata -licuio -licutu -licui18n endif .PHONY: doit