Conecte-Office.js a qualquer estrutura JavaScript

Office.js é independente de estrutura e funciona perfeitamente com qualquer estrutura ou biblioteca JavaScript do lado do cliente. Esteja você criando com React, Angular, Vue, Svelte ou qualquer outra estrutura, o padrão de integração é o mesmo: certifique-se de que Office.js inicialize antes que seu aplicativo seja renderizado.

Observação

Você também pode usar estruturas do lado do servidor, como ASP.NET, PHP e Java para criar Suplementos do Office, mas este artigo não as aborda. Este artigo se concentra especificamente em estruturas JavaScript do lado do cliente que são executadas no navegador.

Este artigo explica os padrões universais para integração Office.js com estruturas JavaScript do lado do cliente, considerações importantes e fornece exemplos em várias estruturas.

Dica

Este artigo foi projetado para desenvolvedores que criam suplementos do Office do zero usando sua estrutura JavaScript preferida ou integrando Office.js a um projeto de estrutura existente. Se você estiver usando o gerador Yeoman para Suplementos do Office ou Microsoft 365 Agents Toolkit, essas ferramentas já fornecem a configuração correta Office.js.

Pré-requisitos

Início rápido: o padrão universal

Independentemente da estrutura escolhida, siga o padrão a seguir.

  1. Faça referência Office.js da CDN em seu HTML <head>.
  2. Ligue Office.onReady() e aguarde a conclusão.
  3. Inicialize sua estrutura depois que Office.js estiver pronta.
// Universal pattern - works with any framework.
Office.onReady((info) => {
  // Office.js is now ready.
  // Initialize your framework here.
  initializeYourFramework();
});

Carregar Office.js da CDN

Você deve fazer referência à API JavaScript do Office da CDN (rede de distribuição de conteúdo) em seu arquivo HTML. Adicione a marca a seguir <script> na <head> seção de sua página HTML, antes de quaisquer outras marcas de script ou referências de pacote de estrutura.

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My Office Add-in</title>

  <!-- Office.js must be loaded from CDN, not bundled -->
  <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>

  <!-- Your framework bundle loads after Office.js -->
</head>

Importante

  • Carregue Office.js da CDN e faça referência a ela em seu arquivo HTML. Não o importe em seu código JavaScript ou TypeScript.
  • A referência Office.js deve aparecer na <head> seção para garantir que a API seja totalmente inicializada antes que qualquer elemento do corpo seja carregado.
  • Não agrupe Office.js com o código do aplicativo. Sempre faça referência a ele na CDN.

Para obter mais informações sobre como referenciar Office.js, incluindo APIs de visualização e pontos de extremidade CDN alternativos, consulte Referenciar a biblioteca de API JavaScript do Office.

Inicializar a estrutura após Office.onReady

A chave para integrar o Office.js com qualquer estrutura é inicializar seu aplicativo dentro do retorno de Office.onReady() chamada. Essa abordagem garante que Office.js seja totalmente inicializada antes que sua estrutura comece a renderizar. Essa inicialização é importante porque Office.js precisa:

  • Baixe e armazene em cache os arquivos da biblioteca de API da CDN.
  • Inicialize o ambiente de tempo de execução do Office.
  • Estabeleça comunicação com o aplicativo do Office.

Se sua estrutura for renderizada antes que Office.js esteja pronta, as chamadas a APIs do Office falharão. Ao inicializar seu aplicativo dentro Office.onReady()do , você garante Office.js estará pronto quando o código do aplicativo for executado.

Exemplos

Os exemplos a seguir mostram o mesmo padrão de integração em diferentes estruturas. O padrão é idêntico - apenas o método de inicialização da estrutura muda.

Reagir

// src/index.tsx
Office.onReady(() => {
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(<App />);
});

Angular

// src/main.ts
Office.onReady(() => {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(err => console.error(err));
});

Vue

// src/main.ts
Office.onReady(() => {
  createApp(App).mount('#app');
});

Esbelto

// src/main.ts
Office.onReady(() => {
  new App({ target: document.getElementById('app') });
});

JavaScript simples sem estrutura

// src/app.js
Office.onReady((info) => {
  document.getElementById('run-button').onclick = run;

  if (info.host === Office.HostType.Excel) {
    console.log('Running in Excel');
  }
});

