OpenUI5 Demo
This commit is contained in:
parent
f48835d420
commit
8c95521682
@ -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
|
||||
|
||||
|
@ -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).
|
||||
|
||||
<details>
|
||||
<summary><b>ARC Instructions</b> (click to show)</summary>
|
||||
|
||||
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.
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Additional steps for Intel GPUs</b> (click to show)</summary>
|
||||
|
||||
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"});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
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.
|
||||
|
@ -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"
|
||||
<mvc:View>
|
||||
<Page>
|
||||
@ -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"
|
||||
<mvc:View>
|
||||
<Page>
|
||||
<!-- The `onExport` method is bound to the `press` event -->
|
||||
<Button text="Export Data" press=".onExport" />
|
||||
</Page>
|
||||
</mvc:View>
|
||||
```
|
||||
|
||||
#### 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"
|
||||
<mvc:View
|
||||
controllerName="sheetjs.openui5.controller.Main"
|
||||
displayBlock="true"
|
||||
xmlns="sap.m"
|
||||
xmlns:mvc="sap.ui.core.mvc"
|
||||
xmlns:core="sap.ui.core"
|
||||
core:require="{formatter: 'sheetjs/openui5/model/formatter'}">
|
||||
<Page>
|
||||
<VBox width="auto" alignItems="Start">
|
||||
<Table width="300px" items="{/presidents}">
|
||||
<columns>
|
||||
<Column>
|
||||
<header>
|
||||
<Text text="Name" />
|
||||
</header>
|
||||
</Column>
|
||||
<Column>
|
||||
<header>
|
||||
<Text text="Value" />
|
||||
</header>
|
||||
</Column>
|
||||
</columns>
|
||||
<items>
|
||||
<ColumnListItem>
|
||||
<cells>
|
||||
<Text text="{Name}" />
|
||||
<Text text="{Index}" />
|
||||
</cells>
|
||||
</ColumnListItem>
|
||||
</items>
|
||||
</Table>
|
||||
<Button text="Export XLSX" press=".onExport" />
|
||||
</VBox>
|
||||
</Page>
|
||||
<mvc:View controllerName="sheetjs.openui5.controller.Main" displayBlock="true" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" core:require="{formatter: 'sheetjs/openui5/model/formatter'}">
|
||||
<Page>
|
||||
<VBox width="auto" alignItems="Start">
|
||||
<Table width="300px" items="{/presidents}">
|
||||
<columns>
|
||||
<Column><header><Text text="Name" /></header></Column>
|
||||
<Column><header><Text text="Index" /></header></Column>
|
||||
</columns>
|
||||
<items><ColumnListItem><cells>
|
||||
<Text text="{Name}" />
|
||||
<Text text="{Index}" />
|
||||
</cells></ColumnListItem></items>
|
||||
</Table>
|
||||
<Button text="Export XLSX" press=".onExport" />
|
||||
</VBox>
|
||||
</Page>
|
||||
</mvc:View>
|
||||
```
|
||||
|
||||
##### 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 <kbd>Enter</kbd>
|
||||
- `Which framework do you want to use?`: Press <kbd>Enter</kbd> (`OpenUI5` should be the default)
|
||||
- `Which framework version do you want to use?`: Type `1.132.1` and press <kbd>Enter</kbd>
|
||||
- `Who is the author of the application?`: Press <kbd>Enter</kbd> (use the default author)
|
||||
- `Would you like to create a new directory for the application?`: Type `Y` and press <kbd>Enter</kbd>
|
||||
- `Would you like to initialize a local git repository for the application?`: Type `N` and press <kbd>Enter</kbd>
|
||||
|
||||
![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.
|
||||
|
||||
<CodeBlock language="html" value="html" title="webapp/index.html">
|
||||
{`<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>`}
|
||||
4) Add the SheetJS Standalone script to `webapp/index.html` after the `title` tag:
|
||||
|
||||
<CodeBlock language="html" value="html" title="webapp/index.html (add highlighted lines)">{`\
|
||||
<title>UI5 Application: sheetjs.openui5</title>
|
||||
<!-- highlight-next-line -->
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>`}
|
||||
</CodeBlock>
|
||||
|
||||
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"
|
||||
<mvc:View
|
||||
controllerName="sheetjs.openui5.controller.Main"
|
||||
displayBlock="true"
|
||||
xmlns="sap.m"
|
||||
xmlns:mvc="sap.ui.core.mvc"
|
||||
xmlns:core="sap.ui.core"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<Page>
|
||||
<content>
|
||||
<core:HTML content="{/tableHTML}" />
|
||||
<Button text="Export XLSX" press=".onExport"/>
|
||||
</content>
|
||||
</Page>
|
||||
<mvc:View controllerName="sheetjs.openui5.controller.Main" displayBlock="true" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<Page>
|
||||
<content>
|
||||
<core:HTML id="tbl" content="{/tableHTML}" />
|
||||
<Button text="Export XLSX" press=".onExport"/>
|
||||
</content>
|
||||
</Page>
|
||||
</mvc:View>
|
||||
```
|
||||
|
||||
##### 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: `<table>`, footer: `</table>` };
|
||||
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: `<table id="excel-table">`,
|
||||
footer: `</table>`
|
||||
};
|
||||
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 <kbd>Enter</kbd>
|
||||
- `Which framework do you want to use?`: Press <kbd>Enter</kbd> (`OpenUI5` should be the default)
|
||||
- `Which framework version do you want to use?`: Type `1.132.1` and press <kbd>Enter</kbd>
|
||||
- `Who is the author of the application?`: Press <kbd>Enter</kbd> (use the default author)
|
||||
- `Would you like to create a new directory for the application?`: Type `Y` and press <kbd>Enter</kbd>
|
||||
- `Would you like to initialize a local git repository for the application?`: Type `N` and press <kbd>Enter</kbd>
|
||||
|
||||
![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.
|
||||
|
||||
<CodeBlock language="html" value="html" title="webapp/index.html">
|
||||
{`<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>`}
|
||||
4) Add the SheetJS Standalone script to `webapp/index.html` after the `title` tag:
|
||||
|
||||
<CodeBlock language="html" value="html" title="webapp/index.html (add highlighted lines)">{`\
|
||||
<title>UI5 Application: sheetjs.openui5</title>
|
||||
<!-- highlight-next-line -->
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>`}
|
||||
</CodeBlock>
|
||||
|
||||
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/)
|
||||
[^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.
|
@ -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.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -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.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -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.
|
||||
|
||||
:::
|
||||
|
@ -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.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -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.
|
||||
|
||||
:::
|
||||
|
||||
|
BIN
docz/static/ui5/easy-ui5.png
Normal file
BIN
docz/static/ui5/easy-ui5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 128 KiB |
Loading…
Reference in New Issue
Block a user