docs.sheetjs.com/docz/docs/03-demos/30-cloud/01-salesforce.md

744 lines
22 KiB
Markdown
Raw Normal View History

2022-06-27 02:05:36 +00:00
---
2022-08-24 00:51:18 +00:00
title: Salesforce LWC
2023-02-28 11:40:44 +00:00
pagination_prev: demos/local/index
pagination_next: demos/extensions/index
2022-06-27 02:05:36 +00:00
---
2023-05-03 03:40:40 +00:00
import current from '/version.js';
2023-10-02 04:57:11 +00:00
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
2023-05-03 03:40:40 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-10-02 04:57:11 +00:00
[Salesforce](https://www.salesforce.com/) is a suite of cloud-based software
systems for Customer Relationship Management (CRM). "Lightning Web Components"
(LWC) is a robust JavaScript extension platform available to Salesforce apps[^1].
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo explores the LWC scripting features in Salesforce. We'll explore how
to install SheetJS scripts in Lightning Web Components and build a sample app
for exporting lists to XLSX workbooks.
2022-06-27 02:05:36 +00:00
2023-09-24 03:59:48 +00:00
:::caution pass
2022-06-27 02:05:36 +00:00
Salesforce may change the platform in backwards-incompatible ways, so the demo
may require some adjustments. The official documentation should be consulted.
:::
2023-11-30 07:10:37 +00:00
:::note Tested Deployments
2023-04-09 21:13:24 +00:00
2024-10-07 21:41:19 +00:00
This demo was last tested on 2024 October 06 using Lightning API version `61.0`.
2023-04-09 21:13:24 +00:00
:::
:::danger Telemetry
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
The Salesforce developer tools embed telemetry. It can be disabled by setting
2024-10-07 21:41:19 +00:00
the environment variable `SF_DISABLE_TELEMETRY` to `true` or running a command:
2022-06-27 02:05:36 +00:00
```bash
2023-10-02 04:57:11 +00:00
npx @salesforce/cli config set disable-telemetry=true --global
2022-06-27 02:05:36 +00:00
```
2023-10-02 04:57:11 +00:00
:::
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
## Integration Details
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
Lightning Web Components can load scripts stored in static resources.
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
### Installation
2022-06-27 02:05:36 +00:00
2023-09-22 06:32:55 +00:00
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
can be downloaded and added as a static resource.
2023-10-02 04:57:11 +00:00
:::info pass
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
Due to Salesforce name restrictions, the script must be renamed to `sheetjs.js`.
2022-06-27 02:05:36 +00:00
:::
2024-10-07 21:41:19 +00:00
:::caution Lightning Web Security Performance Degradation
There are known performance regressions with the new Lightning Web Security.
SheetJS users have reported that sub-second exports using the older Lightning
Locker Service will take over 20 seconds using the new system.
**This is a bug in Salesforce Lightning Web Security!**
Until Salesforce fixes the bug, it is strongly recommended to disable the broken
"Lightning Web Security" and use the battle-tested "Lightning Locker Service":
0) Switch to the Salesforce Classic view.
If a profile icon appears in the top-right corner of the Salesforce page, click
on the icon and select "Switch to Salesforce Classic" in the popover menu:
![Switch to Salesforce Classic](pathname:///salesforce/l2c.png)
1) Click the "Setup" link in the right side of the top bar.
2) In the "Quick Find" box, type "Session" and select "Session Settings".
3) Scroll down to "Lightning Web Security" and uncheck the box next to
> Use Lightning Web Security for Lightning web components and Aura components
![Disable Lightning Web Security](pathname:///salesforce/lws.png)
4) Scroll down to the bottom of the page and click "Save".
:::
2023-10-02 04:57:11 +00:00
### Loading SheetJS
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
Assuming the script was renamed to `sheetjs.js`, the name of the resource will
be `sheetjs`. `async` functions can use `loadScript` to fetch and load the
library. The script will define the variable `XLSX`[^2]
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
It is recommended to load the library in a callback. For example, the following
`@api` method loads the library and exports sample data to a spreadsheet file:
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
```js title="Sample LWC component to export a sample dataset"
2023-10-02 04:57:11 +00:00
import { LightningElement, api } from 'lwc';
2022-06-27 02:05:36 +00:00
import { loadScript } from 'lightning/platformResourceLoader';
2023-11-30 07:10:37 +00:00
// highlight-next-line
2022-06-27 02:05:36 +00:00
import sheetjs from '@salesforce/resourceUrl/sheetjs';
export default class SheetComponent extends LightningElement {
2023-10-02 04:57:11 +00:00
@api async download() {
2024-10-07 21:41:19 +00:00
// highlight-next-line
2022-06-27 02:05:36 +00:00
await loadScript(this, sheetjs); // load the library
// At this point, the library is accessible with the `XLSX` variable
2024-10-07 21:41:19 +00:00
/* Create worksheet */
2023-10-02 04:57:11 +00:00
var ws = XLSX.utils.aoa_to_sheet([
[ "S", "h", "e", "e", "t", "J"," S" ],
[ 5 , 4 , 3 , 3 , 7 , 9 , 5 ]
]);
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
/* Create workbook and add worksheet */
2023-10-02 04:57:11 +00:00
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Data");
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
/* Export data and attempt to download a XLSX workbook */
2023-10-02 04:57:11 +00:00
XLSX.writeFile(wb, "SheetForceExport.xlsx");
}
}
```
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
### Exporting Data from SF List
2022-06-27 02:05:36 +00:00
2023-11-30 07:10:37 +00:00
Using the LWC Wire Service, components receive data in separate events.[^3]
Event handlers typically store the updated data in component state, ensuring the
data is available when a spreadsheet export is requested.
2022-06-27 02:05:36 +00:00
#### Getting Account Data
2023-11-30 07:10:37 +00:00
This demo uses the deprecated `getListUi` function[^4] to pull account data.
`getListUi` requires the name of the LWC object (`objectApiName` property) and
name of the LWC list view (`listViewApiName` property)
The following snippet receives data from the "All Accounts" list view:
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
```js title="Pulling Account data using the LWC Wire Service (sketch)"
2023-10-02 04:57:11 +00:00
import { LightningElement, wire } from 'lwc';
2022-06-27 02:05:36 +00:00
import { getListUi } from 'lightning/uiListApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
// ...
export default class SheetComponent extends LightningElement {
@wire(getListUi, {
objectApiName: ACCOUNT_OBJECT.objectApiName,
listViewApiName: 'AllAccounts'
}) listInfo({ error, data }) {
// LIST DATA AVAILABLE HERE
};
// ...
}
```
2023-10-02 04:57:11 +00:00
#### Array of Arrays
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
SheetJS most reliably translates "arrays of arrays"[^5], a nested array which
directly maps to individual cell addresses.
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
For example, using the Accounts list, each row represents one account. Each
column represents the account name, phone number, or another field.
```js title="Sample Array of Arrays based on Account info"
var aoa = [
["Name", "Phone"], // row 1 -- column titles
["Mike Jones", "(281) 330-8004"], // row 2 -- first data row
["Jenny Sheets", "(201) 867-5309"] // row 3 -- second data row
2022-06-27 02:05:36 +00:00
];
```
2024-10-07 21:41:19 +00:00
The APIs typically return nested objects, so the array of arrays must be
manually constructed by iterating over the data.
:::tip pass
The ["Export Tutorial"](/docs/getting-started/examples/export) covers JavaScript
array methods and transformation in more detail.
:::
2022-06-27 02:05:36 +00:00
<details>
<summary><b>Salesforce Representation</b> (click to show)</summary>
2022-06-27 02:05:36 +00:00
The `data` parameter in the callback has a deep structure. Typically one would
set a property in the component and display data in a template:
2024-10-07 21:41:19 +00:00
```js title="Storing records in LWC Component state (sketch)"
2022-06-27 02:05:36 +00:00
// ...
// declare records variable in the component
records;
@wire(getListUi, {
objectApiName: ACCOUNT_OBJECT.objectApiName,
listViewApiName: 'AllAccounts'
}) listInfo({ error, data }) {
if (data) {
// data.records.records is the array of interest
this.records = data.records.records;
this.error = undefined;
}
}
// ...
```
The template itself would iterate across the records:
2024-10-07 21:41:19 +00:00
```html title="Generating HTML Tables in a LWC Template"
2022-06-27 02:05:36 +00:00
<template>
<template if:true={records}>
<table>
<tr><th>Name</th><th>Phone</th></tr>
<template for:each={records} for:item="record">
<tr key={record.fields.Id.value}>
<td>{record.fields.Name.value}</td>
<td>{record.fields.Phone.value}</td>
</tr>
</template>
</table>
</template>
</template>
```
</details>
A suitable SheetJS array of arrays can be constructed by mapping across records:
2024-10-07 21:41:19 +00:00
```js title="Constructing an array of arrays from Salesforce data (snippet)"
var headers = [ "Name", "Phone" ]; // First row of the spreadsheet
2023-10-02 04:57:11 +00:00
var aoa = [headers].concat(data.records.records.map(record => [
2022-06-27 02:05:36 +00:00
record.fields.Name.value, // Name field
record.fields.Phone.value, // Phone field
]));
```
2023-10-02 04:57:11 +00:00
#### State
This data is available in a wire service callback, but it is common to export
the data in a separate API event. This flow is handled with a state variable:
```js
export default class SheetComponent extends LightningElement {
// highlight-next-line
aoa; // will hold data for export
@wire(getListUi, {
objectApiName: ACCOUNT_OBJECT.objectApiName,
listViewApiName: 'AllAccounts'
}) listInfo({ error, data }) {
if (data) {
var headers = [ "Name", "Phone" ];
// create AOA
var _aoa = [headers].concat(data.records.records.map(record => [
record.fields.Name.value, // Name field
record.fields.Phone.value, // Phone field
]));
// assign to state
// highlight-next-line
this.aoa = _aoa;
} else if (error) console.log(error);
};
}
```
#### Exporting Data
2024-10-07 21:41:19 +00:00
Data is readily exported to a spreadsheet in a callback function. Starting from
the array of arrays, the SheetJS `aoa_to_sheet` method[^6] generates a SheetJS
sheet object[^7]. A workbook object[^8] is created with `book_new`[^9] and the
sheet is added with `book_append_sheet`[^10]. Finally, the SheetJS `writeFile`
method creates a XLSX file and initiates a download[^11].
2022-06-27 02:05:36 +00:00
```js
@api async download() {
await loadScript(this, sheetjs); // load the library
2023-10-02 04:57:11 +00:00
// get data from state
// highlight-next-line
var _aoa = this.aoa;
2022-06-27 02:05:36 +00:00
// create workbook
var wb = XLSX.utils.book_new();
2023-10-02 04:57:11 +00:00
var ws = XLSX.utils.aoa_to_sheet(_aoa);
2022-06-27 02:05:36 +00:00
XLSX.utils.book_append_sheet(wb, ws, "Data");
2023-10-02 04:57:11 +00:00
2022-06-27 02:05:36 +00:00
// export
XLSX.writeFile(wb, "SheetForceExport.xlsx");
};
```
2023-10-02 04:57:11 +00:00
## Complete Example
:::info pass
This demo was built on a "Developer Edition" account. At the time of writing, an
[account can be created for free.](https://developer.salesforce.com/signup)
:::
0) Create a "Developer Edition" account. Take note of the unique Username
### Configure Tools
1) Install [NodeJS LTS](https://nodejs.org/en/download).
2) Disable telemetry:
```bash
npx @salesforce/cli config set disable-telemetry=true --global
```
3) Confirm the CLI tool works by checking version information:
```bash
npx @salesforce/cli --version
```
:::note pass
When the demo was last tested, the command printed
```
2024-10-07 21:41:19 +00:00
@salesforce/cli/2.60.13 darwin-arm64 node-v20.18.0
2023-10-02 04:57:11 +00:00
```
:::
4) Log into the org from the CLI tool:
```bash
npx @salesforce/cli org login web
```
This will open a web browser. Sign in and authorize the application.
### Create Project
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
5) Create the "SheetForce" sample project with the `project generate` command:
```bash
npx @salesforce/cli project generate -n SheetForce
```
Enter the project directory:
```bash
cd SheetForce
```
6) Create a LWC component with the `lightning generate component` command:
```bash
npx @salesforce/cli lightning generate component --type lwc -n sheetComponent -d force-app/main/default/lwc
```
7) Replace `force-app\main\default\lwc\sheetComponent\sheetComponent.html` with
the following template code:
2024-05-05 16:07:09 +00:00
```html title="force-app\main\default\lwc\sheetComponent\sheetComponent.html (add highlighted lines)"
2023-10-02 04:57:11 +00:00
<template>
<!-- highlight-next-line -->
<b>SheetForce demo</b>
</template>
```
8) Replace `force-app\main\default\lwc\sheetComponent\sheetComponent.js-meta.xml`
with the following XML:
2024-05-05 16:07:09 +00:00
```xml title="force-app\main\default\lwc\sheetComponent\sheetComponent.js-meta.xml (replace highlighted lines)"
2023-10-02 04:57:11 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
2024-10-07 21:41:19 +00:00
<apiVersion>61.0</apiVersion>
2023-10-02 04:57:11 +00:00
<!-- highlight-start -->
<isExposed>true</isExposed>
<masterLabel>SheetForce</masterLabel>
<description>SheetJS Demo</description>
<targets>
<target>lightning__AppPage</target>
</targets>
<!-- highlight-end -->
</LightningComponentBundle>
```
### Deploy Sample Project
2024-05-05 16:07:09 +00:00
9) Deploy the project from the CLI. You will need the Salesforce unique
2023-10-02 04:57:11 +00:00
Username. For example, if the Username was `SF@USER.NAME`, the command is:
```bash
npx @salesforce/cli project deploy start -d force-app -o SF@USER.NAME
```
2024-05-05 16:07:09 +00:00
10) Find the new component:
2023-10-02 04:57:11 +00:00
<Tabs groupId="sfview">
<TabItem value="nuevo" label="Lightning Experience">
To find the new component in "Lightning Experience" view:
A) In the Salesforce site, click on the gear icon in the top-right corner of the
page and select "Setup" (Setup for current app).
B) Type "Custom Code" in the left sidebar search box. Expand "Custom Code",
expand "Lightning Components" and click "Lightning Components".
:::caution pass
With certain security settings, Salesforce will show an error:
> We can't display this page because your browser blocks cross-domain cookies, but you can view this page in Salesforce Classic.
Click the link to open the page in Salesforce Classic.
:::
</TabItem>
<TabItem value="classique" label="Classic">
A) Click the "Setup" link in the top-right corner of the page.
B) Type "Lightning" in the left sidebar search box. Expand "Develop", expand
"Lightning Components" and click "Lightning Components".
</TabItem>
</Tabs>
The page in Salesforce Classic will look like the screenshot below:
![Custom Component](pathname:///salesforce/custcomp.png)
### Initialize App Page
#### Create App Page
2024-05-05 16:07:09 +00:00
11) Create an "App Page" in the "Lightning App Builder":
2023-10-02 04:57:11 +00:00
<Tabs groupId="sfview">
<TabItem value="nuevo" label="Lightning Experience">
A) In the Salesforce site, click on the gear icon in the top-right corner of the
page and select "Setup" (Setup for current app).
B) Type "App Build" in the left sidebar search box. Expand "User Interface" and
click "Lightning App Builder".
:::caution pass
With certain security settings, Salesforce will show an error:
> We can't display this page because your browser blocks cross-domain cookies, but you can view this page in Salesforce Classic.
Click the link to open the page in Salesforce Classic.
:::
C) Click the "New" button.
</TabItem>
<TabItem value="classique" label="Classic">
A) Click the "Setup" link in the top-right corner of the page.
B) Type "App Build" in the left search box and select "Lightning App Builder".
C) Click the "New" button.
</TabItem>
</Tabs>
#### App Wizard
D) Select "App Page" in the left list and click "Next"
E) Type "SheetJS Demo" in the Label textbox and click "Next"
F) Select "One Region" in the left list and click "Done"
#### App Builder
2024-05-05 16:07:09 +00:00
12) Add the "SheetForce" component to the App Page.
2023-10-02 04:57:11 +00:00
In the left "Components" sidebar, under the "Custom" section, there should be a
"SheetForce" entry.
Click and drag "SheetForce" into the "Add Component(s) Here" frame in the app
builder main view to add it to the page.
Click "Save".
2024-05-05 16:07:09 +00:00
13) Activate the page.
2023-10-02 04:57:11 +00:00
When the "Page Saved" modal is displayed, click "Activate".
The following options should be set:
- Click "Change..." next to "Icon" and pick a memorable icon
- Under "Lightning Experience" click "LightningBolt" then "Add page to app"
Click "Save" to activate the page.
2024-05-05 16:07:09 +00:00
14) Open the demo page.
2023-10-02 04:57:11 +00:00
Click the left arrow in the top-left corner of the page to return to Setup.
If there is a "Switch to Lightning Experience" at the top, click the link.
Click the App Launcher (`᎒᎒᎒`) and search for "SheetJS". Under "Items", the new
"SheetJS Demo" will be listed, Click "SheetJS Demo".
The app will display the "SheetForce demo" text from the component template:
![Demo](pathname:///salesforce/initial.png)
### Add SheetJS
2024-05-05 16:07:09 +00:00
<ol start="15"><li><p>Download <a href={"https://cdn.sheetjs.com/xlsx-" + current + "/package/dist/xlsx.full.min.js"}>{"https://cdn.sheetjs.com/xlsx-" + current + "/package/dist/xlsx.full.min.js"}</a></p></li></ol>
2023-10-02 04:57:11 +00:00
:::danger pass
2023-10-02 04:57:11 +00:00
**DO NOT "COPY AND PASTE"!** The file should be explicitly downloaded. Copying
and pasting corrupts the source code and the component will fail in subtle ways.
The easiest approach is to right-click the link and select "Save Link As..."
:::
The following command can be run in PowerShell or `bash`:
<CodeBlock language="bash">{`\
curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
</CodeBlock>
2024-05-05 16:07:09 +00:00
16) Move the file to the `force-app/main/default/staticresources/` folder and
2023-10-02 04:57:11 +00:00
rename the file to `sheetjs.js`.
If the file was downloaded from the previous command, `mv` can move and rename:
```bash
mv xlsx.full.min.js force-app/main/default/staticresources/sheetjs.js
```
2024-05-05 16:07:09 +00:00
17) Create `force-app/main/default/staticresources/sheetjs.resource-meta.xml`
2023-10-02 04:57:11 +00:00
(`sheetjs.resource-meta.xml` in the folder from step 2) with the following XML:
```xml title="force-app/main/default/staticresources/sheetjs.resource-meta.xml"
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
<cacheControl>Private</cacheControl>
<contentType>application/javascript</contentType>
</StaticResource>
```
2024-10-07 21:41:19 +00:00
18) Deploy the project again with the same command from step 9:
2023-10-02 04:57:11 +00:00
```bash
npx @salesforce/cli project deploy start -d force-app -o SF@USER.NAME
```
2024-10-07 21:41:19 +00:00
Replace `SF@USER.NAME` with the unique Username.
2024-05-05 16:07:09 +00:00
19) Look for the static resource:
2023-10-02 04:57:11 +00:00
<Tabs groupId="sfview">
<TabItem value="nuevo" label="Lightning Experience">
A) In the Salesforce site, click on the gear icon in the top-right corner of the
page and select "Setup" (Setup for current app).
B) Type "Static" in the left sidebar search box. Click "Static Resources"
:::caution pass
With certain security settings, Salesforce will show an error:
> We can't display this page because your browser blocks cross-domain cookies, but you can view this page in Salesforce Classic.
Click the link to open the page in Salesforce Classic.
:::
</TabItem>
<TabItem value="classique" label="Classic">
A) Click the "Setup" link in the top-right corner of the page.
B) Type "Static" in the left sidebar search box. Click "Static Resources"
</TabItem>
</Tabs>
The page in Salesforce Classic will look like the screenshot below:
![Static Resources](pathname:///salesforce/static.png)
### Test the Static Resource
2024-05-05 16:07:09 +00:00
20) Replace `force-app/main/default/lwc/sheetComponent/sheetComponent.js` with
2023-10-02 04:57:11 +00:00
the following script:
2024-05-05 16:07:09 +00:00
```js title="force-app/main/default/lwc/sheetComponent/sheetComponent.js (replace script)"
2023-10-02 04:57:11 +00:00
import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import sheetjs from '@salesforce/resourceUrl/sheetjs';
export default class SheetComponent extends LightningElement {
version = "???"; // start with ???
async connectedCallback() {
await loadScript(this, sheetjs); // load the library
// At this point, the library is accessible with the `XLSX` variable
this.version = XLSX.version;
}
}
```
This component exposes a `version` property based on the SheetJS version.
2024-05-05 16:07:09 +00:00
21) Replace `force-app/main/default/lwc/sheetComponent/sheetComponent.html` with
2023-10-02 04:57:11 +00:00
the following template:
2024-10-07 21:41:19 +00:00
```html title="force-app/main/default/lwc/sheetComponent/sheetComponent.html (replace line)"
2023-10-02 04:57:11 +00:00
<template>
<!-- highlight-next-line -->
<b>SheetForce {version}</b>
</template>
```
This template references the `version` property.
2024-10-07 21:41:19 +00:00
22) Deploy the project again with the same command from step 9:
2023-10-02 04:57:11 +00:00
```bash
npx @salesforce/cli project deploy start -d force-app -o SF@USER.NAME
```
2024-10-07 21:41:19 +00:00
Replace `SF@USER.NAME` with the unique Username.
2024-05-05 16:07:09 +00:00
23) Reload the "SheetJS Demo" page. The page should display the SheetJS version:
2023-10-02 04:57:11 +00:00
![Version number](pathname:///salesforce/version.png)
:::info pass
It may take a few minutes for Salesforce to refresh. If the demo still shows the
original "SheetForce demo" text after refreshing, close and reopen the demo app.
:::
### Export Data from SF Lists
2024-05-05 16:07:09 +00:00
24) Add a button to `sheetComponent.html` that will call a `download` callback:
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
```html title="force-app/main/default/lwc/sheetComponent/sheetComponent.html (replace page)"
2022-06-27 02:05:36 +00:00
<template>
<!-- if the `aoa` property is set, show a button -->
<template if:true={aoa}>
<button onclick={download}><b>Click to Export!</b></button>
</template>
<!-- if the `aoa` property is not set, show a message -->
<template if:false={aoa}><b>Please wait for data to load ...</b></template>
</template>
```
2024-05-05 16:07:09 +00:00
25) Replace `sheetComponent.js` with the following:
2022-06-27 02:05:36 +00:00
2024-10-07 21:41:19 +00:00
```js title="force-app/main/default/lwc/sheetComponent/sheetComponent.js (replace script)"
2022-06-27 02:05:36 +00:00
import { LightningElement, wire, api } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import { getListUi } from 'lightning/uiListApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import sheetjs from '@salesforce/resourceUrl/sheetjs';
export default class SheetComponent extends LightningElement {
aoa; // will hold data for export
@wire(getListUi, {
objectApiName: ACCOUNT_OBJECT.objectApiName,
listViewApiName: 'AllAccounts'
}) listInfo({ error, data }) {
if (data) {
var headers = [ "Name", "Phone" ];
// create AOA and assign to `aoa` property
this.aoa = [headers].concat(data.records.records.map(record => [
record.fields.Name.value, // Name field
record.fields.Phone.value, // Phone field
]));
} else if (error) console.log(error);
};
@api async download() {
await loadScript(this, sheetjs); // load the library
// create workbook
var wb = XLSX.utils.book_new();
var ws = XLSX.utils.aoa_to_sheet(this.aoa);
XLSX.utils.book_append_sheet(wb, ws, "Data");
// export
XLSX.writeFile(wb, "SheetForceExport.xlsx");
};
}
```
2024-10-07 21:41:19 +00:00
26) Deploy the project again with the same command from step 9:
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
```bash
npx @salesforce/cli project deploy start -d force-app -o SF@USER.NAME
```
2024-10-07 21:41:19 +00:00
Replace `SF@USER.NAME` with the unique Username.
2024-05-05 16:07:09 +00:00
27) Reload the "SheetJS Demo" page. The page should include a button for export:
2023-10-02 04:57:11 +00:00
![SF Export Button](pathname:///salesforce/export.png)
2022-06-27 02:05:36 +00:00
2024-05-05 16:07:09 +00:00
28) Click the "Click to Export!" button. The app will attempt to download a file.
2022-06-27 02:05:36 +00:00
2023-10-02 04:57:11 +00:00
The simple export includes all of the data:
![Excel Export](pathname:///salesforce/xl.png)
2022-06-27 02:05:36 +00:00
2023-09-24 03:59:48 +00:00
:::tip pass
2022-06-27 02:05:36 +00:00
[SheetJS Pro](https://sheetjs.com/pro) offers additional styling options like
cell styling, automatic column width calculations, and frozen rows.
2023-03-26 00:55:35 +00:00
:::
2023-10-02 04:57:11 +00:00
[^1]: It is strongly recommended to review the [detailed introduction in the Salesforce documentation](https://developer.salesforce.com/docs/platform/lwc/guide/get-started-introduction.html)
[^2]: The `XLSX` variable is the main global for the SheetJS library. It exposes methods as described in ["API Reference"](/docs/api/)
2023-11-30 07:10:37 +00:00
[^3]: See ["Understand the Wire Service"](https://developer.salesforce.com/docs/platform/lwc/guide/data-wire-service-about.html) in the Salesforce LWC documentation.
[^4]: See [`getListUI`](https://developer.salesforce.com/docs/platform/lwc/guide/reference-get-list-ui.html) in the Salesforce LWC documentation.
2024-10-07 21:41:19 +00:00
[^5]: See ["Array of Arrays" in "Utilities"](/docs/api/utilities/array#array-of-arrays) for more details.
[^6]: See [`aoa_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input)
[^7]: See ["Sheet Objects"](/docs/csf/sheet)
[^8]: See ["Workbook Object"](/docs/csf/book)
[^9]: See [`book_new` in "Utilities"](/docs/api/utilities/wb)
[^10]: See [`book_append_sheet` in "Utilities"](/docs/api/utilities/wb)
[^11]: See [`writeFile` in "Writing Files"](/docs/api/write-options)