Usar APIs Office.js em seu aplicativo

Após Office.js inicializar (quando Office.onReady() terminar), você poderá chamar APIs do Office em qualquer lugar do suplemento. Use os ganchos de ciclo de vida ou manipuladores de eventos da sua estrutura para chamar APIs do Office quando necessário.

// React example: Call an Office JS API in the useEffect lifecycle hook.
import { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState('');

  useEffect(() => {
    loadData();
  }, []);

  async function loadData() {
    await Excel.run(async (context) => {
      const range = context.workbook.getSelectedRange();
      range.load('values');
      await context.sync();

      // Update component state with the data from Excel.
      const value = range.values[0][0];
      setData(value);
    });
  }

  return <div>Selected cell: {data}</div>;
}

// Similar patterns for other frameworks:
// Angular: ngOnInit() { this.loadData(); }
// Vue: onMounted(() => { loadData(); })
// Svelte: onMount(() => { loadData(); })

Suporte a TypeScript

Para habilitar o IntelliSense e a verificação de tipo para Office.js em projetos TypeScript, instale as definições de tipo de DefinitelyTyped.

npm install --save-dev @types/office-js

O TypeScript reconhece automaticamente os tipos. Você não precisa de uma instrução de importação em seu código porque Office.js é carregado globalmente da CDN.

// TypeScript automatically recognizes Office types.
Office.onReady((info: Office.OfficeInfo) => {
  if (info.host === Office.HostType.Excel) {
    // TypeScript provides IntelliSense for Excel APIs.
  }
});

Para obter mais informações, consulte Referenciar a biblioteca da API JavaScript do Office.

Outras considerações

Indicadores de carregamento

Se você quiser mostrar um indicador de carregamento enquanto Office.js inicializa, exiba-o antes de chamar Office.onReady() e oculte-o dentro do retorno de chamada.

// Show loading indicator.
document.getElementById('loading')!.style.display = 'block';

Office.onReady((info) => {
  // Hide loading indicator.
  document.getElementById('loading')!.style.display = 'none';

  // Initialize framework.
  initializeYourFramework();
});

Para uma melhor experiência do usuário com estruturas que têm seus próprios estados de carregamento, use um carregador HTML/CSS simples que seja exibido imediatamente. Em seguida, deixe sua estrutura assumir o controle depois de montada.

API de diálogo e ciclo de vida do componente

A API de Caixa de Diálogo do Office abre páginas em janelas separadas do navegador. Esse comportamento tem implicações importantes para aplicativos de estrutura:

  • Cada caixa de diálogo cria um novo contexto de execução com uma instância de estrutura separada.
  • A caixa de diálogo executa sua própria cópia do código do aplicativo.
  • Você deve chamar Office.onReady() na página de diálogo.
  • A página principal e as janelas de diálogo não compartilham o estado.
  • O armazenamento de sessão não é compartilhado entre contextos.

Se você usar um roteador de estrutura para navegar para uma rota de diálogo, lembre-se de que a janela de diálogo cria uma instância completamente nova do seu aplicativo. Ele não reutiliza a instância existente.

// Main page - opens a dialog.
Office.context.ui.displayDialogAsync(
  'https://localhost:3000/dialog-route',
  { height: 50, width: 50 },
  (result) => {
    if (result.status === Office.AsyncResultStatus.Succeeded) {
      const dialog = result.value;
      dialog.addEventHandler(Office.EventType.DialogMessageReceived, (arg) => {
        // Handle message from dialog.
      });
    } else {
      // Handle error opening the dialog.
      console.error(result.error);
    }
  }
);

// Dialog page - must also call Office.onReady.
Office.onReady(() => {
  // This is a separate framework instance.
  initializeYourFramework();
});

Solução alternativa da API de Histórico

Office.js substitui os métodos replaceState padrão Window.history e pushState por null. Se sua estrutura ou roteador depender desses métodos (comuns no React Router, Vue Router, Angular Router e outros), você precisará armazená-los em cache e restaurá-los.

Adicione este código ao seu arquivo HTML, encapsulando a marca de script Office.js:

