Demo refresh
This commit is contained in:
parent
50c4139bb4
commit
19b9f5b122
@ -292,8 +292,8 @@
|
||||
<Cell><Data ss:Type="String">Python</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
|
@ -122,7 +122,7 @@ This demo was last tested in the following deployments:
|
||||
| Architecture | BunJS | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `1.1.39` | 2024-12-17 |
|
||||
| `darwin-arm` | `1.2.2` | 2025-02-16 |
|
||||
| `darwin-arm` | `1.2.7` | 2025-03-30 |
|
||||
| `win11-x64` | `1.1.42` | 2024-12-22 |
|
||||
| `win11-arm` | `1.2.3` | 2025-02-23 |
|
||||
| `linux-x64` | `1.1.40` | 2024-12-19 |
|
||||
|
@ -40,8 +40,8 @@ This browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date |
|
||||
|:------------|:-----------|
|
||||
| Chrome 126 | 2024-06-21 |
|
||||
| Safari 17.4 | 2024-06-20 |
|
||||
| Chrome 133 | 2025-03-30 |
|
||||
| Safari 18.3 | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -41,7 +41,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | JS Engine | Pandas | Python | Date |
|
||||
|:-------------|:----------------|:-------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 2.2.3 | 3.13.1 | 2024-12-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 2.2.2 | 3.12.3 | 2024-06-30 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 2.2.3 | 3.11.8 | 2024-12-21 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.5.3 | 3.11.7 | 2025-01-01 |
|
||||
@ -528,7 +528,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | JS Engine | Polars | Python | Date |
|
||||
|:-------------|:----------------|:--------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 1.18.0 | 3.13.1 | 2024-12-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 0.20.31 | 3.12.3 | 2024-06-30 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 1.26.0 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 1.17.1 | 3.11.8 | 2024-12-21 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 1.23.0 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.18.0 | 3.11.7 | 2025-01-01 |
|
||||
|
@ -128,9 +128,9 @@ function exportFile() {
|
||||
<td>{p.Index}</td>
|
||||
</tr>{/each}
|
||||
<!-- highlight-end -->
|
||||
</tbody><tfoot><td colSpan={2}>
|
||||
</tbody><tfoot><tr><td colSpan={2}>
|
||||
<button on:click={exportFile}>Export XLSX</button>
|
||||
</td></tfoot></table>
|
||||
</td></tfoot></tr></table>
|
||||
</main>
|
||||
```
|
||||
|
||||
@ -143,7 +143,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| SvelteJS | ViteJS | Date |
|
||||
|:---------|:---------|:-----------|
|
||||
| `4.2.18` | `5.2.13` | 2024-06-07 |
|
||||
| `5.25.3` | `6.2.3` | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -170,7 +170,9 @@ The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSSvelteAoA.xlsx`. There may be a
|
||||
delay since Vite will try to optimize the SheetJS library on the fly.
|
||||
|
||||
5) Build the site:
|
||||
5) Stop the server (press <kbd>CTRL</kbd>+<kbd>C</kbd> in the terminal window).
|
||||
|
||||
6) Build the site:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
@ -178,10 +180,10 @@ npm run build
|
||||
|
||||
The generated site will be placed in the `dist` folder.
|
||||
|
||||
6) Start a local web server:
|
||||
7) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx http-server dist
|
||||
npx -y http-server dist
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) with a web browser
|
||||
@ -243,7 +245,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| SvelteJS | ViteJS | Date |
|
||||
|:---------|:---------|:-----------|
|
||||
| `4.2.18` | `5.2.13` | 2024-06-07 |
|
||||
| `5.25.3` | `6.2.3` | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -270,7 +272,9 @@ The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSSvelteHTML.xlsx`. There may be a
|
||||
delay since Vite will try to optimize the SheetJS library on the fly.
|
||||
|
||||
5) Build the site:
|
||||
5) Stop the server (press <kbd>CTRL</kbd>+<kbd>C</kbd> in the terminal window).
|
||||
|
||||
6) Build the site:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
@ -278,10 +282,10 @@ npm run build
|
||||
|
||||
The generated site will be placed in the `dist` folder.
|
||||
|
||||
6) Start a local web server:
|
||||
7) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx http-server dist
|
||||
npx -y http-server dist
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) with a web browser
|
||||
|
@ -36,8 +36,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| Browser | Version | Date |
|
||||
|:-------------|:------------------|:-----------|
|
||||
| Chromium 125 | `1.8.2` (latest) | 2024-06-09 |
|
||||
| Chromium 125 | `1.2.32` (legacy) | 2024-06-09 |
|
||||
| Chromium 133 | `1.8.2` (latest) | 2025-03-30 |
|
||||
| Chromium 133 | `1.2.32` (legacy) | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -288,8 +288,13 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
</html>`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Start a local web server with `npx http-server .` and access the displayed
|
||||
URL with a web browser (typically `http://localhost:8080`)
|
||||
2) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx -y http-server .
|
||||
```
|
||||
|
||||
Access the displayed URL with a web browser (typically `http://localhost:8080`)
|
||||
|
||||
When the page loads, the app will fetch https://docs.sheetjs.com/pres.xlsx and
|
||||
store an array of objects in state. When the "Export Table" button is clicked,
|
||||
@ -387,8 +392,13 @@ app.controller('sheetjs', function($scope, $http) {
|
||||
</html>`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Start a local web server with `npx http-server .` and access the displayed
|
||||
URL with a web browser (typically `http://localhost:8080`)
|
||||
2) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx -y http-server .
|
||||
```
|
||||
|
||||
Access the displayed URL with a web browser (typically `http://localhost:8080`)
|
||||
|
||||
When the page loads, the app will fetch https://docs.sheetjs.com/pres.xlsx and
|
||||
store the HTML string in state. When the "Export Table" button is clicked, a
|
||||
|
@ -76,7 +76,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Platform | Date |
|
||||
|:-------------|:-----------|
|
||||
| Chromium 125 | 2024-06-08 |
|
||||
| Chromium 133 | 2025-03-30 |
|
||||
|
||||
Demos exclusively using Dojo Core were tested using Dojo Toolkit `1.17.3`.
|
||||
|
||||
|
@ -41,9 +41,10 @@ This demo was tested in the following environments:
|
||||
|
||||
| ViteJS | Date |
|
||||
|:---------|:-----------|
|
||||
| `5.4.10` | 2024-11-04 |
|
||||
| `4.5.5` | 2024-11-04 |
|
||||
| `3.2.11` | 2024-11-04 |
|
||||
| `6.2.3` | 2025-03-30 |
|
||||
| `5.4.15` | 2025-03-30 |
|
||||
| `4.5.10` | 2025-03-30 |
|
||||
| `3.2.11` | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -90,8 +90,8 @@ Each browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date |
|
||||
|:------------|:-----------|
|
||||
| Chrome 126 | 2024-06-19 |
|
||||
| Safari 17.3 | 2024-06-19 |
|
||||
| Chrome 133 | 2025-03-30 |
|
||||
| Safari 18.3 | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -411,9 +411,9 @@ This demo was tested in the following environments:
|
||||
| `12.22.12` | 2024-06-21 | |
|
||||
| `14.21.3` | 2024-06-21 | |
|
||||
| `16.20.2` | 2024-06-21 | |
|
||||
| `18.20.3` | 2024-06-21 | |
|
||||
| `20.15.0` | 2024-06-21 | |
|
||||
| `22.3.0` | 2024-06-21 | |
|
||||
| `18.20.8` | 2025-03-30 | |
|
||||
| `20.18.0` | 2025-03-30 | |
|
||||
| `22.14.0` | 2025-03-30 | |
|
||||
|
||||
The `NODE_TLS_REJECT_UNAUTHORIZED` workaround sets the value to `'0'`:
|
||||
|
||||
@ -484,9 +484,9 @@ This demo was tested in the following environments:
|
||||
|
||||
| NodeJS | Date |
|
||||
|:-----------|:-----------|
|
||||
| `18.20.3` | 2024-06-21 |
|
||||
| `20.15.0` | 2024-06-21 |
|
||||
| `22.3.0` | 2024-06-21 |
|
||||
| `18.20.8` | 2025-03-30 |
|
||||
| `20.18.0` | 2025-03-30 |
|
||||
| `22.14.0` | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -579,9 +579,9 @@ This demo was tested in the following environments:
|
||||
| `12.22.12` | 2024-06-21 | |
|
||||
| `14.21.3` | 2024-06-21 | |
|
||||
| `16.20.2` | 2024-06-21 | |
|
||||
| `18.20.3` | 2024-06-21 | |
|
||||
| `20.15.0` | 2024-06-21 | |
|
||||
| `22.3.0` | 2024-06-21 | |
|
||||
| `18.20.8` | 2025-03-30 | |
|
||||
| `20.18.0` | 2025-03-30 | |
|
||||
| `22.14.0` | 2025-03-30 | |
|
||||
|
||||
The `NODE_TLS_REJECT_UNAUTHORIZED` workaround sets the value to `'0'`:
|
||||
|
||||
@ -651,9 +651,9 @@ This demo was tested in the following environments:
|
||||
| `12.22.12` | 1.7.2 | 2024-06-21 |
|
||||
| `14.21.3` | 1.7.2 | 2024-06-21 |
|
||||
| `16.20.2` | 1.7.2 | 2024-06-21 |
|
||||
| `18.20.3` | 1.7.2 | 2024-06-21 |
|
||||
| `20.15.0` | 1.7.2 | 2024-06-21 |
|
||||
| `22.3.0` | 1.7.2 | 2024-06-21 |
|
||||
| `18.20.8` | 1.8.4 | 2025-03-30 |
|
||||
| `20.18.0` | 1.8.4 | 2025-03-30 |
|
||||
| `22.14.0` | 1.8.4 | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
@ -663,7 +663,7 @@ This demo was tested in the following environments:
|
||||
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz axios@1.7.2`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz axios@1.8.4`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Save the following to `SheetJSAxios.js`:
|
||||
|
@ -135,8 +135,8 @@ Each browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date |
|
||||
|:------------|:-----------|
|
||||
| Chrome 126 | 2024-06-19 |
|
||||
| Safari 17.3 | 2024-06-19 |
|
||||
| Chrome 133 | 2025-03-30 |
|
||||
| Safari 18.3 | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -169,7 +169,7 @@ export default defineConfig({
|
||||
plugins: [
|
||||
{ // this plugin handles ?sheetjs tags
|
||||
name: "vite-sheet",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?sheetjs$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
@ -243,7 +243,7 @@ export default defineConfig({
|
||||
plugins: [
|
||||
{ // this plugin handles ?html tags
|
||||
name: "vite-sheet-html",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?html/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?html/, "")));
|
||||
var html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
@ -309,7 +309,7 @@ export default defineConfig({
|
||||
plugins: [
|
||||
{ // this plugin handles ?b64 tags
|
||||
name: "vite-b64-plugin",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?b64$/)) return;
|
||||
var path = id.replace(/\?b64/, "");
|
||||
var data = readFileSync(path, "base64");
|
||||
@ -356,10 +356,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| ViteJS | Date |
|
||||
|:---------|:-----------|
|
||||
| `5.2.12` | 2024-06-02 |
|
||||
| `4.5.3` | 2024-06-02 |
|
||||
| `3.2.10` | 2024-06-02 |
|
||||
| `2.9.18` | 2024-06-02 |
|
||||
| `6.2.3` | 2025-03-30 |
|
||||
| `5.4.15` | 2025-03-30 |
|
||||
| `4.5.10` | 2025-03-30 |
|
||||
| `3.2.11` | 2025-03-30 |
|
||||
| `2.9.18` | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -53,15 +53,15 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS | Device | Config | Date |
|
||||
|:-----------|:--------------------|:-------|:-----------|
|
||||
| Android 30 | NVIDIA Shield | A | 2024-05-30 |
|
||||
| iOS 15.1 | iPad Pro | A | 2024-05-30 |
|
||||
| Android 34 | NVIDIA Shield | B | 2025-03-30 |
|
||||
| iOS 15.6 | iPhone 13 Pro Max | B | 2025-03-30 |
|
||||
|
||||
**Simulators**
|
||||
|
||||
| OS | Device | Config | Dev Platform | Date |
|
||||
|:-----------|:--------------------|:-------|:-------------|:-----------|
|
||||
| Android 34 | Pixel 3a | A | `darwin-arm` | 2024-05-30 |
|
||||
| iOS 17.5 | iPhone SE (3rd gen) | A | `darwin-arm` | 2024-05-30 |
|
||||
| Android 34 | Pixel 3a | B | `darwin-arm` | 2025-03-30 |
|
||||
| iOS 18.2 | iPhone SE (3rd gen) | B | `darwin-arm` | 2025-03-30 |
|
||||
|
||||
<details>
|
||||
<summary><b>Configurations</b> (click to show)</summary>
|
||||
@ -72,6 +72,12 @@ Configuration A:
|
||||
- Cordova: `cordova-lib@12.0.1`, `android 13.0.0, ios 7.1.0`
|
||||
- File Integration: `@awesome-cordova-plugins/file` version `6.7.0`
|
||||
|
||||
Configuration B:
|
||||
|
||||
- Ionic: `@ionic/angular 8.5.2`, `@ionic/angular-toolkit 12.1.1`
|
||||
- Cordova: `cordova-lib@12.0.2`, `android 14.0.0, ios 7.1.1`
|
||||
- File Integration: `@awesome-cordova-plugins/file` version `6.16.0`
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
@ -81,15 +87,15 @@ Configuration A:
|
||||
Before starting this demo, manually disable telemetry:
|
||||
|
||||
```bash
|
||||
npx @ionic/cli config set -g telemetry false
|
||||
npx @capacitor/cli telemetry off
|
||||
npx -y @ionic/cli config set -g telemetry false
|
||||
npx -y @capacitor/cli telemetry off
|
||||
```
|
||||
|
||||
To verify telemetry was disabled:
|
||||
|
||||
```bash
|
||||
npx @ionic/cli config get -g telemetry
|
||||
npx @capacitor/cli telemetry
|
||||
npx -y @ionic/cli config get -g telemetry
|
||||
npx -y @capacitor/cli telemetry
|
||||
```
|
||||
|
||||
:::
|
||||
@ -223,7 +229,12 @@ known location. After writing, an alert will display the location of the file.
|
||||
|
||||
### Platform Setup
|
||||
|
||||
0) Disable telemetry as noted in the warning.
|
||||
0) Disable telemetry:
|
||||
|
||||
```bash
|
||||
npx -y @ionic/cli config set -g telemetry false
|
||||
npx -y @capacitor/cli telemetry off
|
||||
```
|
||||
|
||||
1) Follow the official instructions for iOS and Android development[^9].
|
||||
|
||||
@ -262,7 +273,7 @@ When asked to select `NgModules` or `Standalone Components`, select `NgModules`
|
||||
|
||||
If a prompt asks to confirm Cordova use, enter <kbd>Y</kbd> to continue.
|
||||
|
||||
If a prompt asks about creating an Ionic account, enter <kbd>N</kbd> to opt out.
|
||||
If a prompt asks to create an Ionic account, enter <kbd>N</kbd> to opt out.
|
||||
|
||||
:::caution pass
|
||||
|
||||
@ -284,28 +295,9 @@ cd ..
|
||||
```bash
|
||||
cd SheetJSIonic
|
||||
ionic cordova plugin add cordova-plugin-file
|
||||
ionic cordova platform add android --confirm
|
||||
ionic cordova platform add ios --confirm
|
||||
npm i --save @awesome-cordova-plugins/core @awesome-cordova-plugins/file @ionic/cordova-builders
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
If `cordova-plugin-file` is added before the platforms, installation may fail:
|
||||
|
||||
```
|
||||
CordovaError: Could not load API for ios project
|
||||
```
|
||||
|
||||
This can be resolved by removing and reinstalling the `ios` platform:
|
||||
|
||||
```bash
|
||||
ionic cordova platform rm ios
|
||||
ionic cordova platform add ios --confirm
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
If the `npm i` step fails due to `rxjs` resolution, add the highlighted lines
|
||||
@ -375,10 +367,144 @@ curl.exe -o src/app/home/home.page.ts -L https://docs.sheetjs.com/ionic/home.pag
|
||||
|
||||
:::
|
||||
|
||||
### Android
|
||||
|
||||
8) Add the Android platform to the project:
|
||||
|
||||
```bash
|
||||
ionic cordova platform add android --confirm
|
||||
npm i --save cordova-android
|
||||
```
|
||||
|
||||
9) Enable file reading and writing in the Android app.
|
||||
|
||||
Edit `platforms/android/app/src/main/AndroidManifest.xml` and add the following
|
||||
two lines before the `application` tag:
|
||||
|
||||
```xml title="platforms/android/app/src/main/AndroidManifest.xml (add to file)"
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
```
|
||||
|
||||
In the `application` tag, add the attribute `android:requestLegacyExternalStorage="true"`.
|
||||
|
||||
10) Build the app and start the emulator:
|
||||
|
||||
```bash
|
||||
ionic cordova emulate android
|
||||
```
|
||||
|
||||
When the app is loaded, a list of Presidents should be displayed. This list is
|
||||
dynamically generated by fetching and parsing a test file.
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some test runs, `cordova build android --emulator` step failed with error:
|
||||
|
||||
```
|
||||
Could not find or parse valid build output file
|
||||
```
|
||||
|
||||
This was resolved by forcefully installing `cordova-android`:
|
||||
|
||||
```bash
|
||||
npm i --save cordova-android
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some test runs, Ionic could not find the emulator:
|
||||
|
||||
```
|
||||
ERR_NO_TARGET: No target devices/emulators available.
|
||||
```
|
||||
|
||||
The target emulator can be found by running
|
||||
|
||||
```bash
|
||||
avdmanager list avd
|
||||
```
|
||||
|
||||
In a test run, the output showed a Pixel 3a with the following details:
|
||||
|
||||
```text
|
||||
// highlight-next-line
|
||||
Name: Pixel_3a_API_34
|
||||
Device: pixel_3a (Google)
|
||||
Path: /Users/SheetJS/.android/avd/Pixel_4_API_33.avd
|
||||
```
|
||||
|
||||
The Ionic command accepts a `--target` flag. Pass the emulator name:
|
||||
|
||||
```bash
|
||||
ionic cordova emulate android --target=Pixel_3a_API_34
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some tests, the build failed with a Gradle error:
|
||||
|
||||
```
|
||||
Could not find an installed version of Gradle either in Android Studio,
|
||||
or on your system to install the gradle wrapper. Please include gradle
|
||||
in your path or install Android Studio
|
||||
```
|
||||
|
||||
On macOS, this issue was resolved by installing Gradle with Homebrew manager:
|
||||
|
||||
```bash
|
||||
brew install gradle
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::danger pass
|
||||
|
||||
When the demo was last tested on Android, reading files worked as expected.
|
||||
However, the generated files were not externally visible from the Files app.
|
||||
|
||||
**This is a known bug with Android SDK 33 and the underlying file plugins!**
|
||||
|
||||
:::
|
||||
|
||||
### iOS
|
||||
|
||||
8) Enable file sharing and make the documents folder visible in the iOS app.
|
||||
:::danger pass
|
||||
|
||||
**iOS testing can only be performed on Apple hardware running macOS!**
|
||||
|
||||
Xcode and iOS simulators are not available on Windows or Linux.
|
||||
|
||||
:::
|
||||
|
||||
11) Add the iOS platform to the project:
|
||||
|
||||
```bash
|
||||
ionic cordova platform add ios --confirm
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
If `cordova-plugin-file` is added before the platforms, installation may fail:
|
||||
|
||||
```
|
||||
CordovaError: Could not load API for ios project
|
||||
```
|
||||
|
||||
This can be resolved by removing and reinstalling the `ios` platform:
|
||||
|
||||
```bash
|
||||
ionic cordova platform rm ios
|
||||
ionic cordova platform add ios --confirm
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
12) Enable file sharing and make the documents folder visible in the iOS app.
|
||||
Add the following lines to `platforms/ios/SheetJSIonic/SheetJSIonic-Info.plist`:
|
||||
|
||||
```xml title="platforms/ios/SheetJSIonic/SheetJSIonic-Info.plist (add to file)"
|
||||
@ -395,7 +521,7 @@ Add the following lines to `platforms/ios/SheetJSIonic/SheetJSIonic-Info.plist`:
|
||||
|
||||
(The root element of the document is `plist` and it contains one `dict` child)
|
||||
|
||||
9) Build the app and start the simulator
|
||||
13) Build the app and start the simulator
|
||||
|
||||
```bash
|
||||
ionic cordova emulate ios
|
||||
@ -464,71 +590,86 @@ ng add @ionic/cordova-builders
|
||||
|
||||
:::
|
||||
|
||||
### Android
|
||||
### iOS Device
|
||||
|
||||
10) Enable file reading and writing in the Android app.
|
||||
14) Connect an iOS device to the computer and "Trust" the device if prompted.
|
||||
|
||||
Edit `platforms/android/app/src/main/AndroidManifest.xml` and add the following
|
||||
two lines before the `application` tag:
|
||||
15) Enable code signing for the project:
|
||||
|
||||
```xml title="platforms/android/app/src/main/AndroidManifest.xml (add to file)"
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
```
|
||||
|
||||
In the `application` tag, add the attribute `android:requestLegacyExternalStorage="true"`.
|
||||
|
||||
11) Build the app and start the emulator
|
||||
Open the `SheetJSIonic.xcodeproj` project in Xcode:
|
||||
|
||||
```bash
|
||||
ionic cordova emulate android
|
||||
open platforms/ios/SheetJSIonic.xcodeproj
|
||||
```
|
||||
|
||||
When the app is loaded, a list of Presidents should be displayed. This list is
|
||||
dynamically generated by fetching and parsing a test file.
|
||||
Select the "SheetJSIonic" project in the "Project navigator" side panel.
|
||||
|
||||
:::caution pass
|
||||
In the main panel, select "Signing & Capabilities".
|
||||
|
||||
In some test runs, `cordova build android --emulator` step failed with error:
|
||||
In the "Team" dropdown, select a certificate.
|
||||
|
||||
```
|
||||
Could not find or parse valid build output file
|
||||
```
|
||||
In the "Bundle Identifier" text box, enter `com.sheetjs.SheetJSIonic`
|
||||
|
||||
This was resolved by forcefully installing `cordova-android`:
|
||||
16) Launch the app on the device:
|
||||
|
||||
```bash
|
||||
npm i --save cordova-android
|
||||
ionic cordova run ios --device --verbose
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
In the most recent test, the `native-run ios` command failed with
|
||||
|
||||
```
|
||||
[native-run] ERR_UNKNOWN: Path 'platforms/ios/build/device/SheetJSIonic.ipa' not found
|
||||
```
|
||||
|
||||
Inspecting `platforms/ios/build/`, the actual folder name was:
|
||||
|
||||
```bash
|
||||
% ls platforms/ios/build
|
||||
#highlight-next-line
|
||||
Debug-iphoneos
|
||||
```
|
||||
|
||||
To force `native-run` to use the device, the name must be found by inspecting
|
||||
the output of `native-run ios --list`:
|
||||
|
||||
```bash
|
||||
% native-run ios --list
|
||||
|
||||
Connected Devices:
|
||||
|
||||
Name API Target ID
|
||||
---------------------------------------------
|
||||
SheetJS iOS 15.6 12345678-90ABCDEF12345678
|
||||
|
||||
```
|
||||
|
||||
`native-run` accepts a `--device` flag. Pass the device name:
|
||||
|
||||
|
||||
```bash
|
||||
native-run ios --app platforms/ios/build/Debug-iphoneos/SheetJSIonic.ipa --device SheetJS
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
17) Test the app.
|
||||
|
||||
In some tests, the build failed with a Gradle error:
|
||||
The app will fetch a file and display the contents in a table.
|
||||
|
||||
```
|
||||
Could not find an installed version of Gradle either in Android Studio,
|
||||
or on your system to install the gradle wrapper. Please include gradle
|
||||
in your path or install Android Studio
|
||||
```
|
||||
Tap "Export Data" to create a file. To find the file, switch to the "Files" app
|
||||
and browse "On My iPhone" > "SheetJSIonic". There should be a new spreadsheet
|
||||
named "SheetJSIonic".
|
||||
|
||||
On macOS, this issue was resolved by installing Gradle with Homebrew manager:
|
||||
Switch to the "Numbers" app and open that file. Tap "EDIT" to make changes.
|
||||
Change cell A7 to "SheetJS Dev" and cell B7 to 47. Tap "Done" and close the app.
|
||||
|
||||
```bash
|
||||
brew install gradle
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::danger pass
|
||||
|
||||
When the demo was last tested on Android, reading files worked as expected.
|
||||
However, the generated files were not externally visible from the Files app.
|
||||
|
||||
**This is a known bug with Android SDK 33 and the underlying file plugins!**
|
||||
|
||||
:::
|
||||
Switch back to "SheetJSIonic" and tap "Import Data". Tap "Choose Files" in the
|
||||
popup. Tap "Browse" in the bottom of the sheet. Navigate to "On My iPhone" >
|
||||
"SheetJSIonic" and tap the new "SheetJSIonic" spreadsheet. The screen will show
|
||||
the file with the new line.
|
||||
|
||||
[^1]: See ["Array of Arrays" in the API reference](/docs/api/utilities/array#array-of-arrays)
|
||||
[^2]: See [`ion-grid`](https://ionicframework.com/docs/api/grid) in the Ionic documentation.
|
||||
|
@ -53,8 +53,8 @@ This demo was tested in the following environments:
|
||||
|:-----------|:--------------------|:------------------|:-------------|:-----------|
|
||||
| Android 35 | Pixel 9 Pro | `6.2.0` / `6.0.3` | `darwin-x64` | 2025-01-19 |
|
||||
| iOS 18.2 | iPhone 16 Pro Max | `6.2.0` / `6.0.3` | `darwin-x64` | 2025-01-19 |
|
||||
| Android 34 | Pixel 3a | `6.0.0` / `6.0.0` | `darwin-arm` | 2024-06-02 |
|
||||
| iOS 17.5 | iPhone 15 Pro Max | `6.0.0` / `6.0.0` | `darwin-arm` | 2024-06-02 |
|
||||
| Android 34 | Pixel 3a | `7.1.0` / `7.0.0` | `darwin-arm` | 2025-03-30 |
|
||||
| iOS 18.2 | iPhone 16 Pro Max | `7.1.0` / `7.0.0` | `darwin-arm` | 2025-03-30 |
|
||||
| Android 35 | Pixel 9 | `6.2.0` / `6.0.2` | `win11-x64` | 2024-12-21 |
|
||||
| Android 35 | Pixel 9 | `6.2.0` / `6.0.2` | `linux-x64` | 2025-01-02 |
|
||||
|
||||
@ -438,9 +438,8 @@ picker for saving the file. Select the `sheetjs-cap` folder and tap "Save". If
|
||||
prompted to "Replace Existing Items?", tap "Replace".
|
||||
|
||||
Switch back to the app and tap "Choose File". Tap "Choose File" in the popup.
|
||||
|
||||
Tap on "Choose File" in the app and "Choose File" in the popup. In the picker,
|
||||
tap "Recents" and select the newest `SheetJSCap` file. The table will refresh.
|
||||
In the picker, tap "Recents" and select the newest `SheetJSCap` file. The table
|
||||
will refresh with the new data.
|
||||
|
||||
### Android Device
|
||||
|
||||
|
@ -208,7 +208,7 @@ This demo was tested in the following environments:
|
||||
| OS and Version | Architecture | Electron | Date |
|
||||
|:---------------|:-------------|:---------|:-----------|
|
||||
| macOS 15.2 | `darwin-x64` | `33.2.1` | 2024-12-31 |
|
||||
| macOS 14.5 | `darwin-arm` | `30.0.8` | 2024-05-28 |
|
||||
| macOS 14.5 | `darwin-arm` | `35.1.2` | 2025-03-38 |
|
||||
| Windows 11 | `win11-x64` | `33.2.1` | 2025-02-11 |
|
||||
| Windows 11 | `win11-arm` | `33.2.1` | 2025-02-23 |
|
||||
| Linux (HoloOS) | `linux-x64` | `33.2.1` | 2025-01-02 |
|
||||
@ -361,7 +361,7 @@ and select `pres.numbers`.
|
||||
## Electron Breaking Changes
|
||||
|
||||
The first version of this demo used Electron `1.7.5`. The current demo includes
|
||||
the required changes for Electron `33.2.1`.
|
||||
the required changes for Electron `35.1.2`.
|
||||
|
||||
There are no Electron-specific workarounds in the library, but Electron broke
|
||||
backwards compatibility multiple times. A summary of changes is noted below.
|
||||
|
@ -122,7 +122,7 @@ This demo was tested in the following environments:
|
||||
| OS and Version | Architecture | NW.js | Date | Notes |
|
||||
|:---------------|:-------------|:---------|:-----------|:---------------------|
|
||||
| macOS 15.2 | `darwin-x64` | `0.94.0` | 2024-12-31 | |
|
||||
| macOS 14.5 | `darwin-arm` | `0.88.0` | 2024-05-28 | |
|
||||
| macOS 14.5 | `darwin-arm` | `0.94.0` | 2025-03-30 | |
|
||||
| Windows 11 | `win11-x64` | `0.94.0` | 2024-12-19 | |
|
||||
| Windows 11 | `win11-arm` | `0.94.0` | 2025-02-23 | |
|
||||
| Linux (HoloOS) | `linux-x64` | `0.89.0` | 2025-01-10 | |
|
||||
@ -225,6 +225,7 @@ testing, version `4.11.6` correctly generated the standalone application.
|
||||
| Architecture | Command |
|
||||
|:-------------|:--------------------------------------------------------------|
|
||||
| `darwin-x64` | `open ../out/sheetjs-nwjs.app` |
|
||||
| `darwin-arm` | `open ../out/sheetjs-nwjs.app` |
|
||||
| `win11-x64` | `..\out\sheetjs-nwjs.exe` |
|
||||
| `win11-arm` | `..\out\sheetjs-nwjs.exe` |
|
||||
| `linux-x64` | `../out/sheetjs-nwjs` |
|
||||
|
@ -295,14 +295,14 @@ async function exportFile(table_element) {
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| OS and Version | Architecture | Wails | Date |
|
||||
|:---------------|:-------------|:---------|:-----------|
|
||||
| macOS 15.2 | `darwin-x64` | `v2.9.2` | 2024-12-31 |
|
||||
| macOS 14.5 | `darwin-arm` | `v2.8.2` | 2024-05-28 |
|
||||
| Windows 11 | `win11-x64` | `v2.9.2` | 2024-12-21 |
|
||||
| Windows 11 | `win11-arm` | `v2.10` | 2025-02-23 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v2.9.2` | 2025-01-02 |
|
||||
| Linux (Debian) | `linux-arm` | `v2.10` | 2025-02-16 |
|
||||
| OS and Version | Architecture | Wails | Date |
|
||||
|:---------------|:-------------|:----------|:-----------|
|
||||
| macOS 15.2 | `darwin-x64` | `v2.9.2` | 2024-12-31 |
|
||||
| macOS 14.5 | `darwin-arm` | `v2.10.1` | 2025-03-30 |
|
||||
| Windows 11 | `win11-x64` | `v2.9.2` | 2024-12-21 |
|
||||
| Windows 11 | `win11-arm` | `v2.10` | 2025-02-23 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v2.9.2` | 2025-01-02 |
|
||||
| Linux (Debian) | `linux-arm` | `v2.10` | 2025-02-16 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -354,7 +354,7 @@ This demo was tested in the following environments:
|
||||
| OS and Version | Architecture | Tauri | Date |
|
||||
|:---------------|:-------------|:----------|:-----------|
|
||||
| macOS 15.2 | `darwin-x64` | `v1.6.0` | 2024-12-31 |
|
||||
| macOS 14.5 | `darwin-arm` | `v1.5.14` | 2024-05-26 |
|
||||
| macOS 14.5 | `darwin-arm` | `v1.6.0` | 2025-03-30 |
|
||||
| Windows 11 | `win11-x64` | `v1.6.0` | 2024-12-21 |
|
||||
| Windows 11 | `win11-arm` | `v1.6.0` | 2025-02-23 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v1.6.0` | 2025-01-02 |
|
||||
@ -384,16 +384,17 @@ If required dependencies are installed, the output will show a checkmark next to
|
||||
|
||||
<pre>
|
||||
<span {...g}>[✔]</span> <span style={{...y.style,...B.style}}>Environment</span>
|
||||
{` `}<span {...c}>-</span> <span {...B}>OS</span>: Mac OS 15.2.0 x86_64 (X64)
|
||||
{` `}<span {...c}>-</span> <span {...B}>OS</span>: Mac OS 14.5.0 arm64 (X64)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>Xcode Command Line Tools</span>: installed
|
||||
{` `}<span {...g}>✔</span> <span {...B}>rustc</span>: 1.83.0 (90b35a623 2024-11-26)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>cargo</span>: 1.83.0 (5ffbef321 2024-10-29)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>rustup</span>: 1.27.1 (54dd3d00f 2024-04-24)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>Rust toolchain</span>: stable-x86_64-apple-darwin (default)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>rustc</span>: 1.85.1 (4eb161250 2025-03-15)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>cargo</span>: 1.85.1 (d73d2caf9 2024-12-31)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>rustup</span>: 1.28.1 (f9edccde0 2025-03-05)
|
||||
{` `}<span {...g}>✔</span> <span {...B}>Rust toolchain</span>: stable-aarch64-apple-darwin (default)
|
||||
{` `}<span {...c}>-</span> <span {...B}>node</span>: 20.18.0
|
||||
{` `}<span {...c}>-</span> <span {...B}>pnpm</span>: 9.12.3
|
||||
{` `}<span {...c}>-</span> <span {...B}>npm</span>: 10.8.2
|
||||
{` `}<span {...c}>-</span> <span {...B}>bun</span>: 1.1.42
|
||||
{` `}<span {...c}>-</span> <span {...B}>deno</span>: deno 2.1.4
|
||||
{` `}<span {...c}>-</span> <span {...B}>bun</span>: 1.2.7
|
||||
{` `}<span {...c}>-</span> <span {...B}>deno</span>: deno 2.2.6
|
||||
</pre>
|
||||
|
||||
:::caution pass
|
||||
@ -536,7 +537,7 @@ export default defineConfig(async () => ({
|
||||
|
||||
- Replace `index.html` with the following codeblock:
|
||||
|
||||
```html title="index.html"
|
||||
```html title="index.html (replace contents)"
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@ -573,7 +574,7 @@ table.center {
|
||||
|
||||
- Replace `src/main.ts` with the following codeblock:
|
||||
|
||||
```ts title="src/main.ts"
|
||||
```ts title="src/main.ts (replace contents)"
|
||||
import { mount } from "kaioken";
|
||||
import App from "./App";
|
||||
|
||||
|
@ -193,7 +193,7 @@ This demo was tested in the following environments:
|
||||
| OS and Version | Architecture | Server | Client | Date |
|
||||
|:---------------|:-------------|:---------|:---------|:-----------|
|
||||
| macOS 15.2 | `darwin-x64` | `5.5.0` | `5.5.0` | 2024-12-31 |
|
||||
| macOS 14.5 | `darwin-arm` | `5.1.0` | `5.1.0` | 2024-05-25 |
|
||||
| macOS 14.5 | `darwin-arm` | `6.0.0` | `6.0.0` | 2025-03-30 |
|
||||
| Windows 11 | `win11-x64` | `5.5.0` | `5.5.0` | 2024-12-20 |
|
||||
| Windows 11 | `win11-arm` | `5.6.0` | `5.6.0` | 2025-02-23 |
|
||||
| Linux (HoloOS) | `linux-x64` | `5.5.0` | `5.5.0` | 2025-01-02 |
|
||||
|
@ -158,15 +158,15 @@ This browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date |
|
||||
|:------------|:-----------|
|
||||
| Chrome 118 | 2024-06-29 |
|
||||
| Chrome 118 | 2025-03-30 |
|
||||
|
||||
Browsers that do not support WebSQL will throw errors:
|
||||
|
||||
| Browser | Date | Error Message |
|
||||
|:------------|:-----------|:------------------------------|
|
||||
| Chrome 126 | 2024-06-29 | `openDatabase is not defined` |
|
||||
| Safari 17.1 | 2024-06-29 | `Web SQL is deprecated` |
|
||||
| Firefox 127 | 2024-06-29 | `openDatabase is not defined` |
|
||||
| Chrome 133 | 2025-03-30 | `openDatabase is not defined` |
|
||||
| Safari 18.3 | 2025-03-30 | `Web SQL is deprecated` |
|
||||
| Firefox 136 | 2025-03-30 | `openDatabase is not defined` |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -28,8 +28,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| macOS | Language | Date |
|
||||
|:-------|:------------------|:-----------|
|
||||
| `14.5` | AppleScript (OSA) | 2024-06-30 |
|
||||
| `14.5` | JavaScript (JXA) | 2024-06-30 |
|
||||
| `14.5` | AppleScript (OSA) | 2025-03-30 |
|
||||
| `14.5` | JavaScript (JXA) | 2025-03-30 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -548,7 +548,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | Version | Python | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `3.13.1` | 2024-12-31 |
|
||||
| `darwin-arm` | `2.7.0` | `3.12.3` | 2024-06-30 |
|
||||
| `darwin-arm` | `2.7.0` | `3.12.3` | 2025-03-30 |
|
||||
| `linux-x64` | `2.7.0` | `3.11.7` | 2024-12-31 |
|
||||
| `linux-arm` | `2.7.0` | `3.11.2` | 2025-02-15 |
|
||||
|
||||
@ -1020,7 +1020,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.2.0` | 2024-12-31 |
|
||||
| `darwin-arm` | `2.2.0` | 2024-06-30 |
|
||||
| `darwin-arm` | `2.2.0` | 2025-03-30 |
|
||||
| `linux-x64` | `2.2.0` | 2024-12-31 |
|
||||
| `linux-arm` | `2.2.0` | 2025-02-15 |
|
||||
|
||||
|
@ -1118,7 +1118,7 @@ This demo was last tested in the following deployments:
|
||||
| Architecture | V8 Version | Javet | Java | Date |
|
||||
|:-------------|:--------------|:--------|:----------|:-----------|
|
||||
| `darwin-x64` | `13.2.152.16` | `4.1.1` | `22` | 2025-01-19 |
|
||||
| `darwin-arm` | `12.6.228.13` | `3.1.3` | `11.0.23` | 2024-06-19 |
|
||||
| `darwin-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-03-30 |
|
||||
| `win11-x64` | `12.6.228.13` | `3.1.3` | `21.0.5` | 2024-12-20 |
|
||||
| `linux-x64` | `12.6.228.13` | `3.1.3` | `17.0.7` | 2024-06-20 |
|
||||
| `linux-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-02-16 |
|
||||
@ -1149,7 +1149,8 @@ curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-v8-macos-x86_64/
|
||||
<TabItem value="darwin-arm" label="ARM64 Mac">
|
||||
|
||||
```bash
|
||||
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-macos/3.1.3/javet-macos-3.1.3.jar
|
||||
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet/4.1.1/javet-4.1.1.jar
|
||||
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-v8-macos-arm64/4.1.1/javet-v8-macos-arm64-4.1.1.jar
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -1216,8 +1217,8 @@ java -cp ".:javet-4.1.1.jar:javet-v8-macos-x86_64-4.1.1.jar" SheetJSJavet pres.x
|
||||
<TabItem value="darwin-arm" label="ARM64 Mac">
|
||||
|
||||
```bash
|
||||
javac -cp ".:javet-macos-3.1.3.jar" SheetJSJavet.java
|
||||
java -cp ".:javet-macos-3.1.3.jar" SheetJSJavet pres.xlsx
|
||||
javac -cp ".:javet-4.1.1.jar:javet-v8-macos-arm64-4.1.1.jar" SheetJSJavet.java
|
||||
java -cp ".:javet-4.1.1.jar:javet-v8-macos-arm64-4.1.1.jar" SheetJSJavet pres.xlsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -1279,7 +1280,7 @@ This demo was last tested in the following deployments:
|
||||
| Architecture | V8 Version | Date |
|
||||
|:-------------|:--------------|:-----------|
|
||||
| `darwin-x64` | `12.3.219.12` | 2024-07-16 |
|
||||
| `darwin-arm` | `12.3.219.12` | 2024-07-16 |
|
||||
| `darwin-arm` | `12.3.219.12` | 2025-03-30 |
|
||||
| `win11-x64` | `12.3.219.12` | 2024-12-20 |
|
||||
| `win11-arm` | `12.3.219.12` | 2025-02-23 |
|
||||
| `linux-x64` | `12.3.219.12` | 2025-01-10 |
|
||||
|
@ -33,7 +33,7 @@ Swift on MacOS supports JavaScriptCore without additional dependencies.
|
||||
| Architecture | Swift | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `6.0.2` | 2024-12-17 |
|
||||
| `darwin-arm` | `5.10` | 2024-06-30 |
|
||||
| `darwin-arm` | `6.0.3` | 2025-03-30 |
|
||||
|
||||
[**C / C++ Compiled from Source**](#c)
|
||||
|
||||
@ -753,13 +753,51 @@ to `SheetJSwift.xlsx`, which can be opened in a spreadsheet editor.
|
||||
It is straightforward to load the platform-native (macOS) or compiled libraries
|
||||
in programs built in other programming languages.
|
||||
|
||||
The JavaScriptCore C interface does not use "blingos" (function-like macros), so
|
||||
it is possible to reference each method in an external binding.
|
||||
|
||||
### Rust
|
||||
|
||||
Writing bindings is fairly mechanical. For example, the following C code
|
||||
creates a string within the engine from a UTF8 string:
|
||||
Writing bindings is fairly mechanical. There are 4 parts to the process:
|
||||
|
||||
```c
|
||||
JSStringRef script = JSStringCreateWithUTF8CString("SheetJS");
|
||||
0) Link to the external library.
|
||||
|
||||
1) Generate Rust representations of the original C data types.
|
||||
|
||||
2) Translate the function declaration.
|
||||
|
||||
3) Write a wrapper to convert between Rust concepts and C concepts.
|
||||
|
||||
For example, the following C code creates a string within the engine from a
|
||||
UTF8 string:
|
||||
|
||||
```c title="Sample use of JSStringCreateWithUTF8CString"
|
||||
const char *code = "'Sheet' + 'JS'";
|
||||
JSStringRef script = JSStringCreateWithUTF8CString(code);
|
||||
```
|
||||
|
||||
An ergonomic wrapper function would take a Rust string literal and handle unsafe
|
||||
data operations:
|
||||
|
||||
```rust title="Theoretical equivalent in Rust"
|
||||
let code: &str = "'Sheet' + 'JS'";
|
||||
let script: JSStringRef = JSC::JSStringCreateWithUTF8CString(code);
|
||||
```
|
||||
|
||||
**Rust Linkage**
|
||||
|
||||
Custom directives are typically added to `build.rs`. The `cargo::rustc-link-lib`
|
||||
directive instructs the Rust compiler to link against an external library.
|
||||
|
||||
The following snippet will instruct the toolchain to link against the system
|
||||
`JavaScriptCore.framework` framework on macOS:
|
||||
|
||||
```rust title="build.rs (link to JavaScriptCore.framework on macOS)"
|
||||
#[cfg(target_os = "macos")]
|
||||
fn main() {
|
||||
// highlight-next-line
|
||||
println!("cargo::rustc-link-lib=framework=JavaScriptCore");
|
||||
}
|
||||
```
|
||||
|
||||
**Rust Types**
|
||||
@ -767,7 +805,7 @@ JSStringRef script = JSStringCreateWithUTF8CString("SheetJS");
|
||||
`JSStringRef` is a pointer to an opaque data type. The spiritual equivalent
|
||||
according to the Rustonomicon is a pointer to an opaque struct[^9]:
|
||||
|
||||
```rust
|
||||
```rust title="JSStringRef opaque type in Rust"
|
||||
#[repr(C)]
|
||||
pub struct JSString {
|
||||
_data: [u8; 0],
|
||||
@ -779,7 +817,7 @@ type JSStringRef = *mut JSContext;
|
||||
|
||||
**Function Declaration**
|
||||
|
||||
The `JSStringCreateWithUTF8CString` function in declared in C as follows:
|
||||
The `JSStringCreateWithUTF8CString` function is declared in C as follows:
|
||||
|
||||
```c
|
||||
JSStringRef JSStringCreateWithUTF8CString(const char * string);
|
||||
@ -787,8 +825,9 @@ JSStringRef JSStringCreateWithUTF8CString(const char * string);
|
||||
|
||||
The equivalent Rust declaration must be defined in an `extern "C"` block:
|
||||
|
||||
```rust
|
||||
```rust title="JSStringCreateWithUTF8CString Rust declaration"
|
||||
unsafe extern "C" {
|
||||
// JSStringRef JSStringCreateWithUTF8CString(const char * string);
|
||||
pub unsafe fn JSStringCreateWithUTF8CString(string: *const u8) -> JSStringRef;
|
||||
}
|
||||
```
|
||||
@ -825,7 +864,7 @@ let ref: JSStringRef = JSStringCreateWithUTF8CString(cstr.as_ptr() as *const u8)
|
||||
|
||||
The demo makes a safe wrapper to perform the unsafe waltz in one line:
|
||||
|
||||
```rust
|
||||
```rust title="Ergonomic wrapper for JSStringCreateWithUTF8CString"
|
||||
pub struct JSC;
|
||||
impl JSC {
|
||||
pub fn JSStringCreateWithUTF8CString(str: &str) -> JSStringRef { unsafe {
|
||||
|
@ -177,7 +177,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | Jurassic | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `3.2.8` | 2024-12-17 |
|
||||
| `darwin-arm` | `3.2.7` | 2024-06-15 |
|
||||
| `darwin-arm` | `3.2.9` | 2025-03-30 |
|
||||
| `win11-x64` | `3.2.8` | 2024-12-19 |
|
||||
| `win11-arm` | `3.2.9` | 2025-02-23 |
|
||||
| `linux-x64` | `3.2.8` | 2025-01-10 |
|
||||
|
@ -144,11 +144,11 @@ worker.addEventListener('message', function(e) {
|
||||
|
||||
:::danger pass
|
||||
|
||||
Each moving part in this solution has been deprecated years ago:
|
||||
Each moving part in this solution has been deprecated many years ago:
|
||||
|
||||
- Adobe stopped supporting Flash Player at the end of 2020
|
||||
- Microsoft stopped supporting IE8 in 2019 and stopped supporting IE9 in 2020
|
||||
- `Downloadify` support ended in 2010 and `SWFObject` support ended in 2016
|
||||
- Adobe discontinued Flash Player
|
||||
- Microsoft discontinued Internet Explorer
|
||||
- `Downloadify` and `SWFObject` are no longer supported
|
||||
|
||||
New projects should strongly consider requiring modern browsers. This info is
|
||||
provided on an "as is" basis and there is no realistic way to provide support
|
||||
|
@ -340,9 +340,9 @@ _Assign a dynamic array formula_
|
||||
XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true);
|
||||
```
|
||||
|
||||
Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB
|
||||
file formats. They are represented like normal array formulae but have special
|
||||
cell metadata indicating that the formula should be allowed to adjust the range.
|
||||
Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB file formats.
|
||||
They are internally stored as normal array formulae but have special cell
|
||||
metadata indicating that the formula should be allowed to adjust the range.
|
||||
|
||||
An array formula can be marked as dynamic by setting the cell `D` property to
|
||||
true. The `F` range is expected but can be the set to the current cell:
|
||||
|
@ -15,12 +15,12 @@
|
||||
"make": "electron-forge make"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.6.0",
|
||||
"@electron-forge/maker-deb": "7.6.0",
|
||||
"@electron-forge/maker-rpm": "7.6.0",
|
||||
"@electron-forge/maker-squirrel": "7.6.0",
|
||||
"@electron-forge/maker-zip": "7.6.0",
|
||||
"electron": "33.2.1"
|
||||
"@electron-forge/cli": "7.8.0",
|
||||
"@electron-forge/maker-deb": "7.8.0",
|
||||
"@electron-forge/maker-rpm": "7.8.0",
|
||||
"@electron-forge/maker-squirrel": "7.8.0",
|
||||
"@electron-forge/maker-zip": "7.8.0",
|
||||
"electron": "35.1.2"
|
||||
},
|
||||
"config": {
|
||||
"forge": {
|
||||
|
@ -10,6 +10,7 @@ type AOA = any[][];
|
||||
selector: 'app-home',
|
||||
//templateUrl: 'home.page.html',
|
||||
styleUrls: ['home.page.scss'],
|
||||
standalone: false,
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
|
@ -10,7 +10,7 @@ export default defineConfig({
|
||||
vue(),
|
||||
{ // this plugin handles ?sheetjs tags
|
||||
name: "vite-sheet",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?sheetjs$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
@ -19,7 +19,7 @@ export default defineConfig({
|
||||
},
|
||||
{ // this plugin handles ?html tags
|
||||
name: "vite-sheet-html",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?html/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?html/, "")));
|
||||
var html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
@ -28,7 +28,7 @@ export default defineConfig({
|
||||
},
|
||||
{ // this plugin handles ?b64 tags
|
||||
name: "vite-b64-plugin",
|
||||
transform(code, id) {
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?b64$/)) return;
|
||||
var path = id.replace(/\?b64/, "");
|
||||
var data = readFileSync(path, "base64");
|
||||
|
@ -1,72 +1,109 @@
|
||||
#!/bin/bash
|
||||
# https://docs.sheetjs.com/docs/demos/frontend/bundler/vitejs
|
||||
# NOTE: this only checks whether data or SheetJS code is added to the bundle
|
||||
|
||||
cd /tmp
|
||||
rm -rf sheetjs-vite-tests
|
||||
mkdir sheetjs-vite-tests
|
||||
cd sheetjs-vite-tests
|
||||
|
||||
for n in {3..5}; do
|
||||
npm create vite@$n sheetjs-vite$n -- --template vue-ts
|
||||
for n in {3..6}; do
|
||||
npm create -y vite@$n sheetjs-vite$n -- --template vue-ts
|
||||
cd sheetjs-vite$n
|
||||
npm i
|
||||
npm i --save puppeteer express@4
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
npm ls | grep vite
|
||||
|
||||
## See https://github.com/vuejs/language-tools/issues/4484#issuecomment-2182469459
|
||||
if [[ "$n" == "4" ]]; then npm i "vue-tsc@2"; fi
|
||||
|
||||
curl -O https://docs.sheetjs.com/vitejs/vite.config.ts
|
||||
|
||||
mkdir -p data
|
||||
curl -L -o data/pres.xlsx https://sheetjs.com/pres.xlsx
|
||||
curl -L -o data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
|
||||
|
||||
cat >src/components/HelloWorld.vue <<EOF
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import data from '../../data/pres.xlsx?sheetjs';
|
||||
import { version, utils, writeFileXLSX } from 'xlsx';
|
||||
|
||||
interface President {
|
||||
terms: { "type": "prez" | "viceprez"; }[];
|
||||
name: { first: string; last: string; }
|
||||
bio: { birthday: string; }
|
||||
}
|
||||
|
||||
async function xport() {
|
||||
/* fetch JSON data and parse */
|
||||
const url = "https://docs.sheetjs.com/executive.json";
|
||||
const raw_data: President[] = await (await fetch(url)).json();
|
||||
|
||||
/* filter for the Presidents */
|
||||
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
|
||||
|
||||
/* sort by first presidential term */
|
||||
prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start);
|
||||
prez.sort((l,r) => l.start.localeCompare(r.start));
|
||||
|
||||
/* flatten objects */
|
||||
const rows = prez.map(row => ({
|
||||
name: row.name.first + " " + row.name.last,
|
||||
birthday: row.bio.birthday
|
||||
}));
|
||||
|
||||
/* generate worksheet and workbook */
|
||||
const worksheet = utils.json_to_sheet(rows);
|
||||
const workbook = utils.book_new();
|
||||
utils.book_append_sheet(workbook, worksheet, "Dates");
|
||||
|
||||
/* fix headers */
|
||||
utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
|
||||
|
||||
/* calculate column width */
|
||||
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
|
||||
worksheet["!cols"] = [ { wch: max_width } ];
|
||||
|
||||
/* create an XLSX file and try to save to Presidents.xlsx */
|
||||
console.log(utils.sheet_to_csv(worksheet));
|
||||
writeFileXLSX(workbook, "Presidents.xlsx");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Index</th></tr>
|
||||
<tr v-for="(row,R) in data" v-bind:key="R">
|
||||
<td>{{row.Name}}</td>
|
||||
<td>{{row.Index}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" @click="xport">Export with SheetJS version {{ version }}</button>
|
||||
</template>
|
||||
EOF
|
||||
|
||||
npm run build
|
||||
echo "### Results: " $(grep Clinton -R dist | wc -l) $(grep BESSELJ -R dist | wc -l)
|
||||
npx vite build
|
||||
|
||||
cat >src/components/HelloWorld.vue <<EOF
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import b64 from '../../data/pres.xlsx?b64';
|
||||
import { read, utils } from "xlsx";
|
||||
/* parse workbook and convert first sheet to row array */
|
||||
const wb = read(b64);
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
interface IPresident { Name: string; Index: number; };
|
||||
const data = utils.sheet_to_json<IPresident>(ws);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Index</th></tr>
|
||||
<tr v-for="(row,R) in data" v-bind:key="R">
|
||||
<td>{{row.Name}}</td>
|
||||
<td>{{row.Index}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
cat >test.cjs <<EOF
|
||||
const puppeteer = require('puppeteer');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('./dist/'));
|
||||
app.listen(7262, async() => {
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
page.on("console", msg => console.log("PAGE LOG:", msg.text()));
|
||||
await page.setViewport({width: 1920, height: 1080});
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Browser.setDownloadBehavior', {
|
||||
behavior: 'allow',
|
||||
downloadPath: require("path").resolve('./')
|
||||
});
|
||||
page.on('request', req => console.log(req.url()));
|
||||
await page.goto('http://localhost:7262/');
|
||||
await page.click("button");
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await browser.close();
|
||||
process.exit();
|
||||
});
|
||||
EOF
|
||||
|
||||
npm run build
|
||||
echo "### Results: " $(grep Clinton -R dist | wc -l) $(grep BESSELJ -R dist | wc -l)
|
||||
node test.cjs
|
||||
npx -y xlsx-cli Presidents.xlsx | head -n 3
|
||||
rm -f Presidents.xlsx
|
||||
|
||||
|
||||
cd -
|
||||
|
||||
done
|
||||
|
@ -6,7 +6,7 @@ rm -rf sheetjs-vite-static
|
||||
mkdir sheetjs-vite-static
|
||||
cd sheetjs-vite-static
|
||||
|
||||
for n in {2..5}; do
|
||||
for n in {2..6}; do
|
||||
npm create -y vite@$n sheetjs-vite-$n -- --template vue-ts
|
||||
cd sheetjs-vite-$n
|
||||
npm i
|
||||
@ -24,9 +24,13 @@ if [[ "$n" == "2" ]]; then
|
||||
# Please update to v0.35.0 or higher for TypeScript version: 4.9.5
|
||||
#
|
||||
# Forcefully upgrading `vue-tsc` appears to be innocuous.
|
||||
npm i --save vue-tsc@latest
|
||||
npm i --save "vue-tsc@1.x"
|
||||
elif [[ "$n" == "4" ]]; then
|
||||
# Search string not found: "/supportedTSExtensions = .*(?=;)/"
|
||||
npm i --save "vue-tsc@2"
|
||||
fi
|
||||
curl -O https://docs.sheetjs.com/vitejs/vite.config.ts
|
||||
|
||||
mkdir -p data
|
||||
curl -L -o data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user