darwin-arm

This commit is contained in:
SheetJS 2023-10-19 01:23:55 -04:00
parent b230d64dd6
commit 2505d3b639
22 changed files with 620 additions and 412 deletions

@ -97,6 +97,8 @@ require(['xlsx'], function(XLSX) {
});
```
**See the [RequireJS demo](/docs/demos/frontend/bundler/requirejs) for details**
## Dojo Toolkit
Dojo has changed module loading strategies over the years. These examples were

@ -448,7 +448,8 @@ In the component, `aoa_to_sheet` is used to generate the worksheet:
The default angular-cli configuration requires no additional configuration.
Some deployments use the SystemJS loader, which does require configuration.
[The SystemJS demo](/docs/demos/bundler#systemjs) describe the required settings.
[The SystemJS demo](/docs/demos/frontend/bundler/systemjs) includes the
required settings.
### Legacy Demo

@ -0,0 +1,225 @@
---
title: Bundling Sheets with RequireJS
sidebar_label: RequireJS
pagination_prev: demos/index
pagination_next: demos/grid/index
sidebar_position: 11
---
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
[RequireJS](https://requirejs.org/) is a JavaScript file and module loader. It
includes an in-browser loader as well as a static optimizer.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses RequireJS and SheetJS to export data. We'll explore how to load
SheetJS in a site using RequireJS and how to use the `r.js` optimizer to create
a bundled site.
The [Live demo](pathname:///requirejs/requirejs.html) loads RequireJS from the
CDN, uses it to load the standalone script from the SheetJS CDN, and uses the
`XLSX` variable to create a button click handler that creates a workbook.
:::note
This demo was last tested on 2023 October 18 against RequireJS `2.3.6`
:::
## Integration Details
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
comply with AMD `define` semantics. They support RequireJS and the `r.js`
optimizer out of the box.
### Config
The RequireJS config should set the `xlsx` alias in the `paths` property.
#### SheetJS CDN
The SheetJS CDN URL can be directly referenced in a path alias:
<CodeBlock language="js">{`\
require.config({
baseUrl: ".",
name: "app",
paths: {
// highlight-next-line
xlsx: "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min"
}
});`}
</CodeBlock>
#### Vendoring
After downloading the SheetJS standalone script, a relative path can be used in
the path alias. For example, if the standalone script was downloaded in the same
directory as the HTML page, the path should be `./xlsx.full.min`:
```js
require.config({
baseUrl: ".",
name: "app",
paths: {
// highlight-next-line
xlsx: "./xlsx.full.min"
}
});
```
### Usage
Once the alias is set, `"xlsx"` can be required from app scripts:
```js
// highlight-next-line
require(["xlsx"], function(XLSX) {
/* use XLSX here */
console.log(XLSX.version);
});
```
Within the callback, the `XLSX` variable exposes the functions listed in the
["API Reference"](/docs/api/) section of the documentation.
## Complete Example
This demo will explore the standalone RequireJS script and the `r.js` optimizer.
### Standalone RequireJS
0) Download the SheetJS Standalone script and move to the project directory:
<ul>
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
</ul>
<CodeBlock language="bash">{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
</CodeBlock>
1) Save the following to `index.html`:
```html title="index.html"
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="http://requirejs.org/docs/release/2.3.6/comments/require.js"></script>
<script>
/* Wire up RequireJS */
require.config({
baseUrl: ".",
name: "SheetJSRequire",
paths: {
xlsx: "./xlsx.full.min"
}
});
</script>
<script src="SheetJSRequire.js"></script>
</body>
</html>
```
2) Save the following to `SheetJSRequire.js`:
```js title="SheetJSRequire.js"
require(["xlsx"], function(XLSX) {
document.getElementById("xport").addEventListener("click", function() {
/* fetch JSON data and parse */
var url = "https://sheetjs.com/data/executive.json";
fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
/* filter for the Presidents */
var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
/* flatten objects */
var rows = prez.map(function(row) { return {
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}; });
/* generate worksheet and workbook */
var worksheet = XLSX.utils.json_to_sheet(rows);
var workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFileXLSX(workbook, "Presidents.xlsx");
});
});
});
```
:::info pass
The `r.js` optimizer does not handle `async` functions or ES6 arrow functions.
To demonstrate compatibility with older versions of Webpack, `SheetJSRequire.js`
uses normal functions and traditional Promise chains.
:::
3) Start a local HTTP server, then go to `http://localhost:8080/`
```bash
npx http-server .
```
Click on "Click here to export" to generate a file.
### r.js Optimizer
4) Create `build.js` configuration for the optimizer:
```js title="build.js"
({
baseUrl: ".",
name: "SheetJSRequire",
paths: {
xlsx: "./xlsx.full.min"
},
out: "SheetJSRequire.min.js"
});
```
5) Run the `r.js` optimizer to create `SheetJSRequire.min.js`:
```bash
npx -p requirejs@2.3.6 r.js -o build.js
```
6) Save the following to `optimized.html`:
```html title="optimized.html"
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
<script src="SheetJSRequire.min.js"></script>
</body>
</html>
```
7) Open `http://localhost:8080/optimized.html`
Click on "Click here to export" to generate a file.