<head>
  <!-- Cache history methods before Office.js loads -->
  <script type="text/javascript">
    window._historyCache = {
      replaceState: window.history.replaceState,
      pushState: window.history.pushState
    };
  </script>

  <!-- Load Office.js -->
  <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>

  <!-- Restore history methods after Office.js loads -->
  <script type="text/javascript">
    window.history.replaceState = window._historyCache.replaceState;
    window.history.pushState = window._historyCache.pushState;
  </script>
</head>

Observação

Essa solução alternativa só será necessária se o aplicativo usar o roteamento do lado do cliente (React Router, Vue Router, Angular Router e outros). Aplicativos estáticos sem roteamento não precisam dessa solução alternativa.

Testar fora dos aplicativos do Office

Você pode desenvolver e testar a interface do usuário do seu suplemento usando ferramentas de desenvolvedor do navegador sem fazer o sideload no Office. Essa abordagem permite uma iteração mais rápida durante o desenvolvimento e facilita a depuração dos componentes da interface do usuário.

Quando você abre o suplemento em um navegador comum (fora de um aplicativo do Office), Office.onReady() ele ainda é executado, mas ele é resolvido para as propriedades do host e da null plataforma.

Office.onReady((info) => {
  if (info?.host) {
    console.log(`Running in ${info.host} on ${info.platform}`);
  } else {
    console.log('Running outside of Office (development mode)');
  }

  // Initialize your framework, regardless of whether the add-in is running inside or outside of Office.
  initializeYourFramework();
});

Ferramentas de criação e empacotadores

As estruturas JavaScript modernas normalmente usam ferramentas de compilação como Webpack, Vite, Rollup ou esbuild. Ao configurar sua compilação:

  • Não importe ou agrupe Office.js em seu código JavaScript ou TypeScript.
  • Carregue Office.js da CDN usando uma <script> marca no HTML.
  • Configure o empacotador para tratar Office como uma variável global.

Exemplo: Configuração do TypeScript com a Vite

Se você usa a Vite com TypeScript, você normalmente não precisa de configuração especial da Vite para Office.js. O @types/office-js pacote fornece as definições de tipo necessárias. No entanto, se você precisar garantir que os tipos de Office.js estejam disponíveis, verifique tsconfig.json:

// tsconfig.json
{
  "compilerOptions": {
    "types": ["office-js"]
    // ... your other compiler options ...
  }
}

Exemplo: configuração de webpack

// webpack.config.js
module.exports = {
  externals: {
    'office': 'Office'
  }
};

Projetos de suplemento gerados pelo gerador Yeoman para Office Os suplementos incluem a configuração de compilação correta por padrão.

Bloqueio de rede e firewalls

Se filtros de rede, firewalls ou extensões de navegador bloquearem o Office.js CDN, Office.onReady() nunca resolverá. Considere implementar um tempo limite para cenários corporativos em que as políticas de rede podem bloquear a CDN.

let officeInitialized = false;

// Set a timeout.
setTimeout(() => {
  if (!officeInitialized) {
    console.error('Office.js failed to initialize. Network may be blocking CDN.');
    // Show error message to user.
  }
}, 10000); // 10 second timeout

Office.onReady((info) => {
  officeInitialized = true;
  initializeYourFramework();
});

Para obter mais informações sobre considerações sobre a CDN, consulte Referenciar a biblioteca da API JavaScript do Office.

Problemas de reatividade ou zona específica da estrutura

Algumas estruturas usam zonas ou sistemas de reatividade para rastrear alterações de estado. Em casos raros, as chamadas à API do Office não disparam atualizações da interface do usuário porque são executadas fora da zona de detecção de alterações da estrutura.

Angular: se a interface do usuário não for atualizada após as chamadas à API do Office, encapsule o código emNgZone.run():

import { NgZone } from '@angular/core';

constructor(private zone: NgZone) {}

async loadDataFromExcel() {
  let cellValue: string;

  // Make Office API call
  await Excel.run(async (context) => {
    const range = context.workbook.getSelectedRange();
    range.load('values');
    await context.sync();
    cellValue = range.values[0][0];
  });

  // Update Angular component state inside zone
  this.zone.run(() => {
    this.myData = cellValue;
  });
}

Confira também