This commit is contained in:
SheetJS 2023-11-28 02:05:59 -05:00
parent aca683dafc
commit f14874c930
12 changed files with 366 additions and 125 deletions

@ -104,7 +104,7 @@ require(['xlsx'], function(XLSX) {
Dojo has changed module loading strategies over the years. These examples were
tested with Dojo `1.17.3`. They are not guaranteed to work with other versions.
Live demos are included in ["Dojo Toolkit"](/docs/demos/frontend/legacy#dojo-toolkit)
Live demos are included in ["Dojo Toolkit"](/docs/demos/frontend/dojo)
:::caution pass

@ -0,0 +1,205 @@
---
title: Sheets in Dojo Sites
sidebar_label: Dojo Toolkit
description: Build interactive websites with Dojo. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
pagination_prev: demos/index
pagination_next: demos/grid/index
sidebar_position: 8
---
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
[Dojo Toolkit](https://dojotoolkit.org/) is a JavaScript toolkit for building
user interfaces. It includes solutions for code loading and DOM manipulation.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses Dojo Toolkit and SheetJS to process and generate spreadsheets.
We'll explore how to load SheetJS using Dojo loader and perform common tasks.
## Installation
The ["AMD" instructions](/docs/getting-started/installation/amd#dojo-toolkit)
includes details for using SheetJS with `require`.
The demos in this section use the async loading strategy with the SheetJS CDN:
<CodeBlock language="html">{`\
<script>
/* configure package paths */
dojoConfig = {
packages: [
{
/* Dojo only supports the name "xlsx" for the script */
name: "xlsx",
/* \`location\` omits trailing slash */
location: "https://cdn.sheetjs.com/xlsx-${current}/package/dist",
/* \`main\` omits the ".js" extension */
main: "xlsx.full.min"
}
]
}
</script>
<!-- load dojo.js -->
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(
/* specify "xlsx" in the module array */
["dojo/request/xhr", "xlsx"],
/* the name of the variable should not be _XLSX ! */
function(xhr, _XLSX) {
/* XLSX-related operations happen in the callback. Use the global \`XLSX\` */
console.log(XLSX.version);
}
);
</script>`}
</CodeBlock>
:::warning pass
The official Google CDN does not have the newest releases of Dojo Toolkit
**This is a known Google CDN bug.**
The script <https://docs.sheetjs.com/dojo/dojo.js> was fetched from the official
`1.17.3` uncompressed release artifact[^1].
:::
## Live Demos
:::note Tested Deployments
The demos were last tested on 2023-11-27.
Demos exclusively using Dojo Core were tested using Dojo Toolkit `1.17.3`.
Demos using `dijit` or `dojox` were tested using Dojo Toolkit `1.14.1`. This
was the latest version available on the Google CDN.
:::
- [Download and display data](pathname:///dojo/read.html)
- [Fetch JSON and generate a workbook](pathname:///dojo/write.html)
- [Parse file and create a data store](pathname:///dojo/combo.html)
- [Export data from a store to XLSX](pathname:///dojo/export.html)
## Operations
### Parsing Remote Files
When fetching spreadsheets with XHR, `handleAs: "arraybuffer"` yields an
`ArrayBuffer` which can be passed to the SheetJS `read` method.
The following example generates a HTML table from the first worksheet:
```html
<div id="tbl"></div>
<script>
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
xhr("https://sheetjs.com/pres.numbers", {
headers: { "X-Requested-With": null },
// highlight-next-line
handleAs: "arraybuffer"
}).then(function(ab) {
/* read ArrayBuffer */
// highlight-next-line
var wb = XLSX.read(ab);
/* display first worksheet data */
var ws = wb.Sheets[wb.SheetNames[0]];
document.getElementById("tbl").innerHTML = XLSX.utils.sheet_to_html(ws);
});
});
</script>
```
:::note pass
The `X-Requested-With` header setting resolves some issues related to CORS.
:::
### Writing Local Files
The SheetJS `writeFile` method attempts to create and download a file:
```js
require(["xlsx"], function(_XLSX) {
/* create a sample workbook */
var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]);
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
/* create an XLSX file and try to save to SheetJSDojo.xlsx */
// highlight-next-line
XLSX.writeFile(workbook, "SheetJSDojo.xlsx");
});
```
### Data Stores
`dojo/store`[^2] is the primary interface for working with structured data.
#### Importing Data
The SheetJS `sheet_to_json` method can generate an array of arrays that can back
a `dojo/store/Memory` store.
The following example fetches a test file, creates a Memory store from the data
in the first worksheet, and assigns to a `dijit` UI Widget:
```html
<script>
require([
"dojo/ready", "dojo/request/xhr", "dojo/store/Memory" "dijit/registry", "xlsx"
], function(ready, xhr, Memory, registry, _XLSX) {
ready(function() {
/* fetch test file */
xhr("https://sheetjs.com/pres.xlsx", {
headers: { "X-Requested-With": null },
handleAs: "arraybuffer"
}).then(function(ab) {
/* parse ArrayBuffer */
var wb = XLSX.read(ab);
/* get first worksheet */
var ws = wb.Sheets[wb.SheetNames[0]];
// highlight-start
/* generate row objects from first worksheet */
const aoo = XLSX.utils.sheet_to_json(ws);
/* generate memory store and assign to combo box */
var store = new Memory({ data: aoo });
// highlight-end
registry.byId("widget").store = store;
});
});
});
</script>
```
#### Exporting Data
Starting from a data store, query results are arrays of objects. Worksheets can
be created using the SheetJS `json_to_sheet` method:
```js
function export_all_data_from_store(store) {
require(["xlsx"], function(_XLSX) {
// highlight-start
/* pull all data rows from the store */
var rows = store.query(function() { return true; });
/* generate SheetJS worksheet */
var ws = XLSX.utils.json_to_sheet(rows);
// highlight-end
/* generate SheetJS workbook and write to XLSX */
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Export");
XLSX.writeFile(wb, "SheetJSDojoExport.xlsx");
});
}
```
[^1]: All Dojo Toolkit releases are available at <https://download.dojotoolkit.org/>. The mirrored `dojo.js` corresponds to the `1.17.3` uncompressed script <http://download.dojotoolkit.org/release-1.17.3/dojo.js.uncompressed.js>.
[^2]: See [`dojo/store`](https://dojotoolkit.org/reference-guide/dojo/store.html) in the Dojo Toolkit documentation.

@ -192,109 +192,9 @@ included in the page and the relevant features are enabled on the target system.
## Frameworks
### Dojo Toolkit
_Live Demos_
- [Download and display data](pathname:///dojo/read.html)
- [Fetch JSON and generate a workbook](pathname:///dojo/write.html)
:::note pass
These demos have been tested with Dojo Toolkit `1.10.4` and `1.17.3`.
:::
:::warning pass
The official Google CDN is out of date. This is a known CDN bug.
The script <https://docs.sheetjs.com/dojo/dojo.js> was fetched from the official
`1.17.3` uncompressed release artifact[^2] on 2023-08-16.
:::
_Installation_
The ["AMD" instructions](/docs/getting-started/installation/amd#dojo-toolkit)
includes details for use with `require`.
<details><summary><b>Integration in the demos</b> (click to show)</summary>
The demos use the async loading strategy with the SheetJS CDN:
<CodeBlock language="html">{`\
<script>
dojoConfig = {
packages: [
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-${current}/package/dist", main: "xlsx.full.min" }
]
}
</script>
<script src="dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
/* XLSX-related operations happen in the callback */
});
</script>`}
</CodeBlock>
</details>
The ["Dojo" section in "Bundlers"](/docs/demos/bundler#dojo) includes a complete example
mirroring the [official export example](/docs/getting-started/examples/export)
<details><summary><b>Details</b> (click to show)</summary>
_Reading Data_
When fetching spreadsheets with XHR, `handleAs: "arraybuffer"` yields an
`ArrayBuffer` which can be passed to `XLSX.read`:
```html
<div id="tbl"></div>
<script>
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
xhr("https://sheetjs.com/pres.numbers", {
headers: { "X-Requested-With": null },
// highlight-next-line
handleAs: "arraybuffer"
}).then(function(ab) {
/* read ArrayBuffer */
// highlight-next-line
var wb = XLSX.read(ab);
/* display first worksheet data */
var ws = wb.Sheets[wb.SheetNames[0]];
document.getElementById("tbl").innerHTML = XLSX.utils.sheet_to_html(ws);
});
});
</script>
```
:::note pass
The `X-Requested-With` header setting resolves some issues related to CORS.
:::
_Writing Data_
`XLSX.writeFile` works as expected:
```html
<script>
require(["xlsx"], function(_XLSX) {
var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]);
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
/* create an XLSX file and try to save to SheetJSDojo.xlsx */
// highlight-next-line
XLSX.writeFile(workbook, "SheetJSDojo.xlsx");
});
</script>
```
</details>
#### Dojo Toolkit
**[The exposition has been moved to a separate page.](/docs/demos/frontend/dojo)**
### KnockoutJS
@ -371,5 +271,4 @@ binding is possible using the `$parent` and `$index` binding context properties:
</details>
[^1]: Project hosted at <https://github.com/dcneiner/Downloadify>
[^2]: All Dojo Toolkit releases are available at <https://download.dojotoolkit.org/>. The mirrored `dojo.js` corresponds to the `1.17.3` uncompressed script <http://download.dojotoolkit.org/release-1.17.3/dojo.js.uncompressed.js>.
[^1]: Project hosted at <https://github.com/dcneiner/Downloadify>

@ -39,7 +39,7 @@ The following tools are covered in separate pages:
Integration details are included [in the "AMD" installation](/docs/getting-started/installation/amd#dojo-toolkit)
Complete Examples are included [in the "Dojo" demo](/docs/demos/frontend/legacy#dojo-toolkit)
Complete Examples are included [in the "Dojo" demo](/docs/demos/frontend/dojo)
## Snowpack

@ -27,7 +27,7 @@ Demos for popular frameworks are included in separate pages:
</li>);
})}</ul>
Legacy frameworks including Dojo are covered [in the "Legacy" section](/docs/demos/frontend/legacy).
Legacy frameworks including KnockoutJS are covered [in the "Legacy" section](/docs/demos/frontend/legacy).
:::note Recommendation

@ -23,14 +23,14 @@ This demo covers basic concepts pertaining to data import and export. The
official documentation includes advanced examples and deployment tips as well as
strategies for general data processing in AlaSQL expressions.
:::note
:::note Tested Deployments
This demo was tested in the following environments:
| Environment | AlaSQL | Date |
|:--------------------|:-------|:----------:|
| NodeJS | 3.1.0 | 2023-10-26 |
| Standalone (Chrome) | 3.0.0 | 2023-08-20 |
| Standalone (Chrome) | 3.0.0 | 2023-11-27 |
:::

@ -19,9 +19,9 @@ This demo uses SheetJS to pull data from a spreadsheet for further analysis
within MATLAB. We'll explore how to run an external tool to convert complex
spreadsheets into simple XLSX files for MATLAB.
:::note
:::note Tested Deployments
This demo was last tested by SheetJS users on 2023 September 12 in MATLAB R2023a.
This demo was last tested by SheetJS users on 2023 November 27 in MATLAB R2023a.
:::

@ -118,7 +118,7 @@ The resulting `buf` can be written to file with `fwrite`.
## Complete Example
:::note
:::note Tested Deployments
This demo was tested in the following deployments:
@ -127,7 +127,7 @@ This demo was tested in the following deployments:
| `12.1.131` | `darwin-x64` | macOS 14.1 | `clang 15.0.0` | 2023-11-15 |
| `12.0.175` | `darwin-arm` | macOS 14.0 | `clang 15.0.0` | 2023-10-20 |
| `12.0.265` | `win10-x64` | Windows 10 | `CL 19.37.32822` | 2023-10-28 |
| `12.0.72` | `linux-x64` | HoloOS 3.4.11 | `gcc 12.2.0` | 2023-10-11 |
| `12.1.222` | `linux-x64` | HoloOS 3.5.7 | `gcc 13.1.1` | 2023-11-27 |
| `11.8.82` | `linux-arm` | Debian 11 | `gcc 10.2.1` | 2023-09-26 |
:::
@ -459,9 +459,10 @@ tools/dev/v8gen.py x64.release.sample
ninja -C out.gn/x64.release.sample v8_monolith
```
:::caution pass
:::note pass
In the most recent Linux x64 test, there were build errors:
In some Linux x64 tests using GCC 12, there were build errors that stemmed from
warnings. The error messages included the tag `-Werror`:
```
../../src/compiler/turboshaft/wasm-gc-type-reducer.cc:212:18: error: 'back_insert_iterator' may not intend to support class template argument deduction [-Werror,-Wctad-maybe-unsupported]
@ -805,7 +806,7 @@ fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec<u8> {
}
```
:::note
:::note Tested Deployments
This demo was last tested in the following deployments:
@ -814,7 +815,7 @@ This demo was last tested in the following deployments:
| `darwin-x64` | `0.81.0` | 2023-11-14 |
| `darwin-arm` | `0.79.2` | 2023-10-18 |
| `win10-x64` | `0.81.0` | 2023-11-14 |
| `linux-x64` | `0.79.2` | 2023-10-11 |
| `linux-x64` | `0.81.0` | 2023-11-27 |
| `linux-arm` | `0.75.1` | 2023-08-30 |
:::

@ -34,7 +34,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
- [`Svelte`](/docs/demos/frontend/svelte)
- [`VueJS`](/docs/demos/frontend/vue)
- [`AngularJS`](/docs/demos/frontend/angularjs)
- [`Dojo`](/docs/demos/frontend/legacy#dojo-toolkit)
- [`Dojo`](/docs/demos/frontend/dojo)
- [`Knockout`](/docs/demos/frontend/legacy#knockoutjs)
### Front-End UI Components

@ -33,17 +33,17 @@ After cloning the repo, running `make help` will display a list of commands.
These instructions will cover system configuration, cloning the source repo,
building, reproducing official releases, and running NodeJS and browser tests.
:::note
:::note Tested Deployments
These instructions were tested on the following platforms:
| Platform | Test Date |
|:------------------------------|:-----------|
| Linux (Steam Deck Holo x64) | 2023-10-11 |
| Linux (Steam Deck Holo x64) | 2023-11-27 |
| Linux (Ubuntu 18 AArch64) | 2023-09-07 |
| MacOS 10.13.6 (x64) | 2023-09-30 |
| MacOS 13.6 (ARM64) | 2023-09-30 |
| Windows 10 (x64) + WSL Ubuntu | 2023-11-13 |
| Windows 10 (x64) + WSL Ubuntu | 2023-11-27 |
| Windows 11 (x64) + WSL Ubuntu | 2023-10-14 |
| Windows 11 (ARM) + WSL Ubuntu | 2023-09-18 |
@ -163,7 +163,7 @@ sudo apt-get install -y nodejs
D) Exit the WSL session and start a new session
E) Install the `n` package and switch NodeJS vesrions:
E) Install the `n` package and switch NodeJS versions:
```bash
# Switch to `n`-managed NodeJS
@ -312,6 +312,14 @@ Desktop Mode on the Steam Deck uses `pacman`. It also requires a few steps.
0) Switch to Desktop mode and open `Konsole`
:::tip pass
At this point, it is strongly recommended to install the `ungoogled-chromium`
browser from the "Discover" app and open this page on the Steam Deck. Running
the browser on the device makes it easy to copy and paste commands.
:::
1) Set a password for the user by running `passwd` and following instructions.
2) Disable read-only mode:
@ -356,12 +364,27 @@ After installing mercurial and subversion, install NodeJS.
:::note pass
[The official NodeJS site](https://nodejs.org/en/download/) provides installers
for "LTS" and "Current" releases. The "LTS" version should be installed.
[The official NodeJS site](https://nodejs.org/en/download/) provides Linux
binaries, but it is strongly recommended to use `nvm` to install NodeJS:
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
```
After installing, start a new terminal session and install NodeJS "LTS":
```bash
nvm install --lts
```
After installing, if running `node` in the terminal fails with a `glibc` error,
an older version of NodeJS should be installed. For example, Ubuntu 18.04 does
not support Node 18 support Node 16.20.0.
not support Node 18 but supports Node 16.20.0:
```bash
nvm install 16
nvm use 16
```
:::

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex">
<title>SheetJS + Dojo Memory Store Demo</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.14.1/dijit/themes/claro/claro.css">
</head>
<body class="claro">
<h1>SheetJS + Dojo Memory Store Demo</h1>
<br/>
This demo fetches <a href="https://sheetjs.com/pres.xlsx">https://sheetjs.com/pres.xlsx</a>, parses the file, generates a Memory store from the first worksheet, and loads a Combo box. When a President is selected, the text box will display the "Index" field from the dataset.
<br/>
(this HTML page is not minified -- feel free to view source!)<br/><br/>
<a href="https://docs.sheetjs.com">SheetJS CE Documentation</a><br/><br/>
<script>
dojoConfig = {
parseOnLoad: true,
packages: [
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-latest/package/dist", main: "xlsx.full.min" }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.14.1/dojo/dojo.js" data-dojo-config=""></script>
<script>
require([
"dojo/ready",
"dojo/request/xhr",
"dojo/store/Memory",
"dijit/registry",
"xlsx"
], function(ready, xhr, Memory, registry, _XLSX) {
ready(function() {
/* fetch test file */
xhr("https://sheetjs.com/pres.xlsx", {
headers: { "X-Requested-With": null },
handleAs: "arraybuffer"
}).then(function(ab) {
/* read ArrayBuffer */
var wb = XLSX.read(ab);
/* generate row objects from first worksheet */
var ws = wb.Sheets[wb.SheetNames[0]];
var aoo = XLSX.utils.sheet_to_json(ws);
/* generate memory store and assign to combo box*/
var store = new Memory({ data: aoo });
registry.byId("combo").store = store;
/* when a President is selected, display the index */
registry.byId("combo").watch("item", function(w, oitem, nitem) {
registry.byId("pindex").set("value", nitem.Index);
});
});
});
});
</script>
<b>Select a president</b><br/>
<div id="combo" data-dojo-type="dijit/form/ComboBox" data-dojo-props="searchAttr:'Name'"></div><br/>
<b>Index of Selected President</b><br/>
<div id="pindex" data-dojo-type="dijit/form/TextBox"></div>
</body>
</html>

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex">
<title>SheetJS + Dojo Store Export Demo</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.14.1/dijit/themes/claro/claro.css">
</head>
<body class="claro">
<h1>SheetJS + Dojo Store Export Demo</h1>
<br/>
This demo exports data from a simple Dojo store, attempting to create a XLSX workbook.
<br/>
(this HTML page is not minified -- feel free to view source!)<br/><br/>
<a href="https://docs.sheetjs.com">SheetJS CE Documentation</a><br/><br/>
<script>
dojoConfig = {
parseOnLoad: true,
packages: [
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-latest/package/dist", main: "xlsx.full.min" }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.14.1/dojo/dojo.js" data-dojo-config=""></script>
<script>
require([
"dojo/store/Memory",
"dijit/registry",
"xlsx"
], function(Memory, registry, _XLSX) {
/* create simple Memory store */
var data = [
{ Name: "Bill Clinton", Index: 42 },
{ Name: "GeorgeW Bush", Index: 43 },
{ Name: "Barack Obama", Index: 44 },
{ Name: "Donald Trump", Index: 45 },
{ Name: "Joseph Biden", Index: 46 }
];
var store = new Memory({data: data});
/* pull all data rows from the store */
var rows = store.query(function() { return true; });
/* generate SheetJS workbook */
var ws = XLSX.utils.json_to_sheet(rows);
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Export");
/* write to file */
XLSX.writeFile(wb, "SheetJSDojoStoreExport.xlsx");
});
</script>
</body>
</html>