@ -0,0 +1,225 @@
---
title: Bundling Sheets with SystemJS
sidebar_label: SystemJS
pagination_prev: demos/index
pagination_next: demos/grid/index
sidebar_position: 12
---
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
SystemJS[^1] is a module loader for NodeJS and browsers.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses SystemJS and SheetJS to export data. We'll explore two workflows:
- ["Browser"](#browser) explores how to load SheetJS with SystemJS using the
in-browser dynamic loader
- ["NodeJS"](#nodejs) explores how to load SheetJS with SystemJS in NodeJS.
:::info pass
This demo was originally written for SystemJS 0.19, the most popular SystemJS
version used with Angular projects. In the years since the release, Angular and
other tools using SystemJS have switched to Webpack.
:::
:::note
This demo was tested against the following SystemJS versions:
| Version | Date |
|:----------|:-----------|
| `0.19.47` | 2023-10-18 |
| `0.20.19` | 2023-10-18 |
| `0.21.6` | 2023-10-18 |
| `6.14.2` | 2023-10-18 |
:::
## Browser
:::info pass
The [Live demo](pathname:///systemjs/systemjs.html) loads SystemJS from the
CDN, uses it to load the standalone script from the SheetJS CDN and emulate
a `require` implementation when loading [`main.js`](pathname:///systemjs/main.js)
"View Source" works on the main HTML page and the `main.js` script.
:::
SystemJS fails by default because the library does not export anything in the
web browser. The `meta` configuration option can be used to expose `XLSX`:
<CodeBlock language="js">{`\
SystemJS.config({
meta: {
'xlsx': {
exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
}
},
map: {
'xlsx': 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js',
'fs': '', // <--|
'crypto': '', // <--| suppress native node modules
'stream': '' // <--|
}
});
SystemJS.import('main.js'); // load \`main.js\``}
</CodeBlock>
With this import, the `main.js` script can freely `require("xlsx")`.
:::caution Web Workers
Web Workers can load the SystemJS library with `importScripts`, but the imported
code cannot assign the original worker's `onmessage` callback. The recommended
approach is to expose a global from the required script, For example, supposing
the shared name is `_cb`, the primary worker script would call the callback:
```js title="worker.js"
/* main worker script */
importScripts('system.js');
SystemJS.config({ /* ... browser config ... */ });
onmessage = function(evt) {
SystemJS.import('workermain.js').then(function() { _cb(evt); });
};
```
The worker script would define and expose the function:
```js title="workermain.js"
/* Loaded with SystemJS import */
var XLSX = require('xlsx');
_cb = function(evt) { /* ... do work here ... */ };
```
:::
## NodeJS
:::caution pass
While SystemJS works in NodeJS, the built-in `require` should be preferred.
:::
### Old Style
The NodeJS module main script is `xlsx/xlsx.js` and should be mapped:
```js
SystemJS.config({
map: {
"xlsx": "./node_modules/xlsx/xlsx.js"
}
});
```
The standalone scripts can be required, but SystemJS config must include a hint
that the script assigns a global:
```js
SystemJS.config({
meta: {
"standalone": { format: "global" }
},
map: {
"standalone": "xlsx.full.min.js"
}
});
```
### New Style
Newer versions of SystemJS supports "import maps" through `applyImportMap`:
```js
const SystemJS = require('systemjs');
const src = require("path").join(process.cwd(), 'node_modules/xlsx/xlsx.js');
SystemJS.applyImportMap(SystemJS.System, {
imports: {
'xlsx': "file://" + src,
'fs': 'node:fs',
'crypto': 'node:crypto',
'stream': 'node:stream'
}
});
````
:::caution pass
In the modern style, importing to the name `XLSX` will cause conflicts.
**It is strongly recommended to import to the name `_XLSX`!**
```js
SystemJS.System.import("xlsx").then(function(
// highlight-next-line
_XLSX // use _XLSX instead of XLSX
) {
if(typeof XLSX == "undefined") throw "Import failed!";
// XLSX is defined here
console.log(XLSX.version);
});
```
:::
### NodeJS Demo
0) Prepare a blank project:
```bash
mkdir sheetjs-systemjs
cd sheetjs-systemjs
npm init -y
```
1) Install the dependencies:
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz systemjs@6.14.2`}
</CodeBlock>
2) Download [`SheetJSystem.js`](pathname:///systemjs/SheetJSystem.js) and move
to the project folder:
```bash
curl -LO https://docs.sheetjs.com/systemjs/SheetJSystem.js
```
:::info pass
The script is handles both old-style and new-style SystemJS loaders.
:::
3) Run in NodeJS:
```bash
node SheetJSystem.js
```
If the demo worked, `Presidents.xlsx` will be created.
:::note pass
As it uses `fetch`, this demo requires Node 18.
:::
[^1]: The project does not have a separate website. The source repository is hosted on [GitHub](https://github.com/systemjs/systemjs)

@ -11,6 +11,7 @@ import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
SheetJS predates ECMAScript modules and most bundler tools. As best practices
have evolved, stress testing SheetJS libraries have revealed bugs in bundlers
@ -23,6 +24,16 @@ considered a bundler bug if the tool cannot properly handle JS libraries.
:::
The following tools are covered in separate pages:
<ul>{useCurrentSidebarCategory().items.filter(item => !item?.customProps?.skip).map((item, index) => {
const listyle = (item.customProps?.icon) ? {
listStyleImage: `url("${item.customProps.icon}")`
} : {};
return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}>
<a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
</li>);
})}</ul>
## Browserify
@ -481,167 +492,7 @@ click the "Click to Export!" button to generate a file.
## RequireJS
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
comply with AMD `define` semantics. They support RequireJS out of the box.
The RequireJS config should set the `xlsx` alias in the `paths` property:
```js
require.config({
baseUrl: ".",
name: "app",
paths: {
// highlight-next-line
xlsx: "xlsx.full.min"
}
});
// highlight-next-line
require(["xlsx"], function(XLSX) {
/* use XLSX here */
console.log(XLSX.version);
});
```
The [Live demo](pathname:///requirejs/requirejs.html) loads RequireJS from the
CDN, uses it to load the standalone script from the SheetJS CDN, and uses the
`XLSX` variable to create a button click handler that creates a workbook.
The `r.js` optimizer also supports the standalone scripts.
<details><summary><b>Complete Example</b> (click to show)</summary>
:::note
This demo was last tested on 2023 May 07 against RequireJS `2.3.3`
:::
:::caution pass
The `r.js` optimizer does not support ES6 syntax including arrow functions and
the `async` keyword! The demo JS code uses traditional functions.
:::
0) Download the SheetJS Standalone script and move to the project directory:
<ul>
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
</ul>
<CodeBlock language="bash">{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
</CodeBlock>
1) Save the following to `index.html`:
```html title="index.html"
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
<script>
/* Wire up RequireJS */
require.config({
baseUrl: ".",
name: "SheetJSRequire",
paths: {
xlsx: "./xlsx.full.min"
}
});
</script>
<script src="SheetJSRequire.js"></script>
</body>
</html>
```
2) Save the following to `SheetJSRequire.js`:
```js title="SheetJSRequire.js"
require(["xlsx"], function(XLSX) {
document.getElementById("xport").addEventListener("click", function() {
/* fetch JSON data and parse */
var url = "https://sheetjs.com/data/executive.json";
fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
/* filter for the Presidents */
var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
/* flatten objects */
var rows = prez.map(function(row) { return {
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}; });
/* generate worksheet and workbook */
var worksheet = XLSX.utils.json_to_sheet(rows);
var workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFileXLSX(workbook, "Presidents.xlsx");
});
});
});
```
3) Start a local HTTP server, then go to `http://localhost:8080/`
```bash
npx http-server .
```
Click on "Click here to export" to generate a file.
4) Create `build.js` configuration for the optimizer:
```js title="build.js"
({
baseUrl: ".",
name: "SheetJSRequire",
paths: {
xlsx: "./xlsx.full.min"
},
out: "SheetJSRequire.min.js"
});
```
5) Run the `r.js` optimizer to create `SheetJSRequire.min.js`:
```bash
npx -p requirejs@2.3.3 r.js -o build.js
```
6) Save the following to `optimized.html`:
```html title="optimized.html"
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
<script src="SheetJSRequire.min.js"></script>
</body>
</html>
```
7) Open `http://localhost:8080/optimized.html`
Click on "Click here to export" to generate a file.
</details>
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/requirejs)**
## Rollup
@ -978,206 +829,9 @@ Click on "Click here to export" to generate a file.
</details>
## SystemJS
#### SystemJS
With configuration, SystemJS supports both browser and NodeJS deployments.
:::caution pass
This demo was written against SystemJS 0.19, the most popular SystemJS version
used with Angular applications. In the years since the release, Angular and
other tools using SystemJS have switched to Webpack.
:::
<Tabs>
<TabItem value="browser" label="Browser">
SystemJS fails by default because the library does not export anything in the
web browser. The `meta` configuration option can be used to expose `XLSX`:
<CodeBlock language="js">{`\
SystemJS.config({
meta: {
'xlsx': {
exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
}
},
map: {
'xlsx': 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js',
'fs': '', // <--|
'crypto': '', // <--| suppress native node modules
'stream': '' // <--|
}
});
SystemJS.import('main.js'); // load \`main.js\``}
</CodeBlock>
The `main.js` script can freely `require("xlsx")`.
:::caution Web Workers
Web Workers can load the SystemJS library with `importScripts`, but the imported
code cannot assign the original worker's `onmessage` callback. The recommended
approach is to expose a global from the required script, For example, supposing
the shared name is `_cb`, the primary worker script would call the callback:
```js title="worker.js"
/* main worker script */
importScripts('system.js');
SystemJS.config({ /* ... browser config ... */ });
onmessage = function(evt) {
SystemJS.import('workermain.js').then(function() { _cb(evt); });
};
```
The worker script would define and expose the function:
```js title="workermain.js"
/* Loaded with SystemJS import */
var XLSX = require('xlsx');
_cb = function(evt) { /* ... do work here ... */ };
```
:::
</TabItem>
<TabItem value="nodejs" label="NodeJS">
:::caution pass
While SystemJS works in NodeJS, the built-in `require` should be preferred.
:::
The NodeJS module main script is `xlsx/xlsx.js` and should be mapped:
```js
SystemJS.config({
map: {
"xlsx": "./node_modules/xlsx/xlsx.js"
}
});
```
The standalone scripts require a hint that the script assigns a global:
```js
SystemJS.config({
meta: {
"standalone": { format: "global" }
},
map: {
"standalone": "xlsx.full.min.js"
}
});
```
</TabItem>
</Tabs>
<details><summary><b>Complete Example</b> (click to show)</summary>
<Tabs>
<TabItem value="browser" label="Browser">
:::note
This demo was last tested on 2023 May 07 against SystemJS 0.20.16
:::
The [Live demo](pathname:///systemjs/systemjs.html) loads SystemJS from the
CDN, uses it to load the standalone script from the SheetJS CDN and emulate
a `require` implementation when loading [`main.js`](pathname:///systemjs/main.js)
"View Source" works on the main HTML page and the `main.js` script.
</TabItem>
<TabItem value="nodejs" label="NodeJS">
:::note
This demo was last tested on 2023 May 07 against SystemJS 0.19.47
:::
1) Install the dependencies:
<CodeBlock language="bash">{`\
npm init -y
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz systemjs@0.19.47`}
</CodeBlock>
2) Save the following script to `SheetJSystem.js`:
```js title="SheetJSystem.js"
const SystemJS = require('systemjs');
// highlight-start
SystemJS.config({
map: {
'xlsx': 'node_modules/xlsx/xlsx.js',
'fs': '@node/fs',
'crypto': '@node/crypto',
'stream': '@node/stream'
}
});
// highlight-end
SystemJS.import('xlsx').then(async function(XLSX) {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/data/executive.json";
const raw_data = await (await fetch(url)).json();
/* filter for the Presidents */
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.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 */
XLSX.writeFile(workbook, "Presidents.xlsx");
});
```
3) Run in NodeJS:
```bash
node SheetJSystem.js
```
If the demo worked, `Presidents.xlsx` will be created.
:::note pass
As it uses `fetch`, this demo requires Node 18.
:::
</TabItem>
</Tabs>
</details>
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/systemjs)**
## Vite

