diff --git a/docz/docs/02-getting-started/01-installation/04-amd.md b/docz/docs/02-getting-started/01-installation/04-amd.md
index 1206ed1..ad2c078 100644
--- a/docz/docs/02-getting-started/01-installation/04-amd.md
+++ b/docz/docs/02-getting-started/01-installation/04-amd.md
@@ -125,47 +125,13 @@ define(['N/file', 'sheetjs'], function(file, XLSX) {
## SAP UI5
-After downloading the script, it can be uploaded to the UI5 project and loaded
-in the `sap.ui.define` call:
+OpenUI5 and SAPUI5 installation instructions are covered in the dedicated
+["OpenUI5 / SAPUI5" demo](/docs/demos/frontend/openui5#installation).
-```js
-sap.ui.define([
- /* ... other libraries ... */
- "path/to/xlsx.full.min"
-], function(/* ... variables for the other libraries ... */, XLSX) {
- // use XLSX here
-});
-```
+SheetJS standalone scripts can be loaded in two ways:
-:::caution pass
-
-In some deployments, the function argument was `undefined`.
-
-The standalone scripts add `window.XLSX`, so it is recommended to use `_XLSX`
-in the function arguments and access the library with `XLSX` in the callback:
-
-```js
-sap.ui.define([
- /* ... other libraries ... */
- "path/to/xlsx.full.min"
-], function(
- /* ... variables for the other libraries ... */,
- _XLSX // !! NOTE: this is not XLSX! A different variable name must be used
-) {
- // highlight-next-line
- alert(XLSX.version); // use XLSX in the callback
-});
-```
-
-:::
-
-:::danger pass
-
-**Copy and pasting code does not work** for SheetJS scripts as they contain
-Unicode characters that may be mangled. The standalone script should be
-downloaded and manually uploaded to the project.
-
-:::
+- [`sap.ui.define`](/docs/demos/frontend/openui5#installation-define)
+- [HTML SCRIPT tag](/docs/demos/frontend/openui5#installation-html)
## RequireJS
diff --git a/docz/docs/02-getting-started/02-examples/06-loader.md b/docz/docs/02-getting-started/02-examples/06-loader.md
index 044cf90..5ba6b28 100644
--- a/docz/docs/02-getting-started/02-examples/06-loader.md
+++ b/docz/docs/02-getting-started/02-examples/06-loader.md
@@ -39,6 +39,7 @@ This demo was tested in the following configurations:
| NVIDIA RTX 4080 SUPER (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-12 |
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-12 |
| AMD RX 6800 XT (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-12 |
+| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-01-24 |
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2024-11-04 |
SheetJS users have verified this demo in other configurations:
@@ -718,25 +719,13 @@ export default class LoadOfSheet extends BufferLoader {
The demo performs the query "Which rows have over 40 miles per gallon?" against
a [sample cars dataset](pathname:///cd.xls) and displays the results.
-:::note pass
-
-SheetJS team members have tested this demo on Windows 10 and Windows 11 using
-PowerShell and Ollama for Windows.
-
-SheetJS team members have tested this demo on Windows 11 using Windows Subsystem
-for Linux.
-
-In addition, SheetJS users have also tested this demo on bare metal Linux.
-
-:::
-
:::caution pass
This demo was tested using the ChatQA-1.5 model[^9] in Ollama.
-The tested model used up to 9.2GB VRAM. It is strongly recommended to run the
-demo on a newer Apple Silicon Mac or a PC with an Nvidia GPU with at least 12GB
-VRAM. SheetJS users have tested the demo on systems with as little as 6GB VRAM.
+The tested model used up to 10GB VRAM. It is strongly recommended to run the
+demo on a GPU with at least 12GB VRAM or a newer Apple Silicon Mac with at least
+32GB unified memory.
:::
@@ -752,6 +741,71 @@ within WSL, Ollama should also be installed within WSL.
:::
+:::danger pass
+
+Intel ARC GPUs require the Intel Extension for PyTorch (IPEX) and a special
+version of Ollama that ships with the associated LLM Library (IPEX-LLM).
+
+
+ ARC Instructions (click to show)
+
+These instructions are based on the official Intel recommendations.
+
+A) If Ollama for Windows was installed, close the program by right-clicking on
+the tray icon and selecting "Quit Ollama".
+
+B) Install Miniforge3[^10], selecting "Just Me" when prompted.
+
+C) Launch a normal Command Prompt and create a Conda environment:
+
+```bash
+cd %USERPROFILE%\Documents
+mkdir ollama-intel
+cd ollama-intel
+set PATH=%PATH%;%USERPROFILE%\miniforge3\condabin
+conda create -n llm-cpp python=3.11
+```
+
+D) Activate the environment in the session and install dependencies:
+
+```bash
+conda activate llm-cpp
+pip install --pre --upgrade ipex-llm[cpp]
+```
+
+Close the window after the installation.
+
+E) Launch a new Administrator Command Prompt and set up Ollama:
+
+```bash
+cd %USERPROFILE%\Documents\ollama-intel
+set PATH=%PATH%;%USERPROFILE%\miniforge3\condabin
+conda activate llm-cpp
+init-ollama.bat
+```
+
+Close the window.
+
+F) Launch a normal Command Prompt window and run Ollama:
+
+```bash
+cd %USERPROFILE%\Documents\ollama-intel
+set PATH=%PATH%;%USERPROFILE%\miniforge3\condabin
+conda activate llm-cpp
+set OLLAMA_NUM_GPU=999
+set no_proxy=localhost,127.0.0.1
+set ZES_ENABLE_SYSMAN=1
+set SYCL_CACHE_PERSISTENT=1
+set SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1
+ollama serve
+```
+
+This window should be kept open throughout the demo.
+
+
+
+:::
+
After installing dependencies, start a new terminal session.
1) Create a new project:
@@ -840,6 +894,27 @@ curl.exe -LO https://docs.sheetjs.com/cd.xls
ollama pull llama3-chatqa:8b-v1.5-q8_0
```
+
+ Additional steps for Intel GPUs (click to show)
+
+A different embedding model must be used on Intel GPUs:
+
+A) Install the `nomic-embed-text:latest` model through Ollama:
+
+```bash
+ollama pull nomic-embed-text:latest
+```
+
+B) Edit `query.mjs` to use the embedding model:
+
+```js title="query.mjs (edit highlighted line)"
+const model = new ChatOllama({ baseUrl: "http://127.0.0.1:11434", model: modelName });
+// highlight-next-line
+const embeddings = new OllamaEmbeddings({ baseUrl: "http://127.0.0.1:11434", model: "nomic-embed-text:latest"});
+```
+
+
+
7) Run the demo script
```bash
@@ -899,3 +974,4 @@ charts, tables, and other features.
[^7]: See ["Workbook Object"](/docs/csf/book)
[^8]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
[^9]: See [the official ChatQA website](https://chatqa-project.github.io/) for the ChatQA paper and other model details.
+[^10]: Select ["Windows" `x86_64`](https://conda-forge.org/download/) in the Installation page.
diff --git a/docz/docs/03-demos/02-frontend/10-openui5.md b/docz/docs/03-demos/02-frontend/10-openui5.md
index 0a631dc..a3cbd1f 100644
--- a/docz/docs/03-demos/02-frontend/10-openui5.md
+++ b/docz/docs/03-demos/02-frontend/10-openui5.md
@@ -34,6 +34,38 @@ includes a complete example starting from the OpenUI5 "Worklist App Tutorial".
SheetJS libraries conform to the UI5 ECMAScript requirements[^1]. SheetJS
libraries can be loaded in a UI5 site at different points in the app lifecycle.
+#### UI5 Module {#installation-define}
+
+The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
+comply with AMD `define` semantics. They support `sap.ui.define` out of the box.
+
+If the SheetJS Standalone script is saved to `webapp/xlsx.full.min.js`, the base
+script `webapp/index.js` can load the `./xlsx.full.min` dependency:
+
+```js title="webapp/index.js (loading the SheetJS dependency)"
+sap.ui.define([
+ // highlight-next-line
+ "./xlsx.full.min", // relative path to script, without the file extension
+ /* ... other libraries ... */
+], function (
+ // highlight-next-line
+ _XLSX // !! NOTE: this is not XLSX! A different variable name must be used
+ /* ... variables for the other libraries ... */,
+) {
+ // highlight-next-line
+ alert(XLSX.version); // use XLSX in the callback
+});
+```
+
+:::info pass
+
+In some deployments, the function argument was `undefined`.
+
+The standalone scripts add `window.XLSX`, so it is recommended to use `_XLSX`
+in the function arguments and access the library with `XLSX` in the callback.
+
+:::
+
#### HTML {#installation-html}
UI5 is typically loaded in a `SCRIPT` tag in `webapp/index.html`. Similarly,
@@ -72,38 +104,6 @@ in the ["API Reference"](/docs/api/) section of the documentation.
:::
-#### UI5 Module {#installation-define}
-
-The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
-comply with AMD `define` semantics. They support `sap.ui.define` out of the box.
-
-If the SheetJS Standalone script is saved to `webapp/xlsx.full.min.js`, the base
-script `webapp/index.js` can load the `./xlsx.full.min` dependency:
-
-```js title="webapp/index.js (loading the SheetJS dependency)"
-sap.ui.define([
- // highlight-next-line
- "./xlsx.full.min", // relative path to script, without the file extension
- /* ... other libraries ... */
-], function (
- // highlight-next-line
- _XLSX // !! NOTE: this is not XLSX! A different variable name must be used
- /* ... variables for the other libraries ... */,
-) {
- // highlight-next-line
- alert(XLSX.version); // use XLSX in the callback
-});
-```
-
-:::info pass
-
-In some deployments, the function argument was `undefined`.
-
-The standalone scripts add `window.XLSX`, so it is recommended to use `_XLSX`
-in the function arguments and access the library with `XLSX` in the callback.
-
-:::
-
## Internal State
The various SheetJS APIs work with various data shapes. The preferred state
@@ -158,7 +158,7 @@ sap.ui.define(["sap/ui/model/json/JSONModel"], function (JSONModel) {
#### Updating State {#json-update}
Starting from a spreadsheet file, the SheetJS [`read`](/docs/api/parse-options)
-method parses the data into a SheetJS workbook object[^6]. After selecting a
+method parses the data into a SheetJS workbook object[^3]. After selecting a
worksheet, the [`sheet_to_json`](/docs/api/utilities/array#array-output) method
generates row objects that can be assigned to the model.
@@ -201,10 +201,12 @@ _loadExcelFile: async function () {
#### Rendering Data {#json-render}
-In UI5, the "Model-View-Controller"[^3] pattern is used to organize code and
+In UI5, the "Model-View-Controller"[^4] pattern is used to organize code and
separate concerns. The view defines the UI structure, the controller handles the
logic, and the model manages the data.
+The following example uses the `Table` component[^5] to display data.
+
```xml title="Example View XML for displaying an array of objects"
@@ -234,37 +236,56 @@ logic, and the model manages the data.
#### Exporting Data {#json-export}
-The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
-functions simplify exporting data. They are typically used in event handlers attached to buttons or other elements.
+The `getProperty` method[^6] of the `JSONModel` pulls data from the UI5 model.
+If an array of objects was pushed with `setProperty`, the `getProperty` method
+will return an array of objects.
-A button press handler can generate a local file when clicked:
+The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
+function will create a SheetJS worksheet object[^7] from the data in the array.
+The [`book_new`](/docs/api/utilities/wb) method will create a SheetJS workbook
+object that includes the new worksheet. [`writeFile`](/docs/api/write-options)
+will attempt to generate a file and initiate a download.
```mermaid
flowchart LR
- state((oModel\ngetProperty))
+ state((State\nJSONModel))
+ aoo[(Array of\nObjects)]
ws(SheetJS\nWorksheet)
- wb(SheetJS\nWorkbook)
+ wb(((SheetJS\nWorkbook)))
file[(XLSX\nexport)]
- state --> |json_to_sheet\n\n| ws
- ws --> |book_new\nbook_append_sheet| wb
+ state --> |getProperty\n\n| aoo
+ aoo --> |json_to_sheet\n\n| ws
+ ws --> |book_new\n\n| wb
wb --> |writeFile\n\n| file
+ linkStyle 1,2,3 color:blue,stroke:blue;
```
-```js
+Here is a sample method for exporting data from the UI5 `JSONModel` to XLSX:
+
+```js title="Fetch data from JSONModel and export to XLSX"
/* get model data and export to XLSX */
- onExport: function () {
- const data = this.getView().getModel().getProperty("/presidents");
- /* generate worksheet from model data */
- // highlight-next-line
- const ws = XLSX.utils.json_to_sheet(data);
- /* create workbook and append worksheet */
- const wb = XLSX.utils.book_new();
- XLSX.utils.book_append_sheet(wb, ws, "Data");
- /* export to XLSX */
- XLSX.writeFileXLSX(wb, "SheetJSOpenUI5AoO.xlsx");
- }
+onExport: function () {
+ const data = this.getView().getModel().getProperty("/presidents");
+ /* generate worksheet from model data */
+ // highlight-next-line
+ const ws = XLSX.utils.json_to_sheet(data);
+ /* create workbook and append worksheet */
+ const wb = XLSX.utils.book_new(ws, "Data");
+ /* export to XLSX */
+ XLSX.writeFileXLSX(wb, "SheetJSOpenUI5AoO.xlsx");
+}
```
+This method can be bound to the `press` event of a `sap.m.Button` control:
+
+```xml title="Example View XML for exporting an array of objects to a workbook"
+
+
+
+
+
+
+```
#### Complete Component
@@ -272,79 +293,66 @@ This complete component example fetches a test file and displays the contents in
When the export button is clicked, an event handler will export a file:
##### View Implementation {#view-implementation}
+
```xml title="webapp/view/Main.view.xml"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
```
+
##### Controller Implementation {#controller-implementation}
+
```js title="webapp/controller/Main.controller.js"
sap.ui.define(
- ["./BaseController", "sap/ui/model/json/JSONModel"],
- function (BaseController, JSONModel) {
- "use strict";
+ ["./BaseController", "sap/ui/model/json/JSONModel"],
+ function (BaseController, JSONModel) {
+ "use strict";
- return BaseController.extend("com.demo.xlsx.controller.Main", {
- onInit: function () {
- /* initialize model */
- const oModel = new JSONModel({
- presidents: [],
- });
- this.getView().setModel(oModel);
+ return BaseController.extend("com.demo.xlsx.controller.Main", {
+ onInit: function () {
+ /* initialize model */
+ const oModel = new JSONModel({ presidents: [] });
+ this.getView().setModel(oModel);
+ /* load data */
+ this._loadExcelFile();
+ },
- /* load data when component is initialized */
- this._loadExcelFile();
- },
+ _loadExcelFile: async function () {
+ /* fetch and parse file */
+ const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
+ const wb = XLSX.read(f);
+ /* extract data from first worksheet */
+ const ws = wb.Sheets[wb.SheetNames[0]];
+ const data = XLSX.utils.sheet_to_json(ws);
+ /* update state model */
+ this.getView().getModel().setProperty("/presidents", data);
+ },
- _loadExcelFile: async function () {
- const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
- const wb = XLSX.read(f);
- const ws = wb.Sheets[wb.SheetNames[0]];
- const data = XLSX.utils.sheet_to_json(ws);
- this.getView().getModel().setProperty("/presidents", data);
- },
-
- onExport: function () {
- const data = this.getView().getModel().getProperty("/presidents");
- const ws = XLSX.utils.json_to_sheet(data);
- const wb = XLSX.utils.book_new();
- XLSX.utils.book_append_sheet(wb, ws, "Data");
- XLSX.writeFileXLSX(wb, "SheetJSOpenUI5AoO.xlsx");
- },
- });
- }
+ onExport: function () {
+ /* fetch data from model */
+ const data = this.getView().getModel().getProperty("/presidents");
+ /* generate workbook */
+ const ws = XLSX.utils.json_to_sheet(data);
+ const wb = XLSX.utils.book_new(ws, "Data");
+ /* export to XLSX */
+ XLSX.writeFileXLSX(wb, "SheetJSOpenUI5AoO.xlsx");
+ },
+ });
+ }
);
```
@@ -354,9 +362,10 @@ sap.ui.define(
:::note Tested Deployments
This demo was tested in the following environments:
-| OpenUI5 | generator-easy-ui5 | Date |
-|:--------|---------|---------|
-| `1.131.1` | `3.8.1` | 2025-01-07 |
+
+| OpenUI5 | Date |
+|:----------|------------|
+| `1.132.1` | 2025-01-24 |
:::
@@ -367,17 +376,16 @@ npm i --global generator-easy-ui5
npx yo easy-ui5 app
```
-:::note Use the provided defaults:
+When prompted, enter the following options:
- - Application id: `sheetjs.openui5`
- - Framework: `OpenUI5`
- - Version: `1.131.1`
- - Author: `SheetJS`
- - Create new directory: `Y`
- - Initialize git: `N`
-
-:::
+ - `Enter your application id (namespace)?`: Type `sheetjs.openui5` and press Enter
+ - `Which framework do you want to use?`: Press Enter (`OpenUI5` should be the default)
+ - `Which framework version do you want to use?`: Type `1.132.1` and press Enter
+ - `Who is the author of the application?`: Press Enter (use the default author)
+ - `Would you like to create a new directory for the application?`: Type `Y` and press Enter
+ - `Would you like to initialize a local git repository for the application?`: Type `N` and press Enter
+![Expected output](pathname:///ui5/easy-ui5.png)
2) Install the dependencies and start server:
@@ -387,35 +395,57 @@ npm install
npm start
```
-3) Open a web browser and access the displayed URL (`http://localhost:8080`)
+3) Open a web browser and access the displayed URL (`http://localhost:8080`).
-4) Add SheetJS to your project by including this script tag in `webapp/index.html`:
+In the file listing, click `index.html` to launch the app.
-
- {``}
+4) Add the SheetJS Standalone script to `webapp/index.html` after the `title` tag:
+
+{`\
+ UI5 Application: sheetjs.openui5
+
+ `}
-5) Replace `webapp/view/Main.view.xml` with the complete [implementation above](#view-implementation).
-6) Replace `webapp/controller/Main.controller.js` with the complete [implementation above](#controller-implementation).
+5) Replace `webapp/view/Main.view.xml` with the `Main.view.xml` snippet in the
+["View Implementation" section](#view-implementation).
-The page will refresh and show a table with an Export button. Click the button and the page will
-attempt to download `SheetJSOpenUI5AoO.xlsx`.
+6) Replace `webapp/controller/Main.controller.js` with the `Main.controller.js`
+example in the ["Controller Implementation" section](#controller-implementation).
-7) Build the site:
+7) Switch back to the browser window.
+
+The page will refresh and show a table with an Export button.
+
+Click the button and the page will attempt to download `SheetJSOpenUI5AoO.xlsx`.
+This file can be inspected with a spreadsheet editor.
+
+8) Build the site:
```bash
-npm run build
+npm run build:opt
```
The generated site will be placed in the `dist` folder.
-8) Start a local web server:
+:::caution pass
+
+SAP recommends `npm run build`. This does not generate a proper standalone site!
+Sites built with `npm run build` must be served with `npm run start:dist`.
+
+This demo uses the `build:opt` target to ensure that a proper static site is
+generated. The `dist` folder in this demo can be posted
+
+:::
+
+9) Start a local web server:
```bash
-npm run start:dist
+npx http-server dist
```
-Access the displayed URL (typically http://localhost:8080) with a web browser and test the page.
+Access the displayed URL (typically `http://localhost:8080`) with a web browser
+and test the page.
When the page loads, the app will fetch https://docs.sheetjs.com/pres.xlsx and
display the data from the first worksheet in a TABLE. The "Export XLSX" button
@@ -426,82 +456,73 @@ will generate a workbook that can be opened in a spreadsheet editor.
### HTML
The main disadvantage of the Array of Objects approach is the specific nature
-of the columns. For more general use, passing around an Array of Arrays works.
-However, this does not handle merge cells[^4] well!
+of the columns. For more general use, passing around an Array of Arrays works.
+However, this does not handle merge cells[^8] well!
-The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function generates HTML that is aware of merges and other worksheet
-features. Using OpenUI5's `core:HTML`[^5] control, we can render this HTML directly. During export, we extract the table element from the
-rendered HTML and use [`table_to_book`](/docs/api/utilities/html#html-table-input) to create a workbook that maintains all the worksheet
-features.
+The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
+generates HTML that is aware of merges and other worksheet features.
-In this example, the component directly renders the HTML table in the model through OpenUI5's `core:HTML`[^5] control. For export, we extract
-the inner table from the rendered HTML using `getElementsByTagName("table")[1]`, then pass it to [`table_to_book`](/docs/api/utilities/html#html-table-input)
-to create a workbook that preserves all features.
+To render the HTML string from the model, the property from the model should be
+bound to the `content` property of a UI5 `core:HTML`[^9] control.
+
+On export, the [`table_to_book`](/docs/api/utilities/html#html-table-input)
+method creates a SheetJS workbook object from the rendered HTML table.
##### View Implementation {#view-implementation-html}
+
```xml title="webapp/view/Main.view.xml"
-
-
-
-
-
-
-
+
+
+
+
+
+
+
```
##### Controller Implementation {#controller-implementation-html}
+
```js title="webapp/controller/Main.controller.js"
-sap.ui.define(
- [
- "sap/ui/core/mvc/Controller",
- "sap/ui/model/json/JSONModel"
- ],
- function (Controller, JSONModel) {
- "use strict";
+sap.ui.define([
+ "sap/ui/core/mvc/Controller",
+ "sap/ui/model/json/JSONModel"
+ ], function (Controller, JSONModel) {
+ "use strict";
- return Controller.extend("sheetjs.openui5.controller.Main", {
- onInit: function () {
- /* the component state is an HTML string */
- const oModel = new JSONModel({
- tableHTML: "",
- });
- this.getView().setModel(oModel);
+ return Controller.extend("sheetjs.openui5.controller.Main", {
+ onInit: function () {
+ /* the component state is an HTML string */
+ const oModel = new JSONModel({ tableHTML: "", });
+ this.getView().setModel(oModel);
+ /* load data */
+ this._loadExcelFile();
+ },
- /* load data when component is initialized */
- this._loadExcelFile();
- },
+ _loadExcelFile: async function () {
+ /* fetch and parse file */
+ const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
+ const wb = XLSX.read(f);
+ /* generate HTML table from first worksheet */
+ const ws = wb.Sheets[wb.SheetNames[0]];
+ const opts = { header: `
`, footer: `
` };
+ const tableHTML = XLSX.utils.sheet_to_html(ws, opts);
+ /* update state model */
+ this.getView().getModel().setProperty("/tableHTML", tableHTML);
+ },
- _loadExcelFile: async function () {
- const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
- const wb = XLSX.read(f); // parse the array buffer
- const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
- const opts = {
- header: `
`,
- footer: `
`
- };
- const tableHTML = XLSX.utils.sheet_to_html(ws, opts); // generate HTML
- this.getView().getModel().setProperty("/tableHTML", tableHTML); // update state
- },
+ onExport: function () {
+ /* Get reference to the `TABLE` element in the model */
+ const table = this.getView().byId("tbl").getDomRef();
- /* get live table and export the XLSX */
- onExport: function () {
- const tableHTML = this.getView().getModel().getProperty("/tableHTML"); // get HTML string from the model
- const div = document.createElement("div"); // create temporary div to parse HTML
- div.innerHTML = tableHTML; // insert HTML into div
+ /* Generate workbook */
+ const wb = XLSX.utils.table_to_book(table);
- const table = div.getElementsByTagName("table")[1]; // get inner table (bypasses outer wrapper)
- const wb = XLSX.utils.table_to_book(table); // convert table element to workbook
- XLSX.writeFileXLSX(wb, "SheetJSOpenUI5HTML.xlsx");
- },
- });
- }
+ /* Export to XLSX */
+ XLSX.writeFileXLSX(wb, "SheetJSOpenUI5HTML.xlsx");
+ },
+ });
+ }
);
```
@@ -511,9 +532,10 @@ sap.ui.define(
:::note Tested Deployments
This demo was tested in the following environments:
-| OpenUI5 | generator-easy-ui5 | Date |
-|:--------|---------|---------|
-| `1.131.1` | `3.8.1` | 2025-01-07 |
+
+| OpenUI5 | Date |
+|:----------|------------|
+| `1.132.1` | 2025-01-24 |
:::
@@ -524,17 +546,16 @@ npm i --global generator-easy-ui5
npx yo easy-ui5 app
```
-:::note Use the provided defaults:
+When prompted, enter the following options:
-- Application id: `sheetjs.openui5`
-- Framework: `OpenUI5`
-- Version: `1.131.1`
-- Author: `SheetJS`
-- Create new directory: `Y`
-- Initialize git: `N`
-
-:::
+ - `Enter your application id (namespace)?`: Type `sheetjs.openui5` and press Enter
+ - `Which framework do you want to use?`: Press Enter (`OpenUI5` should be the default)
+ - `Which framework version do you want to use?`: Type `1.132.1` and press Enter
+ - `Who is the author of the application?`: Press Enter (use the default author)
+ - `Would you like to create a new directory for the application?`: Type `Y` and press Enter
+ - `Would you like to initialize a local git repository for the application?`: Type `N` and press Enter
+![Expected output](pathname:///ui5/easy-ui5.png)
2) Install the dependencies and start server:
@@ -546,33 +567,55 @@ npm start
3) Open a web browser and access the displayed URL (`http://localhost:8080`)
-4) Add SheetJS to your project by including this script tag in `webapp/index.html`:
+In the file listing, click `index.html` to launch the app.
-
- {``}
+4) Add the SheetJS Standalone script to `webapp/index.html` after the `title` tag:
+
+{`\
+ UI5 Application: sheetjs.openui5
+
+ `}
-5) Replace `webapp/view/Main.view.xml` with the complete [implementation above](#view-implementation-html).
-6) Replace `webapp/controller/Main.controller.js` with the complete [implementation above](#controller-implementation-html).
+5) Replace `webapp/view/Main.view.xml` with the `Main.view.xml` snippet in the
+["View Implementation" section](#view-implementation-html).
-The page will refresh and show a table with an Export button. Click the button and the page will
-attempt to download `SheetJSOpenUI5HTML.xlsx`.
+6) Replace `webapp/controller/Main.controller.js` with the `Main.controller.js`
+example in ["Controller Implementation"](#controller-implementation-html).
-7) Build the site:
+7) Switch back to the browser window.
+
+The page will refresh and show a table with an Export button.
+
+Click the button and the page will attempt to download `SheetJSOpenUI5HTML.xlsx`.
+This file can be inspected with a spreadsheet editor.
+
+8) Build the site:
```bash
-npm run build
+npm run build:opt
```
The generated site will be placed in the `dist` folder.
-8) Start a local web server:
+:::caution pass
+
+SAP recommends `npm run build`. This does not generate a proper standalone site!
+Sites built with `npm run build` must be served with `npm run start:dist`.
+
+This demo uses the `build:opt` target to ensure that a proper static site is
+generated. The `dist` folder in this demo can be posted
+
+:::
+
+9) Start a local web server:
```bash
-npm run start:dist
+npx http-server dist
```
-Access the displayed URL (typically http://localhost:8080) with a web browser and test the page.
+Access the displayed URL (typically `http://localhost:8080`) with a web browser
+and test the page.
When the page loads, the app will fetch https://docs.sheetjs.com/pres.xlsx and
display the data from the first worksheet in a TABLE. The "Export XLSX" button
@@ -583,7 +626,10 @@ will generate a workbook that can be opened in a spreadsheet editor.
[^1]: See ["ECMAScript Support"](https://sdk.openui5.org/topic/0cb44d7a147640a0890cefa5fd7c7f8e.html#loio0cb44d7a147640a0890cefa5fd7c7f8e/section_UI5Mod) for more details about OpenUI5 compatibility.
[^2]: See [`JSONModel`](https://sdk.openui5.org/1.38.62/docs/api/symbols/sap.ui.model.json.JSONModel.html) in the OpenUI5 documentation.
-[^3]: See OpenUI5's [MVC Documentation](https://sdk.openui5.org/topic/91f233476f4d1014b6dd926db0e91070) for detailed explanation of the pattern implementation.
-[^4]: See ["Merged Cells" in "SheetJS Data Model"](/docs/csf/features/merges) for more details.
-[^5]: See [`core:HTML`](https://sdk.openui5.org/1.38.62/docs/api/symbols/sap.ui.core.HTML.html) in the OpenUI5 documentation.
-[^6]: See ["SheetJS Data Model"](/docs/csf/)
\ No newline at end of file
+[^3]: See ["SheetJS Data Model"](/docs/csf/)
+[^4]: See [OpenUI5's MVC Documentation](https://sdk.openui5.org/topic/91f233476f4d1014b6dd926db0e91070) for detailed explanation of the pattern implementation.
+[^5]: See ["List, List Item, and Table"](https://sdk.openui5.org/topic/295e44b2d0144318bcb7bdd56bfa5189) in the OpenUI5 documentation.
+[^6]: See [`getProperty` of class `sap.ui.model.json.JSONModel`](https://sdk.openui5.org/api/sap.ui.model.json.JSONModel#methods/getProperty) in the OpenUI5 documentation.
+[^7]: See ["Worksheet Object" in "SheetJS Data Model"](/docs/csf/sheet) for more details.
+[^8]: See ["Merged Cells" in "SheetJS Data Model"](/docs/csf/features/merges) for more details.
+[^9]: See [`core:HTML`](https://sdk.openui5.org/1.38.62/docs/api/symbols/sap.ui.core.HTML.html) in the OpenUI5 documentation.
\ No newline at end of file
diff --git a/docz/docs/03-demos/30-cloud/11-aws.md b/docz/docs/03-demos/30-cloud/11-aws.md
index fa233fe..bf931e3 100644
--- a/docz/docs/03-demos/30-cloud/11-aws.md
+++ b/docz/docs/03-demos/30-cloud/11-aws.md
@@ -33,7 +33,7 @@ will be available in the future.
:::note Tested Deployments
-This demo was last tested on 2024 June 13.
+This demo was last tested on 2024-06-13.
:::
diff --git a/docz/docs/03-demos/30-cloud/12-azure.md b/docz/docs/03-demos/30-cloud/12-azure.md
index 8a259f4..fc74598 100644
--- a/docz/docs/03-demos/30-cloud/12-azure.md
+++ b/docz/docs/03-demos/30-cloud/12-azure.md
@@ -35,7 +35,7 @@ will be available in the future.
:::note Tested Deployments
-This demo was last tested on 2024 June 12.
+This demo was last tested on 2024-06-12.
:::
diff --git a/docz/docs/03-demos/30-cloud/21-gsheet.md b/docz/docs/03-demos/30-cloud/21-gsheet.md
index 54ed00c..1e0901d 100644
--- a/docz/docs/03-demos/30-cloud/21-gsheet.md
+++ b/docz/docs/03-demos/30-cloud/21-gsheet.md
@@ -495,7 +495,7 @@ At this point `wb` is a SheetJS workbook object[^10].
:::note Tested Deployments
-This demo was last tested on 2024 June 08 using `googleapis` version `140.0.0`.
+This demo was last tested on 2024-06-08 using `googleapis` version `140.0.0`.
The demo uses Sheets v4 and Drive v3 APIs.
:::
diff --git a/docz/docs/03-demos/30-cloud/22-airtable.md b/docz/docs/03-demos/30-cloud/22-airtable.md
index 4a55951..0f825e2 100644
--- a/docz/docs/03-demos/30-cloud/22-airtable.md
+++ b/docz/docs/03-demos/30-cloud/22-airtable.md
@@ -206,8 +206,8 @@ const wb = XLSX.readFile("SheetJSAirtableTest.xlsb");
:::note Tested Deployments
-This demo was last tested on 2024 May 04. At the time, free accounts included
-limited API access.
+This demo was last tested on 2024-05-04. In the most recent test, free accounts
+included limited API access.
:::
diff --git a/docz/docs/03-demos/30-cloud/31-dropbox.mdx b/docz/docs/03-demos/30-cloud/31-dropbox.mdx
index 655acec..43f4521 100644
--- a/docz/docs/03-demos/30-cloud/31-dropbox.mdx
+++ b/docz/docs/03-demos/30-cloud/31-dropbox.mdx
@@ -266,7 +266,7 @@ function SheetJSEnregistrez() {
:::note Tested Deployments
-This demo was last tested on 2024 May 27.
+This demo was last tested on 2024-05-27.
:::
diff --git a/docz/static/ui5/easy-ui5.png b/docz/static/ui5/easy-ui5.png
new file mode 100644
index 0000000..3819feb
Binary files /dev/null and b/docz/static/ui5/easy-ui5.png differ