--- title: Oracle Cloud Infrastructure sidebar_label: Oracle Cloud pagination_prev: demos/local/index pagination_next: demos/extensions/index --- import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; [Oracle Cloud Infrastructure](https://www.oracle.com/cloud/) (OCI) is a cloud services platform for building and deploying line of business applications. [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing data from spreadsheets. This demo explores the "Visual Builder Studio" (VBS) environment[^1]. We'll use VBS and SheetJS to build a web application that handles Excel files. In the ["Complete Example"](#complete-example), we'll create an application that imports data from spreadsheet, stores data in "Business Objects"[^2], displays data in table components, and exports Business Objects to new spreadsheets. :::caution pass Oracle Cloud Infrastructure iterates quickly and there is no guarantee that the referenced services will be available in the future. ::: :::note Tested Deployments This demo was last tested on 2025-02-04. ::: ## Visual Applications "Visual Builder Studio", a core Oracle Cloud Infrastructure offering, is a browser-based development environment for creating web applications with drag-and-drop components. ### Installation SheetJS libraries conform to Visual Builder Studio ECMAScript[^5] requirements. They can be loaded in VBS applications at different points in the app lifecycle. #### RequireJS Module {#installation-define} The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) comply with AMD `define` semantics. They support `define` out of the box. *Module Alias* Unlike other platforms, Oracle Visual Builder `define` requires module aliases. Aliases are stored in `app-flow.json`. SheetJS scripts are designed to use the `xlsx` alias. An alias can be added in Visual Builder Studio with the following steps: 1. Click 📄 `Source` from the left sidebar. 2. Expand the `webApps` folder. 3. Expand the subfolder whose name matches the "Application Name" for the site. 4. Open `app-flow.json` within the folder from step 3. 5. Add the following lines after line 5: {`\ "requirejs": { "paths": { "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min" } }, `} *Script Reference* After defining the alias, action chains can load the module using `define`: ```js title="Action Chain Code (loading the SheetJS dependency)" define([ // highlight-next-line "xlsx", /* ... other libraries ... */ 'vb/action/actionChain', 'vb/action/actions' ], ( // highlight-next-line XLSX, /* ... variables for the other libraries ... */ ActionChain, Actions ) => { class MyActionChain extends ActionChain { async run(context) { // highlight-next-line console.log(XLSX.version); // use XLSX in the callback } /* ... other methods ... */ } return MyActionChain; }); ``` #### HTML {#installation-html} [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) can be loaded with a `SCRIPT` tag in the `index.html` entry page for the app. Typically this file is stored in the app folder. For example, if the app is named `sheetjs_demo_app`, the entrypoint HTML file is `webApps/sheetjs_demo_app/index.html`. The script should be added in the `HEAD` block: {`\ `} This will expose the `XLSX` global object, which includes the functions listed in the ["API Reference"](/docs/api/) section of the documentation. :::note pass The Visual Builder scripts are injected at ``. This comment is typically in the `BODY` block: ```html title="index.html (base template)" ``` Adding the SheetJS Standalone script to the `HEAD` block ensures the script will be processed before loading Oracle Visual Builder scripts. ::: ## Business Objects "Business Objects"[^2] in Oracle VBS provides a server-side model implementation for persistent data storage. Think of them as a combination of a data model and database table that handles both data storage and UI binding. ### Business Object Definition The example [presidents sheet](https://docs.sheetjs.com/pres.xlsx) has a header row with "Name" and "Index" columns. In Oracle VBS, we model this as a Business Object with two fields. #### Schema Fields in Business Objects must have a specified type. A sample business object definition for the following schema is shown below: | Field ID | Type | Field Label | |:---------|:---------|:------------| | `name` | `string` | Name | | `index1` | `number` | Index | ```json title="Sample Business Object Definition" { "items" : [ { "name": "Pres", "fields": { "name": { "type": "string", "label": "Name" }, "index1": { "type": "number", "label": "Index" } } } ] } ``` #### Data Actions can query data from the Business Object with REST calls. The `items` property of the response is an array of objects. Fields are identified by Field ID. The field names do not appear in the result.
SpreadsheetQuery Result
![`pres.xlsx` data](pathname:///pres.png) ```json { "items": [ { "name": "Bill Clinton", "index1": 42 }, { "name": "GeorgeW Bush", "index1": 43 }, { "name": "Barack Obama", "index1": 44 }, { "name": "Donald Trump", "index1": 45 }, { "name": "Joseph Biden", "index1": 46 } ] } ```
#### Updating Business Object Starting from a spreadsheet file, the SheetJS [`read`](/docs/api/parse-options) method parses the data into a workbook object. After selecting a worksheet, [`sheet_to_json`](/docs/api/utilities/array#array-output) generates row objects. Using the auto-generated REST API, new Business Object records can be created. Here is a sample flow diagram and method for downloading a workbook, generating rows from the first worksheet, and updating a Business Object[^2]: ```mermaid flowchart LR xlsx[(Remote\nFile)] ab[(Data\nArrayBuffer)] wb(SheetJS\nWorkbook) ws(SheetJS\nWorksheet) json(JSON\nData) bo[(Business\nObject)] xlsx --> |fetch\n\n| ab ab --> |`read`\n\n| wb wb --> |wb.Sheets\nselect| ws ws --> |`sheet_to_json`\n\n| json json --> |REST API\ncreate| bo linkStyle 1,2,3 color:blue,stroke:blue; ``` {`\ define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => { class ButtonActionChain extends ActionChain { async run(context) { /* fetch spreadsheet file */ const url = "https://docs.sheetjs.com/pres.xlsx"; const data = await (await fetch(url)).arrayBuffer(); /* parse */ const wb = XLSX.read(data); /* convert the first worksheet to json */ const ws = wb.Sheets[wb.SheetNames[0]]; const jsonData = XLSX.utils.sheet_to_json(ws); for (const row of jsonData) { // loop over data rows /* create object that follows business object definition */ const presData = { name: row.Name, index1: Number(row.Index) }; /* update business object with new record */ await Actions.callRest(context, { endpoint: 'businessObjects/create_Pres', body: presData }); } } } return ButtonActionChain; }); `} #### Rendering Data In Oracle VBS, the table component `oj-table`[^4] supports direct binding to Business Objects for data display. The view structure specifies the data source binding and column layout. When using the design mode to add a Table, VBS will use a `ServiceDataProvider` with columns based on the specified Endpoint Structure. The following view code was generated when testing the ["Complete Example"](#complete-example): {`\
// highlight-start // highlight-end
`}
#### Exporting Business Objects The export functionality converts Business Object data into an Excel spreadsheet. The process involves retrieving data through REST API call, transforming it into a format suitable for SheetJS, and generating an XLSX file. Here's the complete flow: ```mermaid flowchart LR bo[(Business\nObject)] rest(REST API\nCall) json(JSON\nArray) ws(SheetJS\nWorksheet) wb(SheetJS\nWorkbook) xlsx[(XLSX\nFile)] bo --> |getall_Pres\nendpoint| rest rest --> |transform\nresponse| json json --> |json_to_sheet\n\n| ws ws --> |book_new\n\n| wb wb --> |writeFileXLSX\n\n| xlsx linkStyle 2,3,4 color:blue,stroke:blue; ``` {`\ define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => { class ButtonActionChain1 extends ActionChain { async run(context) { // get pres data const presDataResponse = await Actions.callRest(context, { endpoint: 'businessObjects/getall_Pres', parameters: { fields: 'name,index1' } }); // transform to simple array const simplifiedData = presDataResponse.body.items.map(item => ({ Name: item.name, Index: item.index1 })); // generate workbook const ws = XLSX.utils.json_to_sheet(simplifiedData); const wb = XLSX.utils.book_new(ws, "Presidents"); // export to XLSX which triggers a download XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx"); } } return ButtonActionChain1; });`} ### Importing Data {#importing-data-snippet} The import functionality enables data transfer from an Excel spreadsheet into the Oracle VBS application. The process begins by fetching the XLSX file, parsing it using SheetJS, and then creating corresponding Business Object records. ```js title="Importing Data code" define([ 'vb/action/actionChain', 'vb/action/actions', 'vb/action/actionUtils', 'xlsx' ], ( ActionChain, Actions, ActionUtils, XLSX ) => { 'use strict'; class ButtonActionChain extends ActionChain { /** * @param {Object} context */ async run(context) { const { $page, $flow, $application, $constants, $variables } = context; // fetch XLSX file const url = "https://docs.sheetjs.com/pres.xlsx"; const data = await (await fetch(url)).arrayBuffer(); const wb = XLSX.read(data); // get the first worksheet const ws = wb.Sheets[wb.SheetNames[0]]; // convert to json const jsonData = XLSX.utils.sheet_to_json(ws); // process each row and create business object records for (const row of jsonData) { const presData = { name: row.Name, index1: Number(row.Index) }; // create a business object record await Actions.callRest(context, { endpoint: 'businessObjects/create_Pres', body: presData }); } } } return ButtonActionChain; }); ``` ### Exporting Data {#exporting-data-snippet} The export functionality allows you to convert Business Object data into Excel spreadsheets. This process involves retrieving data from the Business Object using REST API calls, transforming it into a format suitable for SheetJS, and generating an XLSX file. ```js title="Exporting Data code" define([ 'vb/action/actionChain', 'vb/action/actions', 'vb/action/actionUtils', 'xlsx' ], ( ActionChain, Actions, ActionUtils, XLSX ) => { 'use strict'; class ButtonActionChain1 extends ActionChain { /** * @param {Object} context */ async run(context) { const { $page, $flow, $application, $constants, $variables } = context; // get pres data const presDataResponse = await Actions.callRest(context, { endpoint: 'businessObjects/getall_Pres', parameters: { fields: 'name,index1' } }); // transform to simple array const simplifiedData = presDataResponse.body.items.map(item => ({ Name: item.name, Index: item.index1 })); // generate workbook const ws = XLSX.utils.json_to_sheet(simplifiedData); const wb = XLSX.utils.book_new(ws, "Presidents"); /* export to XLSX */ XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx"); } } return ButtonActionChain1; }); ``` ## Complete Example :::note pass At the time of writing, Oracle Cloud offers a 30-day free trial that includes Visual Builder Studio access. ::: 0. If you do not have one, create a new Oracle Cloud free tier account[^3]. 1. Sign in to the [Oracle Cloud Management Console](https://cloud.oracle.com/). ### Visual Builder Setup :::note pass In this section, we will configure VBS and create a new instance. ::: 2. Type "Visual Builder Studio" in the top search box and click "Visual Builder Studio" in the "Services" section. ![Oracle Cloud search for "Visual Builder Studio"](pathname:///oraclecloud/search_box_visual_builder.png) 3. Click `Visual Builder` in the left sidebar. In the "List scope" section, if no Compartment is selected, click the dropdown and select a Compartment. !["Visual Builder" create instance](pathname:///oraclecloud/create_new_instance.png) 4. Click "Create Instance". In the Create Instance panel, enter the following options: - Name: `sheetjs-demo-vb-instance` - Nodes: `1` (it cannot be changed in a Free account) - Choose network access: `Default (No access rules.)` The panel should look like the following screenshot: ![Create Visual Builder Instance](pathname:///oraclecloud/create_vb_instance.png) 5. Click "Create Visual Builder Instance". The panel will close. The instances table will include a new row for `sheetjs-demo-vb-instance`. When the instance is ready, the status will change to "ACTIVE". ![Instance is ready](pathname:///oraclecloud/instances_table_ready.png) 6. Click "Visual Builder Studio" in the left sidebar. 7. Click "Create Visual Builder Studio" in the main area. In the Create Visual Builder Studio Instance panel, type `sheetjs-vbs-instance` in the Instance Name textbox and click "Next" In the "CI/CD Setup" page, ensure "Yes, I authorize this" is checked. Select the compartment in the dropdown and click `Create Visual Builder Studio`. You will be redirected to the instance page. 8. Wait for the instance to be completed. The large circle will be green. ![VBS Instance is ready](pathname:///oraclecloud/instance_green.png) 9. Click `Service Console`. You will be redirected to the organization page. 10. Scroll down and select the "Projects" tab. Click the "+ Create" button to create a new project. The "New Project" wizard has 4 steps: - In "Project Details", enter the Name `sheetjs-demo-project` and click "Next" - In "Project Template", select `Empty Project` and click "Next" - In "Project Properties" page, select `Markdown` and click "Next" - Click "Finish" (by default, the current user will be the "Project Owner") You will be redirected to a provisioning page while resources are allocated: ![Provisioning page](pathname:///oraclecloud/provisioning.png) Once allocated, you will be redirected to the project page. 11. Click "⌂ Project Home" in the left sidebar and click "+ Create Environment". In the popup, type `sheetjs-demo-env` in the "Environment Name" text box and click "Create". You will be redirected to the Environments page. 12. Click `+ Add Instance`. In the modal, select the following: - Instance Type: "Visual Builder and Oracle Integration" - Add Instance Using: "Instance List" - Check the box in the `sheetjs-demo-vb-instance` table row. The selections should match the following screenshot: ![Connect instance to environment](pathname:///oraclecloud/env_connect_to_instance.png) After making the selections, click "Add". Once the instance is created, there will be a checkmark next to `sheetjs-demo-env` in the main area. ![Instance created](pathname:///oraclecloud/instance_created.png) 13. Select the "Service Instances" tab and find the `sheetjs-demo-vb-instance` card. If "Instance URL" is not shown, click "Details" to show the URL. ![Environment card](pathname:///oraclecloud/env_card.png) Click the "Instance URL". Visual Builder will be launched in a new window. 14. Click "+ New Application". In the popup, enter the following options: - Application Display Name: `sheetjs-vbs-demo` - Application Name: `sheetjs_vbs_demo` (automatic) - Application Template: `Empty Application` (default) Click "Finish". After a short wait, the browser will redirect to the new app. ### Business Object Setup :::note pass In this section, we will create a new Business Object. ::: 15. Click the **Business Objects** card in the Welcome tab or the "**⛁**" icon in the left sidebar. The "Business Objects" panel will be displayed. ![Create a new Business Object](pathname:///oraclecloud/create_business_object.png) Click "+ Business Object". In the popup, enter the following: - Name: `Pres` - Display Label: `President` Click "Create". You will be redirected to the Business Object page. 16. Select `Pres` in the Business Objects panel and select the "Fields" tab. ![Business Object - Fields](pathname:///oraclecloud/business_object_fields.png) 17. Click "+ Field" and select "Field" in the dropdown. In the displayed form, enter the following options: - Label: `Name` - Type: Click `A` (`String` will be displayed next to Type) Click "Create Field". 18. Click "+ Field" and select "Field" in the dropdown. In the displayed form, enter the following options: (we are creating a second field) - Label: `Index` - Type: Click `#` (`Number` will be displayed next to Type) Click "Create Field". 19. Scan the main table and verify that two new rows were added: ![Add two new fields](pathname:///oraclecloud/creating_new_fields_name_index.png) ### Web App Creation :::note pass In this section, we will create a new web application. ::: 20. Click "🖥️ Web Applications" in the left bar and click "+ Web Application". In the popup, enter the following options: - Application Name: `sheetjs_demo_app` - Navigation Style: `None` Click "Create". You will be redirected to the page designer. :::note pass If prompted to share clipboard, select "Allow". ::: ### SheetJS Alias :::note pass In this section, we will create an alias to the SheetJS standalone script hosted on the [SheetJS CDN](/docs/getting-started/installation/standalone) ::: 21. Click 📄 `Source` from the left sidebar. 22. In the file tree, if `app-flow.json` is not visible, click the triangle next to `sheetjs_demo_app` to expand the folder. :::caution pass Clicking on the `sheetjs_demo_app` name has no effect! You must click the triangle next to the label to expand the folder. ::: 23. Select `app-flow.json` within the `sheetjs_demo_app` folder. A new code window will be displayed in the main area. 24. Copy the following codeblock and insert it after line 5 in the code editor: {`\ "requirejs": { "paths": { "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min" } }, `} The following screenshot shows the result after inserting the code: ![Adding Sheetjs to the web application](pathname:///oraclecloud/adding_sheetjs_to_app.png) ### App Interface :::note pass In this section, we will create the UI for the application. It will include two buttons for import/export and a table for displaying data. ::: 25. Click "🖥️ Web Applications" in the left sidebar. 26. In the tree, if `main-start` is not visible, click the triangle next to `main` to expand the folder. :::caution pass Clicking on the `main` name does not expand the tree! You must click the triangle next to the label to expand the subtree. ::: 27. Select `main-start` within the `main` section. 28. Select the "Page Designer" tab and select the "Design" tab. In the page designer, drag and drop two `Button` components and one `Table` Component to the canvas. :::caution pass The "Table" component is in the "Collections" section. Do not add a "Dynamic Table"! ::: ![Drag and drop UI components to canvas](pathname:///oraclecloud/drag_drop_components_to_canvas.png) ### Actions Setup :::note pass In this section, we will add event handlers for the import and export buttons. ::: 29. Select the first button in the canvas. 30. In the right panel, select the "General" tab. Enter the following details: - ID: `import-xlsx` - Label: `Import XLSX` Press Enter after typing the label. The canvas will refresh. 31. Select the "Events" tab and click "+ Event Listener". In the dropdown, click `🔔 On 'ojAction'`. 32. Click "Action Chains" in the top bar (next to "Page Designer"). 33. Select "Code" in the top-right tab. ![Switch from Design to Code in Action Chains for the button](pathname:///oraclecloud/action_chain_select_code.png) The main area will show a code editor. 34. Copy the ["Importing Data code"](#importing-data-snippet) example code and paste in the code editor. 35. Click "Page Designer" to return to the page designer. 36. Select the second button in the canvas (not the "Import XLSX" button!) 37. In the right panel, select the "General" tab. Enter the following details: - ID: `export-xlsx` - Label: `Import XLSX` Press Enter after typing the label. The canvas will refresh. 38. Select the "Events" tab and click "+ Event Listener". In the dropdown, click `🔔 On 'ojAction'`. 39. Click "Action Chains" in the top bar (next to "Page Designer"). 40. Select "Code" in the top-right tab. 41. Copy the ["Exporting Data code"](#exporting-data-snippet) example code and paste in the code editor. ### Data Binding :::note pass In this section, we will connect the `Pres` Business object to the Table. ::: 42. Click "Page Designer" to return to the page designer. 43. Select the Table component in the canvas. 44. In the right panel, select the "Quick Start" tab and click "Add Data". ![Connecting Business Object Pres to the table](pathname:///oraclecloud/connecting_business_object.png) 45. Complete the "Add Data" wizard: - In "Choose the source of your data", select "Pres" in the "Business Objects" section and click "Next". - In the next section ("Bind Data"), check the box next to `name` and the box next to `index1`. After confirming the page looks like the following screenshot, click "Next". ![Bind columns to field name and index1](pathname:///oraclecloud/bind_columns_to_fields_name_index1.png) - In the next section ("Define Query") click "Finish". ### App Testing :::note pass In this section, we will test import and export functionality. ::: 46. Click the Preview button (▶️ icon) in the top-right corner of the page. The application will be launched in a new browser tab. 47. Click "Import XLSX". 48. Switch back to the Visual Builder window. 49. Click the "⛁" icon in the left sidebar and click the "Pres" Business Object. 50. Switch to the "Data" tab and verify that new data has been added. :::caution pass In some test runs, no data was added. Repeat the ["SheetJS Alias"](#sheetjs-alias) steps and confirm the alias exists. If the alias is missing, add the alias and launch a new Preview window. ::: ![Expected data for Pres Business Object](pathname:///oraclecloud/pres_data.png) 51. Switch back to the "Preview" window and refresh the page. The preview will now show the data from the "Pres" Business Object. ![Preview of Pres Business Object](pathname:///oraclecloud/pres_preview.png) 52. Click the "Export XLSX" button. The app will attempt to download `SheetJSOracleVisualBuilderAoO.xlsx` Save the file and open with a spreadsheet editor. Confirm the spreadsheet matches the data shown in the app. [^1]: See ["Oracle Visual Builder Studio"](https://docs.oracle.com/en/cloud/paas/visual-builder/) in the Oracle Cloud documentation. [^2]: See ["Work With Business Objects"](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/working-business-objects1.html) in the Oracle Visual Build Studio documentation. [^3]: Registering for a free account [on the Oracle Cloud Free Tier](https://www.oracle.com/cloud/free/) requires a valid phone number and a valid credit card. [^4]: See [Oracle VBS Table Component](https://docs.oracle.com/en/middleware/developer-tools/jet/13/reference-api/oj.ojTable.html) for more details. [^5]: See ["JavaScript Support in Oracle VBS"](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/work-javascript-editor1.html?utm_source=chatgpt.com) for more details on custom JavaScript functionality and module handling.