Skip to content
Learni
View all tutorials
Office Add-ins

How to Develop Advanced Excel Add-ins in 2026

Lire en français

Introduction

In 2026, Excel add-ins powered by the Office JavaScript API are revolutionizing spreadsheet automation. Unlike outdated VBA, these cross-platform web extensions (Windows, Mac, web, mobile) leverage TypeScript for seamless workbook interactions. Imagine generating dynamic charts from real-time data changes or validating cells via events—that's the daily reality of an expert add-in.

This expert tutorial walks you through building a complete add-in step by step: advanced range read/write, worksheet event handling, conditional charts, and custom functions. You'll learn to sideload for local testing and publish to AppSource. The result: a bookmark-worthy tool that supercharges your productivity on real projects like financial dashboards or data science analysis. Ready to turn Excel into a super-app? (142 words)

Prerequisites

  • Node.js 20+ and npm 10+
  • Visual Studio Code with extensions: Office Add-ins Toolkit, TypeScript Importer
  • Excel 365 (desktop/web) for sideload
  • Advanced knowledge of TypeScript, Promises/async-await, and DOM manipulation
  • Microsoft 365 Developer Sandbox account (free via portal.office.com)

Install the development tools

terminal-install.sh
npm install -g yo generator-office @microsoft/office-js @types/office-js
npm install -g office-addin-debugging
mkdir mon-addin-excel && cd mon-addin-excel

This command installs Yeoman and the Office generator for rapid scaffolding, plus Office JS types for IntelliSense. The project folder is created empty for full control. Avoid outdated global versions: npm 10+ handles peer deps without conflicts.

Generate the project skeleton

Use Yeoman to bootstrap a TypeScript project with a task pane. Choose 'Excel' as the host, 'Task pane' as the type, and 'United States' for localization. This generates an XML manifest, HTML/TS for the UI, and webpack for bundling.

Initialize the project with Yeoman

yo-office.sh
yo office
# Suivez l'assistant :
# ? What is your solution name? ExcelAdvancedAddin
# ? Which type of Office Add-in would you like to create? Office Add-in Task Pane project using TypeScript
# ? Which type of Office project would you like to create? Excel Desktop (Edge Chromium), Excel Current Web, and Excel on iPad
# ? Would you like to open the project in VS Code now? Yes

Yeoman creates a complete project with tsconfig.json, webpack.config.js, and a src folder. The multi-platform choice ensures compatibility. Launch VS Code directly for integrated debugging; skip basic templates for expert customization.

Configure the complete XML manifest

manifest.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
  <Id>12345678-1234-1234-1234-123456789abc</Id>
  <Version>1.0.0.0</Version>
  <ProviderName>Learni Dev</ProviderName>
  <DefaultLocale>fr-FR</DefaultLocale>
  <DisplayName DefaultValue="Add-in Excel Avancé" />
  <Description DefaultValue="Add-in expert pour automatisations Excel" />
  <IconUrl DefaultValue="https://localhost:3000/assets/icon-64.png" />
  <SupportUrl DefaultValue="https://learni-group.com" />
  <AppDomains>
    <AppDomain>https://localhost:3000</AppDomain>
  </AppDomains>
  <Hosts>
    <Host Name="Workbook" />
  </Hosts>
  <Requirements>
    <Sets DefaultMinVersion="1.4">
      <Set Name="ExcelApi" MinVersion="1.4" />
    </Sets>
  </Requirements>
  <FormSettings>
    <Form xsi:type="TaskPane">
      <DesktopSettings>
        <SourceLocation DefaultValue="https://localhost:3000/taskpane.html" />
        <RequestedWidth>400</RequestedWidth>
      </DesktopSettings>
    </Form>
  </FormSettings>
  <Permissions>ReadWriteDocument</Permissions>
</OfficeApp>

This manifest defines the identity, UI, and permissions. ExcelApi 1.4+ enables advanced events. Replace the ID with a unique GUID (use guidgen). ReadWriteDocument is minimal for ranges/charts; add ReadAllDocument if needed. Validate with Validate Office Add-ins.

Develop the task pane interface

The task pane is an HTML/TS sidebar injected into Excel. It exposes buttons for expert actions like 'Analyze Range' or 'Generate Chart'. Use Office UI Fabric for a professional design.

Create the task pane HTML file

src/taskpane/taskpane.html
<!DOCTYPE html>
<html>
<head>
    <title>Add-in Excel Avancé</title>
    <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
    <link rel="stylesheet" href="taskpane.css">
    <script src="../node_modules/@fluentui/react/dist/css/fabric.min.css"></script>
</head>
<body>
    <div id="taskpane-demo-header">
        <img width="32" height="32" src="assets/logo-filled.png">
        <h1>Bienvenue dans l'Add-in Expert</h1>
    </div>
    <hr>
    <div id="function-buttons">
        <button id="read-range">Lire Range A1:B10</button>
        <button id="write-chart">Insérer Chart Dynamique</button>
        <button id="add-event">Activer Événements Cellules</button>
        <button id="custom-function">Exécuter Fonction Custom</button>
    </div>
    <div id="output"></div>
    <script src="taskpane.js"></script>
