2024-12-26 16:51:25 +00:00
---
2025-01-06 02:51:20 +00:00
title: Sheets in UI5 Sites
sidebar_label: OpenUI5 / SAPUI5
2024-12-26 16:51:25 +00:00
description: Build enterprise-grade applications with OpenUI5. 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: 10
---
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
2025-01-06 02:51:20 +00:00
[OpenUI5 ](https://openui5.org/ ) is a JavaScript framework for building
enterprise-ready web applications. It is compatible with the SAPUI5 framework.
2024-12-26 16:51:25 +00:00
[SheetJS ](https://sheetjs.com ) is a JavaScript library for reading and writing
data from spreadsheets.
2025-01-07 16:45:50 +00:00
This demo shows how to handle spreadsheet data in OpenUI5 apps using SheetJS.
You'll learn how to load spreadsheet files, process their data, and generate
new spreadsheet exports.
2024-12-26 16:51:25 +00:00
2025-01-06 02:51:20 +00:00
:::info pass
[Docs Issue #20 ](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues/20 )
includes a complete example starting from the OpenUI5 "Worklist App Tutorial".
:::
2024-12-26 16:51:25 +00:00
## Installation
2025-01-15 18:43:08 +00:00
SheetJS libraries conform to the UI5 ECMAScript requirements[^1]. SheetJS
2025-01-06 02:51:20 +00:00
libraries can be loaded in a UI5 site at different points in the app lifecycle.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
#### 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.
:::
2025-01-15 18:43:08 +00:00
#### HTML {#installation-html}
2024-12-26 16:51:25 +00:00
2025-01-06 02:51:20 +00:00
UI5 is typically loaded in a `SCRIPT` tag in `webapp/index.html` . Similarly,
[SheetJS Standalone scripts ](/docs/getting-started/installation/standalone )
2025-01-15 18:43:08 +00:00
can be loaded with a `SCRIPT` tag in the same HTML page:
2025-01-06 02:51:20 +00:00
< CodeBlock language = "html" value = "html" > {`\
< script src = "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js" > < / script >
`}
< / CodeBlock >
This will expose the `XLSX` global object, which includes the functions listed
in the ["API Reference" ](/docs/api/ ) section of the documentation.
:::caution pass
2025-01-15 18:43:08 +00:00
**The SheetJS Standalone script must be loaded before the UI5 bootstrap script**:
2025-01-06 02:51:20 +00:00
2025-01-15 18:43:08 +00:00
< CodeBlock language = "html" value = "html" title = "webapp/index.html (loading the SheetJS standalone script)" > {`\
2025-01-06 02:51:20 +00:00
< head >
< meta charset = "utf-8" >
< title > UI5 Walkthrough< / title >
2025-01-15 18:43:08 +00:00
<!-- The SheetJS Standalone script must be loaded before the UI5 bootstrap -->
2025-01-06 02:51:20 +00:00
< script src = "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js" > < / script >
2025-01-15 18:43:08 +00:00
<!-- UI5 bootstrap script -->
2025-01-06 02:51:20 +00:00
< script
id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
...(other attributes)...
2025-01-15 18:43:08 +00:00
>< / script >
2025-01-06 02:51:20 +00:00
< / head >
`}
2024-12-26 16:51:25 +00:00
< / CodeBlock >
2025-01-06 02:51:20 +00:00
:::
2024-12-26 16:51:25 +00:00
## Internal State
The various SheetJS APIs work with various data shapes. The preferred state
depends on the application.
### JSON Model
2025-01-15 18:43:08 +00:00
The UI5 `JSONModel` [^2] is a client-side model implementation for JavaScript
object data. Think of it like a container that holds your spreadsheet data.
`JSONModel` provides powerful two-way data binding capabilities. UI5 will
automatically updates your webpage whenever the data changes. It will also
respond to changes when users interact with components in the webpage.
2024-12-26 16:51:25 +00:00
2025-01-15 18:43:08 +00:00
#### State {#json-state}
2024-12-26 16:51:25 +00:00
The example [presidents sheet ](https://docs.sheetjs.com/pres.xlsx ) has one
header row with "Name" and "Index" columns. The natural JS representation is an
2025-01-15 18:43:08 +00:00
object for each row, where the keys are specified in the first row:
2024-12-26 16:51:25 +00:00
< table >
< thead > < tr > < th > Spreadsheet< / th > < th > State< / th > < / tr > < / thead >
< tbody > < tr > < td >
![`pres.xlsx` data ](pathname:///pres.png )
< / td > < td >
```js
[
{ 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 }
]
```
< / td > < / tr > < / tbody > < / table >
2025-01-15 18:43:08 +00:00
Here is a basic example of initializing a model. A more complete implementation
will be shown later.
2024-12-26 16:51:25 +00:00
2025-01-15 18:43:08 +00:00
```js title="UI5 JSONModel for rows of data"
2024-12-26 16:51:25 +00:00
sap.ui.define(["sap/ui/model/json/JSONModel"], function (JSONModel) {
2025-01-15 18:43:08 +00:00
// highlight-next-line
const oModel = new JSONModel({ presidents: [] });
2024-12-26 16:51:25 +00:00
});
```
2025-01-15 18:43:08 +00:00
#### Updating State {#json-update}
2024-12-26 16:51:25 +00:00
2025-01-15 18:43:08 +00:00
Starting from a spreadsheet file, the SheetJS [`read` ](/docs/api/parse-options )
2025-01-26 16:46:11 +00:00
method parses the data into a SheetJS workbook object[^3]. After selecting a
2025-01-15 18:43:08 +00:00
worksheet, the [`sheet_to_json` ](/docs/api/utilities/array#array-output ) method
generates row objects that can be assigned to the model.
2024-12-26 16:51:25 +00:00
2025-01-15 18:43:08 +00:00
Here is a sample flow diagram and method for downloading a workbook, generating
rows from the first worksheet, and updating a UI5 `JSONModel` :
2024-12-26 16:51:25 +00:00
```mermaid
flowchart LR
url[(Remote\nFile)]
ab[(Data\nArrayBuffer)]
wb(SheetJS\nWorkbook)
ws(SheetJS\nWorksheet)
aoo(array of\nobjects)
model((JSON\nModel))
url --> |fetch\n\n| ab
ab --> |read\n\n| wb
wb --> |wb.Sheets\nselect sheet| ws
ws --> |sheet_to_json\n\n| aoo
aoo --> |setProperty\nfrom model| model
2025-01-15 18:43:08 +00:00
linkStyle 1,2,3 color:blue,stroke:blue;
2024-12-26 16:51:25 +00:00
```
2025-01-15 18:43:08 +00:00
```js title="Download workbook, extract data from first worksheet, and update JSONModel"
2024-12-26 16:51:25 +00:00
_loadExcelFile: async function () {
/* Download from https://docs.sheetjs.com/pres.xlsx */
const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
2025-01-15 18:43:08 +00:00
2024-12-26 16:51:25 +00:00
// highlight-start
/* parse */
const wb = XLSX.read(f); // parse the array buffer
/* generate array of objects from first worksheet */
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
const data = XLSX.utils.sheet_to_json(ws); // generate objects
/* update JSONModel */
2025-01-15 18:43:08 +00:00
this.getView().getModel().setProperty("/presidents", data);
2024-12-26 16:51:25 +00:00
// highlight-end
}
```
2025-01-15 18:43:08 +00:00
#### Rendering Data {#json-render}
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
In UI5, the "Model-View-Controller"[^4] pattern is used to organize code and
2025-01-15 18:43:08 +00:00
separate concerns. The view defines the UI structure, the controller handles the
logic, and the model manages the data.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
The following example uses the `Table` component[^5] to display data.
2025-01-15 18:43:08 +00:00
```xml title="Example View XML for displaying an array of objects"
2024-12-26 16:51:25 +00:00
< mvc:View >
2025-01-15 18:43:08 +00:00
< Page >
<!-- The Table component binds to the presidents array -->
<!-- highlight - next - line -->
< Table width = "300px" items = "{/presidents}" >
<!-- Column definitions specify the table structure -->
< columns >
< Column > < header > < Text text = "Name" / > < / header > < / Column >
< Column > < header > < Text text = "Value" / > < / header > < / Column >
< / columns >
<!-- ColumnListItem template defines how each row should be rendered -->
<!-- highlight - start -->
< items >
< ColumnListItem >
< cells >
< Text text = "{Name}" / >
< Text text = "{Index}" / >
< / cells >
< / ColumnListItem >
< / items >
<!-- highlight - end -->
< / Table >
< / Page >
2024-12-26 16:51:25 +00:00
< / mvc:View >
```
2025-01-15 18:43:08 +00:00
#### Exporting Data {#json-export}
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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.
2024-12-26 16:51:25 +00:00
```mermaid
flowchart LR
2025-01-26 16:46:11 +00:00
state((State\nJSONModel))
aoo[(Array of\nObjects)]
2024-12-26 16:51:25 +00:00
ws(SheetJS\nWorksheet)
2025-01-26 16:46:11 +00:00
wb(((SheetJS\nWorkbook)))
2024-12-26 16:51:25 +00:00
file[(XLSX\nexport)]
2025-01-26 16:46:11 +00:00
state --> |getProperty\n\n| aoo
aoo --> |json_to_sheet\n\n| ws
ws --> |book_new\n\n| wb
2024-12-26 16:51:25 +00:00
wb --> |writeFile\n\n| file
2025-01-26 16:46:11 +00:00
linkStyle 1,2,3 color:blue,stroke:blue;
2024-12-26 16:51:25 +00:00
```
2025-01-26 16:46:11 +00:00
Here is a sample method for exporting data from the UI5 `JSONModel` to XLSX:
```js title="Fetch data from JSONModel and export to XLSX"
2024-12-26 16:51:25 +00:00
/* get model data and export to XLSX */
2025-01-26 16:46:11 +00:00
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");
}
2024-12-26 16:51:25 +00:00
```
2025-01-26 16:46:11 +00:00
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 >
```
2024-12-26 16:51:25 +00:00
#### Complete Component
This complete component example fetches a test file and displays the contents in a table.
When the export button is clicked, an event handler will export a file:
2025-01-07 16:45:50 +00:00
##### View Implementation {#view-implementation}
2025-01-26 16:46:11 +00:00
2024-12-26 16:51:25 +00:00
```xml title="webapp/view/Main.view.xml"
2025-01-26 16:46:11 +00:00
< 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 >
2024-12-26 16:51:25 +00:00
< / mvc:View >
```
2025-01-26 16:46:11 +00:00
2025-01-07 16:45:50 +00:00
##### Controller Implementation {#controller-implementation}
2025-01-26 16:46:11 +00:00
2024-12-26 16:51:25 +00:00
```js title="webapp/controller/Main.controller.js"
sap.ui.define(
2025-01-26 16:46:11 +00:00
["./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);
/* load data */
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);
},
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");
},
});
}
2024-12-26 16:51:25 +00:00
);
```
< details open >
< summary > < b > How to run the example< / b > (click to hide)< / summary >
:::note Tested Deployments
This demo was tested in the following environments:
2025-01-26 16:46:11 +00:00
| OpenUI5 | Date |
|:----------|------------|
| `1.132.1` | 2025-01-24 |
2024-12-26 16:51:25 +00:00
:::
1) Create a new site:
```bash
2025-01-07 16:45:50 +00:00
npm i --global generator-easy-ui5
2024-12-26 16:51:25 +00:00
npx yo easy-ui5 app
```
2025-01-26 16:46:11 +00:00
When prompted, enter the following options:
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
- `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 >
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
![Expected output ](pathname:///ui5/easy-ui5.png )
2024-12-26 16:51:25 +00:00
2) Install the dependencies and start server:
```bash
cd sheetjs.openui5
npm install
npm start
```
2025-01-26 16:46:11 +00:00
3) Open a web browser and access the displayed URL (`http://localhost:8080`).
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
In the file listing, click `index.html` to launch the app.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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 > `}
2024-12-26 16:51:25 +00:00
< / CodeBlock >
2025-01-26 16:46:11 +00:00
5) Replace `webapp/view/Main.view.xml` with the `Main.view.xml` snippet in the
["View Implementation" section ](#view-implementation ).
6) Replace `webapp/controller/Main.controller.js` with the `Main.controller.js`
example in the ["Controller Implementation" section ](#controller-implementation ).
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
7) Switch back to the browser window.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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:
2024-12-26 16:51:25 +00:00
```bash
2025-01-26 16:46:11 +00:00
npm run build:opt
2024-12-26 16:51:25 +00:00
```
The generated site will be placed in the `dist` folder.
2025-01-26 16:46:11 +00:00
:::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:
2024-12-26 16:51:25 +00:00
```bash
2025-01-26 16:46:11 +00:00
npx http-server dist
2024-12-26 16:51:25 +00:00
```
2025-01-26 16:46:11 +00:00
Access the displayed URL (typically `http://localhost:8080` ) with a web browser
and test the page.
2024-12-26 16:51:25 +00:00
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
will generate a workbook that can be opened in a spreadsheet editor.
< / details >
### HTML
The main disadvantage of the Array of Objects approach is the specific nature
2025-01-26 16:46:11 +00:00
of the columns. For more general use, passing around an Array of Arrays works.
However, this does not handle merge cells[^8] well!
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
The [`sheet_to_html` ](/docs/api/utilities/html#html-table-output ) function
generates HTML that is aware of merges and other worksheet features.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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.
2024-12-26 16:51:25 +00:00
2025-01-07 16:45:50 +00:00
##### View Implementation {#view-implementation-html}
2025-01-26 16:46:11 +00:00
2024-12-26 16:51:25 +00:00
```xml title="webapp/view/Main.view.xml"
2025-01-26 16:46:11 +00:00
< 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 >
2024-12-26 16:51:25 +00:00
< / mvc:View >
```
2025-01-07 16:45:50 +00:00
##### Controller Implementation {#controller-implementation-html}
2025-01-26 16:46:11 +00:00
2024-12-26 16:51:25 +00:00
```js title="webapp/controller/Main.controller.js"
2025-01-26 16:46:11 +00:00
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);
/* load data */
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);
},
onExport: function () {
/* Get reference to the `TABLE` element in the model */
const table = this.getView().byId("tbl").getDomRef();
/* Generate workbook */
const wb = XLSX.utils.table_to_book(table);
/* Export to XLSX */
XLSX.writeFileXLSX(wb, "SheetJSOpenUI5HTML.xlsx");
},
});
}
2024-12-26 16:51:25 +00:00
);
```
< details open >
< summary > < b > How to run the example< / b > (click to hide)< / summary >
:::note Tested Deployments
This demo was tested in the following environments:
2025-01-26 16:46:11 +00:00
| OpenUI5 | Date |
|:----------|------------|
| `1.132.1` | 2025-01-24 |
2024-12-26 16:51:25 +00:00
:::
1) Create a new site:
```bash
2025-01-07 16:45:50 +00:00
npm i --global generator-easy-ui5
2024-12-26 16:51:25 +00:00
npx yo easy-ui5 app
```
2025-01-26 16:46:11 +00:00
When prompted, enter the following options:
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
- `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 >
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
![Expected output ](pathname:///ui5/easy-ui5.png )
2024-12-26 16:51:25 +00:00
2) Install the dependencies and start server:
```bash
cd sheetjs.openui5
npm install
npm start
````
3) Open a web browser and access the displayed URL (`http://localhost:8080`)
2025-01-26 16:46:11 +00:00
In the file listing, click `index.html` to launch the app.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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 > `}
2024-12-26 16:51:25 +00:00
< / CodeBlock >
2025-01-26 16:46:11 +00:00
5) Replace `webapp/view/Main.view.xml` with the `Main.view.xml` snippet in the
["View Implementation" section ](#view-implementation-html ).
6) Replace `webapp/controller/Main.controller.js` with the `Main.controller.js`
example in ["Controller Implementation" ](#controller-implementation-html ).
7) Switch back to the browser window.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
The page will refresh and show a table with an Export button.
2024-12-26 16:51:25 +00:00
2025-01-26 16:46:11 +00:00
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:
2024-12-26 16:51:25 +00:00
```bash
2025-01-26 16:46:11 +00:00
npm run build:opt
2024-12-26 16:51:25 +00:00
```
The generated site will be placed in the `dist` folder.
2025-01-26 16:46:11 +00:00
:::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:
2024-12-26 16:51:25 +00:00
```bash
2025-01-26 16:46:11 +00:00
npx http-server dist
2024-12-26 16:51:25 +00:00
```
2025-01-26 16:46:11 +00:00
Access the displayed URL (typically `http://localhost:8080` ) with a web browser
and test the page.
2024-12-26 16:51:25 +00:00
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
will generate a workbook that can be opened in a spreadsheet editor.
< / details >
2025-01-06 02:51:20 +00:00
[^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.
2025-01-26 16:46:11 +00:00
[^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.