@ -258,7 +258,7 @@ This demo was tested in the following environments:
| OS and Version | Arch | Tauri | Date |
|:---------------|:-----|:---------|:-----------|
| macOS 13.5.1 | x64 | `v1.5.0` | 2023-09-30 |
| macOS 13.4.1 | ARM | `v1.4.0` | 2023-06-29 |
| macOS 14.0 | ARM | `v1.5.2` | 2023-10-18 |
| Windows 10 | x64 | `v1.5.0` | 2023-10-01 |
| Windows 11 | ARM | `v1.4.1` | 2023-09-26 |
| Linux (HoloOS) | x64 | `v1.5.2` | 2023-10-11 |

@ -1,5 +1,5 @@
---
title: NeutralinoJS
title: Data Munging in NeutralinoJS
sidebar_label: NeutralinoJS
description: Build data-intensive desktop apps using NeutralinoJS. Seamlessly integrate spreadsheets into your app using SheetJS. Quickly modernize Excel-powered business processes.
pagination_prev: demos/mobile/index
@ -9,8 +9,6 @@ sidebar_custom_props:
summary: Webview + Lightweight Extensions
---
# Data Munging in NeutralinoJS
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
@ -195,7 +193,7 @@ This demo was tested in the following environments:
| OS and Version | Arch | Server | Client | Date |
|:---------------|:-----|:----------|:----------|:-----------|
| macOS 13.5.1 | x64 | `v4.13.0` | `v3.11.0` | 2023-08-26 |
| macOS 13.4.1 | ARM | `v4.10.0` | `v3.8.2` | 2023-06-28 |
| macOS 14.0 | ARM | `v4.14.1` | `v3.12.0` | 2023-10-18 |
| Windows 10 | x64 | `v4.13.0` | `v3.11.0` | 2023-08-26 |
| Windows 11 | ARM | `v4.13.0` | `v3.11.0` | 2023-09-21 |
| Linux (HoloOS) | x64 | `v4.14.1` | `v3.12.0` | 2023-10-11 |
@ -385,7 +383,8 @@ save as `SheetJSNeu` will not automatically add the `.xlsx` extension!
npx @neutralinojs/neu build
```
Platform-specific programs will be created in the `dist` folder.
Platform-specific programs will be created in the `dist` folder. For example,
the `darwin-arm` program will be `./dist/sheetjs-neu/sheetjs-neu-mac_arm64`
[^1]: See [`nativeAllowList`](https://neutralino.js.org/docs/configuration/neutralino.config.json#nativeallowlist-string) in the NeutralinoJS documentation
[^2]: See [`os.showOpenDialog`](https://neutralino.js.org/docs/api/os#osshowopendialogtitle-options) in the NeutralinoJS documentation

@ -240,7 +240,7 @@ This demo was last tested in the following deployments:
| Architecture | V8 Version | Crate | Date |
|:-------------|:--------------|:---------|:-----------|
| `darwin-x64` | `11.8.172.13` | `0.79.2` | 2023-10-12 |
| `darwin-arm` | `11.4.183.2` | `0.71.2` | 2023-05-22 |
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
| `win10-x64` | `11.8.172.13` | `0.79.2` | 2023-10-09 |
| `win11-x64` | `11.8.172.13` | `0.79.2` | 2023-10-14 |
| `linux-x64` | `11.8.172.13` | `0.79.2` | 2023-10-11 |
@ -351,7 +351,7 @@ This demo was last tested in the following deployments:
| Architecture | Version | Date |
|:-------------|:---------|:-----------|
| `darwin-x64` | `1.37.1` | 2023-10-12 |
| `darwin-arm` | `1.34.1` | 2023-06-05 |
| `darwin-arm` | `1.37.2` | 2023-10-18 |
| `win10-x64` | `1.37.1` | 2023-10-09 |
| `win11-x64` | `1.37.2` | 2023-10-14 |
| `win11-arm` | `1.37.0` | 2023-09-26 |

@ -39,7 +39,11 @@ production sites.
:::note
This demo was last tested on 2023 June 1 with `localForage` 1.10.0
This demo was last tested in the following environments:
| Browser | Date | `localForage` |
|:------------|:-----------|:--------------|
| Chrome 117 | 2023-10-18 | 1.10.0 |
:::
@ -106,7 +110,11 @@ function SheetJSLocalForage() {
:::note
This demo was last tested on 2023 June 1 with DexieJS 3.2.4
This demo was last tested in the following environments:
| Browser | Date | DexieJS |
|:------------|:-----------|:--------|
| Chrome 117 | 2023-10-18 | 3.2.4 |
:::

@ -7,10 +7,36 @@ pagination_next: demos/extensions/index
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
Deno Deploy offers "Serverless Functions" powered by Deno.
[Deno Deploy](https://dash.deno.com/) offers distributed "Serverless Functions"
powered by Deno.
The [Deno installation](/docs/getting-started/installation/deno) instructions
apply to Deno Deploy scripts.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo covers integration details. We'll explore how to load and use SheetJS
scripts in Deno Deploy functions.
The ["Demo"](#demo) section includes build a sample service that converts XLSX
and other types of spreadsheets to HTML tables and CSV rows.
:::caution pass
When the demo was last tested, Deno Deploy required a GitHub account.
:::
:::note
This demo was last tested by SheetJS users on 2023 October 18.
:::
## Integration Details
The [SheetJS Deno module](/docs/getting-started/installation/nodejs) can be
imported from Deno Deploy server scripts.
### Supported Frameworks
:::warning pass
@ -20,17 +46,11 @@ This breaks web frameworks that use the filesystem in body parsing.
:::
:::caution pass
When the demo was last tested, Deno Deploy required a GitHub account.
:::
## Supported Frameworks
When the demo was last tested, the `drash` server framework used an in-memory
approach for parsing POST request bodies.
The [Drash demo](/docs/demos/net/server/drash) covers the framework in detail.
### Parsing Data
When files are submitted via HTTP POST, the `bodyParam` method can fetch data.
@ -41,7 +61,7 @@ The following example assumes the file is submitted at field name `file`:
<CodeBlock language="ts">{`\
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
import { read, utils } from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
\n\
class SheetJSResource extends Drash.Resource {
public paths = ["/"];
@ -61,39 +81,43 @@ class SheetJSResource extends Drash.Resource {
## Demo
:::note
0) Create a new GitHub account or sign into an existing account.
This demo was last tested on 2023 June 05. The service <https://s2c.sheetjs.com>
was implemented using this exact sequence.
1) Open the [main Deno Deploy portal](https://dash.deno.com/) in a browser.
:::
2) If the account never signed into Deno Deploy, click "Continue with Github".
1) Register and Sign in.
In the next screen, review the prompt and click "Authorize Deno Deploy"
2) Click "New Project" to create a new Project. In the next screen, look for the
"Hello World" sample and click the corresponding "Fork" button.
3) Click "New Playground" to create a new Playground.
3) Download [`s2c.ts`](pathname:///deno/s2c.ts). Open with a text editor and
copy the contents into the playground editor (left pane).
4) Download [`s2c.ts`](pathname:///deno/s2c.ts).
4) Click "Save and Deploy".
5) Open `s2c.ts` with a text editor and copy the contents of the source file
into the playground editor (left pane in the browser).
6) Click "Save and Deploy". When the demo was last tested, it was a blue button.
### Testing
5) Download the test file <https://sheetjs.com/pres.xlsx>
7) Wait until the server is deployed. When it is deployed, the right panel will
show "SheetJS Spreadsheet Conversion Service":
6) In the browser window, click "Choose File" and select the downloaded file.
Click "Submit" and the page will show the contents in a HTML TABLE.
> ![Screenshot](pathname:///deno/sshot.png)
7) Click the "Fullscreen" icon in the top-right corner of the page window.
8) Download the test file <https://sheetjs.com/pres.xlsx>
8) Open a terminal window and download <https://sheetjs.com/pres.numbers>:
9) In the browser window, click "Choose File" and select the downloaded file.
10) Click "Submit". The right panel will show the contents in a HTML TABLE.
11) Open a terminal window and download <https://sheetjs.com/pres.numbers>:
```bash
curl -LO https://sheetjs.com/pres.numbers
```
9) Copy the first `curl` line from the page and run in the terminal. For
12) Copy the first `curl` line from the page and run in the terminal. For
example, if the deployment is `clean-badger-69`, the command would be
```bash
@ -102,7 +126,7 @@ curl -X POST -F"file=@pres.numbers" https://clean-badger-69.deno.dev/
The output will be an HTML table
10) Copy the second `curl` line from the page and run in the terminal. For
13) Copy the second `curl` line from the page and run in the terminal. For
example, if the deployment is `clean-badger-69`, the command would be
```bash

