docs.sheetjs.com/docz/docs/03-demos/32-extensions/03-excelapi.md

354 lines
9.2 KiB
Markdown
Raw Normal View History

2022-05-31 02:53:56 +00:00
---
2022-08-26 05:39:17 +00:00
title: Excel JavaScript API
2023-02-28 11:40:44 +00:00
pagination_prev: demos/cloud/index
pagination_next: demos/bigdata/index
2024-05-04 16:15:00 +00:00
sidebar_custom_props:
2024-08-12 05:40:33 +00:00
summary: Add new data import functionality to Excel by integrating SheetJS in custom JavaScript user-defined functions and extensions.
2022-05-31 02:53:56 +00:00
---
2023-04-27 09:12:19 +00:00
import current from '/version.js';
2023-05-07 13:58:36 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-04-27 09:12:19 +00:00
2023-09-05 18:04:23 +00:00
:::info pass
2022-08-30 22:12:52 +00:00
2024-08-12 05:40:33 +00:00
This demo focuses on the Excel JavaScript API.
For reading and writing Excel spreadsheets, [other demos](/docs/demos/) cover a
wide variety of use cases and deployments.
2022-08-30 22:12:52 +00:00
:::
2024-03-12 06:47:52 +00:00
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
2022-05-31 02:53:56 +00:00
Office 2016 introduced a JavaScript API for interacting with the application.
It offers solutions for custom functions as well as task panes.
Excel currently does not provide support for working with Apple Numbers files
2024-03-12 06:47:52 +00:00
and some legacy file formats. SheetJS fills the gap.
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
In the ["Complete Demo"](#complete-demo), we'll create a new custom function
`SHEETJS.EXTERN()` which tries to fetch an external spreadsheet and insert the
data into the worksheet.
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
![`SHEETJS.EXTERN` output](pathname:///xlapi/xlfetch.png)
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
:::note Tested Deployments
2022-05-31 02:53:56 +00:00
2025-01-06 02:51:20 +00:00
This demo was tested in the following deployments:
| OS and Version | Architecture | Excel | Date |
|:---------------|:-------------|:-----------|:-----------|
| macOS 14.5 | `darwin-arm` | 16.81 | 2024-12-22 |
| Windows 11 | `win11-x64` | 365 (2407) | 2024-08-11 |
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
:::
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
:::caution Excel Bugs
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
There was a binary data bug affecting `fetch` and Excel. It was resolved in
version 2303. It is strongly encouraged to upgrade to the latest version of
Excel 365 before running the demo.
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
:::
2022-05-31 02:53:56 +00:00
:::danger Telemetry
2024-03-12 06:47:52 +00:00
The Office Add-in CLI collects telemetry by default. It can be disabled:
```js
npx office-addin-usage-data off
```
The setting can be verified by running:
```js
npx office-addin-usage-data list
```
:::
2023-04-21 00:53:38 +00:00
## Integration Details
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be
imported from scripts in an Excel Custom Functions project.
2022-05-31 02:53:56 +00:00
2024-04-12 01:04:37 +00:00
The [`sheet_to_json`](/docs/api/utilities/array#array-output) helper function
can generate arrays of arrays of values based on the worksheet data. Excel
2024-08-12 05:40:33 +00:00
custom functions transparently treat arrays of arrays as Dynamic Arrays.
This example fetches a file using the `fetch` API, parses the binary data using
the SheetJS `read`[^1] method and returns data from the first worksheet.
```mermaid
flowchart LR
url[(Remote\nFile)]
ab[(File\nBytes)]
subgraph SheetJS Structures
wb(((SheetJS\nWorkbook)))
ws((SheetJS\nWorksheet))
end
aoo[[Array of\nObjects]]
xl>Excel\nWorksheet]
url --> |fetch\narrayBuffer| ab
ab --> |read\n\n| wb
wb --> |wb.Sheets\nselect sheet| ws
ws --> |sheet_to_json\n\n| aoo
aoo --> |return\nExcel| xl
linkStyle 1,2,3 color:blue,stroke:blue;
```
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
```js title="src\functions\functions.js"
2024-08-12 05:40:33 +00:00
const XLSX = require("xlsx");
2022-05-31 02:53:56 +00:00
/**
2023-04-21 00:53:38 +00:00
* Download file and write data
2022-05-31 02:53:56 +00:00
* @customfunction
2023-04-21 00:53:38 +00:00
* @param {string} url URL to fetch and parse
* @returns {any[][]} Worksheet data
2022-05-31 02:53:56 +00:00
*/
2024-03-12 06:47:52 +00:00
export async function extern(url) {
2023-04-21 00:53:38 +00:00
try {
/* Fetch Data */
const res = await fetch(url);
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
/* Get Data */
const ab = await res.arrayBuffer();
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
/* Parse Data */
2024-08-12 05:40:33 +00:00
const wb = XLSX.read(ab);
2023-04-21 00:53:38 +00:00
2024-08-12 05:40:33 +00:00
/* Translate Data */
const ws = wb.Sheets[wb.SheetNames[0]]; // get first worksheet
const aoa = XLSX.utils.sheet_to_json(ws, { header: 1 }); // array of arrays
/* Return Data */
2023-04-21 00:53:38 +00:00
return aoa;
} catch(e) { return [[e.message || e]]; } // pass error back to Excel
}
2022-05-31 02:53:56 +00:00
```
2023-04-21 00:53:38 +00:00
## Complete Demo
2022-05-31 02:53:56 +00:00
2025-01-06 02:51:20 +00:00
0) Clear the functions cache. For the tested version of Excel for Windows:
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
- Open File Explorer
- Select the address bar and enter `%LOCALAPPDATA%\Microsoft\Office\16.0\Wef`
2023-09-05 18:04:23 +00:00
- Delete the `CustomFunctions` folder (if it exists) and empty Recycle Bin.
:::caution pass
**This will delete all custom functions associated with the user account!**
To preserve the custom functions on the user account, rename the existing folder
to `CustomFunctionsBackup` before testing and rename back to `CustomFunctions`
after testing is finished.
:::
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
1) Install [NodeJS LTS](https://nodejs.org/en/download/).
2022-05-31 02:53:56 +00:00
2025-01-06 02:51:20 +00:00
2) Launch a new PowerShell (Windows) or Terminal (MacOS) window.
2024-03-12 06:47:52 +00:00
3) Disable telemetry:
```bash
npx office-addin-usage-data off
```
4) Install dependencies:
2022-05-31 02:53:56 +00:00
2023-05-11 21:28:29 +00:00
```bash
2023-05-07 13:58:36 +00:00
npm i -g yo bower generator-office
2023-04-21 00:53:38 +00:00
```
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
### Creating a new Add-in
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
5) Run the generator:
```bash
npx yo office
```
The generator will ask a few questions:
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
- "Choose a project type": "Excel Custom Functions using a Shared Runtime"
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
- "Choose a script type": "JavaScript",
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
- "What do you want to name your add-in?": "SheetJSImport"
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
The generator will create the project and install dependencies.
6) Start the development process:
2022-05-31 02:53:56 +00:00
2023-05-11 21:28:29 +00:00
```bash
2023-04-21 00:53:38 +00:00
cd SheetJSImport
npm run build
npm start
2022-05-31 02:53:56 +00:00
```
2024-08-12 05:40:33 +00:00
If prompted to `Allow localhost loopback for Microsoft Edge WebView`, type
<kbd>N</kbd> and press Enter.
2024-03-12 06:47:52 +00:00
If prompted to install "Developer CA for Microsoft Office Add-ins" certificate,
select "Yes"
If Windows Firewall prompts to allow Node.js on private networks, select "Yes"
A new terminal window running NodeJS will be created. Keep the window open.
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
A new Excel window with the loaded add-in will launch.
:::caution pass
2024-12-22 04:47:57 +00:00
In some tests, the task pane showed an error:
2024-03-12 06:47:52 +00:00
```
Script error.
```
[Webview2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)
should be installed manually.
:::
7) In `manifest.xml` , search for `Functions.Namespace` . There will be an XML
2023-04-21 00:53:38 +00:00
element with name `bt:String`. Change the `DefaultValue` attribute to `SHEETJS`:
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
```xml title="manifest.xml (change highlighted line)"
2023-04-21 00:53:38 +00:00
<bt:ShortStrings>
// highlight-next-line
<bt:String id="Functions.Namespace" DefaultValue="SHEETJS"/>
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!" />
```
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
8) Close the Excel window and the terminal window. Do not save the XLSX file.
2025-01-06 02:51:20 +00:00
9) In the terminal window, start the development process again:
2024-03-12 06:47:52 +00:00
```bash
2025-01-06 02:51:20 +00:00
npm run stop
2024-03-12 06:47:52 +00:00
npm start
```
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
### Integrating the SheetJS Library
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
10) Install the SheetJS library in the project
2022-05-31 02:53:56 +00:00
2023-05-07 13:58:36 +00:00
<CodeBlock language="bash">{`\
2023-04-27 09:12:19 +00:00
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
2023-05-07 13:58:36 +00:00
</CodeBlock>
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
11) Replace `src\functions\functions.js` with the following:
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
```js title="src\functions\functions.js"
var XLSX = require("xlsx");
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
/**
* Print SheetJS Library Version
* @customfunction
* @returns {string[][]} The SheetJS Library Version.
*/
2024-03-12 06:47:52 +00:00
export function version() {
2023-04-21 00:53:38 +00:00
return [[XLSX.version]];
}
```
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
12) Close the terminal window and the Excel window. Do not save the Excel file.
2025-01-06 02:51:20 +00:00
13) In a new terminal window, start the development process again:
2022-05-31 02:53:56 +00:00
2024-03-12 06:47:52 +00:00
```bash
2025-01-06 02:51:20 +00:00
npm run stop
2024-03-12 06:47:52 +00:00
npm start
```
14) In the new Excel window, enter the formula `=SHEETJS.VERSION()` in cell
2024-08-12 05:40:33 +00:00
`E1`. You should see something similar to the following screenshot:
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
![`SHEETJS.VERSION` output](pathname:///xlapi/xlvers.png)
2022-05-31 02:53:56 +00:00
2023-04-21 00:53:38 +00:00
This indicates that the SheetJS library has been loaded.
2022-05-31 02:53:56 +00:00
2025-01-06 02:51:20 +00:00
:::info pass
In some MacOS tests, the add-in installed `CONTOSO.VERSION`. To force a refresh
of the manifest:
1) Stop the development process:
```bash
npm run stop
```
2) Close the Excel app by right-clicking Excel in the Dock and selecting "Quit".
3) Restart the development process:
```bash
npm start
```
4) Activate the Task Pane for the addin (click "Show Task Pane" in the ribbon).
5) Hover near the top-right corner of the addin and click the `i` icon.
6) Click "Clear Web Cache" and wait a few moments.
:::
2023-04-21 00:53:38 +00:00
### Fetching Files from the Internet
2022-05-31 02:53:56 +00:00
2024-08-12 05:40:33 +00:00
15) Add the following code snippet to `src\functions\functions.js` and save:
2022-05-31 02:53:56 +00:00
2023-09-05 18:04:23 +00:00
```js title="src\functions\functions.js (add to end)"
2022-05-31 02:53:56 +00:00
/**
* Download file and write data
* @customfunction
2023-04-21 00:53:38 +00:00
* @param {string} url URL to fetch and parse
2022-05-31 02:53:56 +00:00
* @returns {any[][]} Worksheet data
*/
2024-03-12 06:47:52 +00:00
export async function extern(url) {
2022-05-31 02:53:56 +00:00
try {
/* Fetch Data */
const res = await fetch(url);
/* Get Data */
2023-04-21 00:53:38 +00:00
const ab = await res.arrayBuffer();
2022-05-31 02:53:56 +00:00
/* Parse Data */
2023-04-21 00:53:38 +00:00
var wb = XLSX.read(ab);
2022-05-31 02:53:56 +00:00
/* get and return data */
var ws = wb.Sheets[wb.SheetNames[0]]; // get first worksheet
var aoa = XLSX.utils.sheet_to_json(ws, { header: 1 }); // get data as array of arrays
2023-01-14 03:13:35 +00:00
return aoa;
} catch(e) { return [[e.message || e]]; } // pass error back to Excel
2022-05-31 02:53:56 +00:00
}
```
2024-08-12 05:40:33 +00:00
16) Close the terminal window and the Excel window (do not save the Excel file).
2025-01-06 02:51:20 +00:00
17) In a new terminal window, start the development process again:
2022-05-31 02:53:56 +00:00
2024-08-12 05:40:33 +00:00
```bash
2025-01-06 02:51:20 +00:00
npm run stop
2024-08-12 05:40:33 +00:00
npm start
```
18) Enter the text `https://docs.sheetjs.com/pres.numbers` in cell `D1`. Enter
2024-04-26 04:16:13 +00:00
the formula `=SHEETJS.EXTERN(D1)` in cell `D2` and press Enter.
2024-03-12 06:47:52 +00:00
Excel should pull in the data and generate a dynamic array. The worksheet should
match the screenshot at the top of this page.
2022-05-31 02:53:56 +00:00
2023-09-05 18:04:23 +00:00
:::tip pass
2023-01-14 03:13:35 +00:00
2022-05-31 02:53:56 +00:00
[SheetJS Pro](https://sheetjs.com/pro) offers additional features that can be
2024-08-12 05:40:33 +00:00
used in Excel Custom Functions and Add-ins.
2023-01-14 03:13:35 +00:00
:::
2024-08-12 05:40:33 +00:00
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)