</body>
</html>

This HTML loads Office.js for the API and Fluent UI for native components. Buttons trigger TS handlers. #output displays live logs. Add taskpane.css for custom styles; test via sideload for mobile responsiveness.

Implement basic handlers in TypeScript

src/taskpane/taskpane.ts
import { Excel } from "office-js";

Office.onReady(() => {
  document.getElementById("read-range")!.onclick = readRange;
  document.getElementById("write-chart")!.onclick = insertChart;
});

async function readRange() {
  await Excel.run(async (context) => {
    const sheet = context.workbook.worksheets.getActiveWorksheet();
    const range = sheet.getRange("A1:B10");
    range.load("values");
    await context.sync();
    const output = document.getElementById("output")!;
    output.innerHTML = `<pre>${JSON.stringify(range.values, null, 2)}</pre>`;
  });
}

async function insertChart() {
  await Excel.run(async (context) => {
    const sheet = context.workbook.worksheets.getActiveWorksheet();
    const range = sheet.getRange("A1:B10");
    const chart = sheet.charts.add("ColumnClustered", range);
    chart.setTitle("Chart Dynamique Généré");
    await context.sync();
  });
}

Handlers use Excel.run to batch atomic ops, avoiding race conditions. load("values") + sync() is the standard pattern—like a Git commit. Limit ranges for performance on large datasets (>10k cells can crash).

Add advanced events and custom functions

Events: Monitor cell changes for auto-recalculations (e.g., data validation). Custom Functions: Define Excel formulas like =MYFUNCTION(A1) via a functions subfolder. Requires ExcelApi 1.2+.

Handle worksheet events

src/taskpane/events.ts
async function addEvent() {
  await Excel.run(async (context) => {
    const sheet = context.workbook.worksheets.getActiveWorksheet();
    sheet.onChanged.add(handleSheetChanged);
    sheet.onSelectionChanged.add(handleSelectionChanged);
    await context.sync();
    document.getElementById("output")!.innerHTML = "Événements activés !";
  });
}

function handleSheetChanged(eventArgs: Excel.WorksheetChangedEventArgs) {
  console.log("Cellule modifiée :", eventArgs.address);
  // Ex: Mettre à jour chart auto
  insertChart();
}

function handleSelectionChanged(eventArgs: Excel.WorksheetSelectionChangedEventArgs) {
  console.log("Sélection :", eventArgs.address);
}

document.getElementById("add-event")!.onclick = addEvent;

// Dans Office.onReady, ajoutez : document.getElementById("add-event")!.onclick = addEvent;

Event handlers are asynchronous and global; use eventArgs for precise context (address, source). Debug with console.log visible in Excel's F12. Disconnect handlers with remove() to avoid memory leaks in long sessions.

Define a custom Excel function

src/functions/functions.ts
function MAFONCTION(maValeur: number): number {
  /**
   * @CustomFunction
   * @param maValeur {number} Value to double.
   * @returns Doubled number.
   */
  return maValeur * 2;
}

/**
 * Calculates sum with variable parameters.
 * @CustomFunction
 * @param valeurs Array of numbers.
 * @returns Sum.
 */
function SOMMEVARIABLE(...valeurs: number[]): number {
  return valeurs.reduce((a, b) => a + b, 0);
}

export { MAFONCTION, SOMMEVARIABLE };

JSDoc @CustomFunction exposes it to Excel as a formula. ...valeurs handles dynamic args. Rebuild with npm run build and sideload; test =MAFONCTION(5) → 10. Cache functions for performance: Office recalculates only on dependency changes.

Sideload script for local testing

sideload.sh
npm install
npm run build
npx office-addin-debugging start https://localhost:3000/manifest.xml
# Ou manuellement : Excel > Insertion > Mon add-in > Charger depuis fichier > manifest.xml

Build webpackifies TS to minified JS. Debugging launches an auto-HTTPS server with a self-signed cert. Use VS Code debugger for breakpoints. For production, replace localhost with a valid domain.

Best practices

  • Batch ops: Always wrap in Excel.run(async (context) => { ... await context.sync(); }) for atomicity and performance (10x gains).
  • Error handling: Wrap in try/catch + context.reSync(); log with Office.context.roamingSettings for persistence.
  • Security: Validate range inputs (e.g., range.getCellCount() < 10000); use ReadOnly perms if possible.
  • Mobile perf: Limit UI to 350px width; test on Excel for iPad for touch events.
  • i18n: Load locales dynamically via Office.context.displayLanguage.

Common errors to avoid

  • No sync(): Async ops fail silently; always await context.sync().
  • HTTPS required: Sideload rejects HTTP; generate cert with mkcert for localhost.
  • API versions: ExcelApi 1.1 lacks events; target 1.4+ in manifest.
  • Memory leaks: Forget remove() on handlers; monitor with Excel Task Manager.

Next steps