@ -120,7 +120,7 @@ This demo was tested in the following deployments:
| Architecture | Version | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | `2.7.0` | 2023-07-24 |
| `darwin-arm` | `2.7.0` | 2023-06-05 |
| `darwin-arm` | `2.7.0` | 2023-10-18 |
| `win10-x64` | `2.7.0` | 2023-07-24 |
| `win11-arm` | `2.7.0` | 2023-09-26 |
| `linux-x64` | `2.7.0` | 2023-10-11 |
@ -173,6 +173,20 @@ curl -LO https://docs.sheetjs.com/duk/sheetjs.duk.c
gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
```
:::note
GCC may generate a warning:
```
duk_js_compiler.c:5628:13: warning: variable 'num_stmts' set but not used [-Wunused-but-set-variable]
duk_int_t num_stmts;
^
```
This warning can be ignored.
:::
</TabItem>
<TabItem value="win" label="Windows">

@ -808,7 +808,7 @@ This demo was last tested in the following deployments:
| Architecture | V8 Crate | Date |
|:-------------|:---------|:-----------|
| `darwin-x64` | `0.75.1` | 2023-08-26 |
| `darwin-arm` | `0.73.0` | 2023-06-05 |
| `darwin-arm` | `0.79.2` | 2023-10-18 |
| `win10-x64` | `0.79.2` | 2023-10-09 |
| `linux-x64` | `0.79.2` | 2023-10-11 |
| `linux-arm` | `0.75.1` | 2023-08-30 |

@ -134,7 +134,7 @@ This demo was tested in the following environments:
| Architecture | Swift | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | `5.8.1` | 2023-07-24 |
| `darwin-arm` | `5.8.1` | 2023-06-05 |
| `darwin-arm` | `5.9.0` | 2023-10-18 |
:::

@ -95,7 +95,7 @@ This demo was tested in the following deployments:
| Architecture | Git Commit | Go version | Date |
|:-------------|:-----------|:-----------|:-----------|
| `darwin-x64` | `873a149` | `1.21.3` | 2023-10-14 |
| `darwin-arm` | `28ee0ee` | `1.20.4` | 2023-06-05 |
| `darwin-arm` | `873a149` | `1.21.3` | 2023-10-18 |
| `win10-x64` | `81d7606` | `1.20.2` | 2023-08-27 |
| `win11-arm` | `fc55792` | `1.21.1` | 2023-09-25 |
| `linux-x64` | `fc55792` | `1.21.3` | 2023-10-11 |

@ -263,7 +263,7 @@ This demo was tested in the following deployments:
| Architecture | Git Commit | Date |
|:-------------|:-----------|:-----------|
| `darwin-x64` | `2788d71` | 2023-07-24 |
| `darwin-arm` | `2788d71` | 2023-06-05 |
| `darwin-arm` | `2788d71` | 2023-10-18 |
| `win10-x64` | `2788d71` | 2023-10-09 |
| `win11-arm` | `2788d71` | 2023-09-25 |
| `linux-x64` | `2788d71` | 2023-10-11 |

@ -363,7 +363,7 @@ This demo was tested in the following deployments:
| Architecture | Git Commit | Date |
|:-------------|:-----------|:-----------|
| `darwin-x64` | `70af78b` | 2023-08-27 |
| `darwin-arm` | `869312f` | 2023-06-05 |
| `darwin-arm` | `2b4f949` | 2023-10-18 |
| `linux-x64` | `2b4f949` | 2023-10-11 |
| `linux-arm` | `70af78b` | 2023-08-27 |

@ -120,11 +120,11 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
- [`bun`](/docs/demos/frontend/bundler#bun)
- [`esbuild`](/docs/demos/frontend/bundler#esbuild)
- [`parcel`](/docs/demos/frontend/bundler#parcel)
- [`requirejs`](/docs/demos/frontend/bundler#requirejs)
- [`requirejs`](/docs/demos/frontend/bundler/requirejs)
- [`rollup`](/docs/demos/frontend/bundler#rollup)
- [`snowpack`](/docs/demos/frontend/bundler#snowpack)
- [`swc`](/docs/demos/frontend/bundler#swc)
- [`systemjs`](/docs/demos/frontend/bundler#systemjs)
- [`systemjs`](/docs/demos/frontend/bundler/systemjs)
- [`vite`](/docs/demos/frontend/bundler#vite)
- [`webpack`](/docs/demos/frontend/bundler/webpack)
- [`wmr`](/docs/demos/frontend/bundler#wmr)
@ -132,6 +132,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
### Other Programming Languages
- [`JavaScript Engines`](/docs/demos/engines)
- [`V8 (C++ / Rust)`](/docs/demos/engines/v8)
- [`Duktape (C / Perl)`](/docs/demos/engines/duktape)
- [`JavaScriptCore (Swift)`](/docs/demos/engines/jsc)
- [`Rhino (Java)`](/docs/demos/engines/rhino)

@ -344,7 +344,7 @@ import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs'
import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs';
XLSX.set_cptable(cptable);
\n\
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
\n\
class SheetResource extends Drash.Resource {
public paths = ["/"];

@ -3,7 +3,7 @@ import { read, utils, set_cptable, version } from 'https://cdn.sheetjs.com/xlsx-
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.20.0/package/dist/cpexcel.full.mjs';
set_cptable(cptable);
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
class SheetJSResource extends Drash.Resource {
public paths = ["/"];

BIN
docz/static/deno/sshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

@ -4,7 +4,7 @@
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
<script src="http://requirejs.org/docs/release/2.3.6/comments/require.js"></script>
<script>
/* Wire up RequireJS */
require.config({
@ -14,7 +14,7 @@ require.config({
xlsx: "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min"
}
});
require(["xlsx"], function(XLSX) {
require(["xlsx"], function(_XLSX) {
document.getElementById("xport").addEventListener("click", async() => {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/data/executive.json";

@ -0,0 +1,55 @@
const SystemJS = require('systemjs');
/* old SystemJS behavior */
if(typeof SystemJS.config != "undefined") SystemJS.config({ map: {
'xlsx': 'node_modules/xlsx/xlsx.js',
'fs': '@node/fs',
'crypto': '@node/crypto',
'stream': '@empty'
} });
/* new SystemJS behavior */
else SystemJS.applyImportMap(SystemJS.System, {
imports: {
'xlsx': "file://" + require("path").join(process.cwd(), 'node_modules/xlsx/xlsx.js'),
'fs': 'node:fs',
'crypto': 'node:crypto',
'stream': 'node:stream'
}
});
(typeof SystemJS.System != "undefined" ? SystemJS.System : SystemJS).import('xlsx').then(async function(_XLSX) {
if(typeof XLSX == "undefined") XLSX = _XLSX;
/* fetch JSON data and parse */
const url = "https://sheetjs.com/data/executive.json";
const raw_data = 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 = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.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 */
if(typeof XLSX.set_fs != "undefined") XLSX.set_fs(require("fs"));
XLSX.writeFile(workbook, "Presidents.xlsx");
});