Microsoft Office

Explorando a nova API de JavaScript para Office

Stephen Oliver
Eric Schmidt

 

Este é o primeiro de uma série de artigos com análises profundas da API de JavaScript para Office, apresentada no Microsoft Office 2013. Pressupõe que você esteja familiarizado com os aplicativos para Office. Caso não esteja, a página de documentação do MSDN, “Visão geral dos Aplicativos para Office 2013” (bit.ly/12nBWHG), fornece uma visão geral e uma introdução à API.

Este artigo e os outros desta série, embora não sejam exaustivos, analisam em detalhes a API, mostrando os principais aspectos que permitirão uma compreensão mais completa e detalhada da maneira como a API do Office funciona.

Neste primeiro artigo, analisaremos os aplicativos para o modelo de objeto do Office. A parte 2 se concentrará na tarefa principal de acessar o conteúdo do arquivo do Office e analisará o modelo de evento. A parte 3 considerará o conceito de vinculação de dados e examinará as noções básicas do trabalho com partes XML personalizadas. Por fim, a parte 4 concluirá a série com uma visão direcionada para os aplicativos de email.

Em toda esta série, mencionamos com frequência os aplicativos para documentação da API do Office. Você pode encontrar a documentação oficial, exemplos de código e recursos da comunidade na Central de desenvolvedores de Aplicativos para Office e SharePoint do MSDN (dev.office.com).

Visão geral da API de JavaScript para Office

A API de JavaScript para Office é composta de um modelo de objeto completo. A API está contida em um conjunto de arquivos JavaScript, começando pelo arquivo office.js. Um aplicativo deve incluir uma referência para o arquivo office.js para utilizar a API de JavaScript para Office. No carregamento, o arquivo office.js carrega os outros scripts necessários para operação, incluindo os scripts para o ambiente de host e as cadeias de caracteres da localidade. Felizmente, é possível adicionar uma referência ao arquivo office.js usando uma rede de fornecimento de conteúdo (CDN), para que não seja necessário implantar uma cópia do arquivo office.js junto com seu aplicativo. Veja um exemplo:

 

<!-- When deploying an app, you should always   load the CDN version of the office.js file. --> <script src=   "https://appsforoffice.microsoft.com/lib/1.0/hosted/office.js"> </script>

O modelo de objeto foi projetado com base em várias metas:

  1. “Escreva uma vez, execute em qualquer lugar.” Precisava ser extensível — não vinculado a um aplicativo host específico, mas criado com base em recursos disponíveis em vários aplicativos host. Os aplicativos acessam funcionalidades específicas de host de maneira consistente.
  2. Várias plataformas. A compatibilidade também teve uma classificação alta nesta lista, portanto, o modelo de objeto não está vinculado a uma versão específica do Office. Além disso, o mesmo código funciona nas versões Web App de aplicativos cliente do Office, quando houver suporte. Por exemplo, um aplicativo para Excel pode funcionar no Excel Web App tão bem quanto no aplicativo cliente do Excel.
  3. Desempenho e segurança. O desempenho precisava ser maximizado, para que os aplicativos pudessem ser pouco invasivos para os usuários. Além disso, a API de JavaScript foi projetada para interagir diretamente com o conteúdo do documento, sem precisar automatizar os aplicativos do Office, aumentando a estabilidade e a segurança das soluções.

Outra meta principal da API de JavaScript era atrair desenvolvedores da Web para a plataforma Office. Portanto, o modelo de objeto foi criado com uma programação Web moderna em mente. Você pode aproveitar suas habilidades e seu conhecimento de outras bibliotecas JavaScript, como jQuery, ao criar aplicativos em conjunto com a API de JavaScript para Office.

O padrão de programação assíncrona

Conforme mencionado, o desempenho era uma meta principal no design dos aplicativos para a API do Office. Uma das maneiras que os designers utilizaram para aumentar o desempenho da API foi o uso intenso de funções assíncronas.

O uso de funções assíncronas evita o bloqueio de um aplicativo durante a execução caso uma função demore para retornar. A função assíncrona é chamada, mas a execução do programa não espera até que a função retorne. Em vez disso, o programa continua enquanto a função assíncrona ainda está em execução. Isso permite que o usuário continue usando o documento do Office enquanto o aplicativo ainda estiver potencialmente funcionando.

Alguns pontos importantes para entender o design assíncrono nos aplicativos para a API do Office abordados nesta seção são:

  • A assinatura comum das funções assíncronas nos aplicativos para API do Office.
  • O uso de parâmetros opcionais nas funções assíncronas.
  • A função do objeto AsyncResult nas funções assíncronas.

Discutiremos cada um deles separadamente.

Assinatura comum das funções assíncronas nos aplicativos para API do Office Todas as funções assíncronas nos aplicativos para API do Office têm a mesma convenção de nomenclatura e a mesma assinatura básica. O nome de todas as funções assíncronas termina em “Async”, por exemplo: Document.getSelectedDataAsync.

A assinatura para todas as funções assíncronas está de acordo com o padrão básico a seguir:

functionNameAsync(     requiredParameters,     [, options], [callback]);

Os parâmetros necessários são seguidos de dois outros parâmetros: um objeto que armazena parâmetros opcionais e uma função de retorno de chamada, sendo que ambos são sempre opcionais.

Parâmetros opcionais nas funções assíncronas O objeto JavaScript opcional na assinatura de funções assíncronas é uma coleção de pares chave/valor, separados por dois-pontos, onde a chave é o nome do parâmetro e o valor são os dados que você deseja usar para esse parâmetro. A ordem dos pares chave/valor não importa, contanto que o nome do parâmetro esteja correto. A documentação do MSDN para cada função assíncrona detalha quais parâmetros estão disponíveis para uso no objeto options para essa função específica.

Por exemplo, o método Document.setSelectedDataAsync tem a mesma assinatura básica comum a todas as funções assíncronas nos aplicativos para Office:

Office.context.document.setSelectedDataAsync(   data [, options], callback);

Como todas as funções assíncronas na API, Document.set­SelectedDataAsync tem um objeto options que armazena parâmetros opcionais, mas os parâmetros para esse objeto options são diferentes daqueles para outras funções assíncronas na API, porque o objetivo dessa função é definir dados. Portanto, os parâmetros opcionais para Document.setSelectedDataAsync estão relacionados à definição de dados:

  • coercionType: uma enumeração CoercionType que especifica o formato dos dados inseridos (texto, HTML, OOXML, tabela ou matriz).
  • asyncContext: um objeto definido pelo usuário que é retornado sem alterações no objeto AsyncResult que é passado para a função de retorno de chamada como seu único parâmetro.

Esse mesmo conceito se aplica a todas as outras funções assíncronas.

Você pode fornecer o objeto que contém os parâmetros opcionais como um literal de objeto embutido na chamada da função assíncrona, ou primeiro criar um objeto e depois passá-lo para o parâmetro. A seguir, estão dois exemplos de código que mostram as duas maneiras de fornecer o objeto options usando a função Document.setSelectedDataAsync.

Passar o parâmetro options embutido:

function setData(data) {   Office.context.document.setSelectedDataAsync(data, {   coercionType: Office.CoercionType.Text }     ); }

Passar o parâmetro options em um objeto JavaScrip:

 

function setData(data) {   var options = { coercionType: Office.CoercionType.Text };   Office.context.document.setSelectedDataAsync(data, options ); }

A função do objeto AsyncResult nas funções assíncronas O terceiro parâmetro na assinatura comum para funções assíncronas na API de JavaScript para Office é o parâmetro de retorno de chamada opcional. O parâmetro de retorno de chamada é exatamente o que parece ser: uma função que você fornece que é chamada quando a operação assíncrona for concluída. É claro que você pode fornecer uma função nomeada ou uma função anônima embutida na chamada para a função assíncrona. O que é importante notar aqui é a função do objeto AsyncResult com relação à função de retorno de chamada.

Quando o tempo de execução chama seu retorno de chamada, passa um objeto Async­Result como o único argumento para o retorno de chamada. O objeto AsyncResult contém informações sobre a operação assíncrona, como: se a operação foi bem-sucedida; quais erros ocorreram, se houver; e o valor de retorno, se houver, da função assíncrona. Na verdade, em todas as funções assíncronas que retornam algum tipo de dado ou objeto, AsyncResult é a única maneira de chegar ao valor retornado. É possível fazer isso usando a propriedade AsyncResult.value.

Por exemplo, o seguinte trecho de código obtém o tamanho do documento e exibe essa informação no elemento HTML especificado na interface do usuário do aplicativo. Para obter o tamanho do arquivo, primeiro você obtém o objeto file que o método Document.getFileAsync retorna pela propriedade AsyncResult.value. Veja como isso é feito:

function getFileData(elementId) {   Office.context.document.getFileAsync(Office.FileType.Text,   function (asyncResult) {     if (asyncResult.status === 'succeeded') {       var myFile = asyncResult.value;       $(elementId).val(myFile.size);     }   }); }

A função getFileData chama o método Document.getFileAsync, especificando que deve retornar o conteúdo do arquivo como texto. Em seguida, usa a propriedade value do objeto AsyncResult passado para o retorno de chamada da função anônima para obter a referência para o objeto File. Depois, exibe o tamanho do arquivo no elemento especificado usando a propriedade size do objeto File. De forma semelhante, você usará a propriedade AsyncResult.value para obter o valor de retorno de qualquer função assíncrona nos aplicativos para a API do Office. 

Saiba mais sobre o método Document.getFileAsync no próximo artigo desta série.

Hierarquia do modelo de objeto

A API de JavaScript para Office pretende fornecer compatibilidade entre as versões do Office e simetria entre diferentes aplicativos host. Para oferecer suporte a essas metas, a API de JavaScript para Office tem um modelo de objeto enxuto com uma hierarquia distinta que não está diretamente vinculada a nenhum aplicativo host específico. Em vez disso, o modelo de objeto hospeda um conjunto direcionado de recursos para interagir com documentos do Office, cujo escopo é o tipo de aplicativo (aplicativo de painel de tarefas, conteúdo ou email) que os utiliza.

A Figura 1 fornece uma visão geral resumida da hierarquia de nível superior de objetos na API de JavaScript para Office (observe que o modelo de objeto inteiro não é mostrado). Especificamente, o diagrama demonstra os relacionamentos entre os objetos Office, Context, Document, Settings, Mailbox e RoamingSettings.


Figura 1 A hierarquia do modelo de objeto na API de JavaScript para Office

Cada aplicativo host (Word, Excel, Excel Web App, PowerPoint, Project, Outlook e Outlook Web App) pode usar um subconjunto de recursos incluídos na API. Por exemplo, aproximadamente 40% do modelo de objeto está relacionado exclusivamente a aplicativos de email que podem ser usados apenas no Outlook e no Outlook Web App. Outra parte do modelo de objeto permite a interação com partes XML personalizadas, que estão disponíveis apenas no Word 2013.

A Figura 2 mostra os recursos disponíveis para aplicativos host específicos.

Figura 2 Disponibilidade de recursos na API de JavaScript para Office por aplicativo host

Recursos Word Excel/Excel Web App PowerPoint Outlook/Outlook Web App Project
Obter/definir dados como texto, tabela, matriz Tudo Tudo Somente texto   Somente texto
Configurações Tudo Tudo Tudo (RoamingSettings)  
Obter arquivo Tudo   Somente compactado    
Ligações Tudo Tudo      
Partes XML personalizadas Tudo        
HTML e OOXML Tudo        
Caixa de correio       Tudo  

Objetos compartilhados no modelo de objeto A API de JavaScript para Office tem um ponto de entrada definitivo, o objeto do Office, que está disponível para todos os tipos de aplicativo e em todos os aplicativos host. O objeto do Office representa uma instância específica de um aplicativo inserida em um documento, pasta de trabalho, apresentação, projeto, mensagem de email ou compromisso. Pode acessar ligações entre o aplicativo e o documento usando o método select. (Abordaremos ligações com mais detalhes em um artigo futuro.) Acima de tudo, o objeto do Office expõe o evento inicializado para o aplicativo, o que permite que você crie uma lógica de inicialização para o aplicativo (abordaremos mais sobre isso em um artigo futuro). Por fim, o objeto do Office contém uma referência ao objeto Context para o aplicativo.

O objeto Context, que também está disponível para todos os tipos de aplicativo e em todos os aplicativos host, expõe informações sobre o ambiente de tempo de execução que hospeda o aplicativo. Além de armazenar as configurações de idioma para o aplicativo, o objeto Context fornece o ponto de entrada para recursos de tempo de execução na API de JavaScript para Office que são específicos para o host no qual o aplicativo foi ativado.

Por exemplo, você pode acessar o documento (objeto Document) associado ao aplicativo por meio da propriedade Context.document. No entanto, essa propriedade retorna um valor apenas quando é chamada em um aplicativo host que oferece suporte a ela, ou seja, em um aplicativo de painel de tarefas ou de conteúdo. Se tentarmos acessar a propriedade Context.document em um aplicativo de email, obteremos um erro “objeto indefinido”. O mesmo acontece com a propriedade Context.mailbox: Em um aplicativo de email, retorna a caixa de correio (objeto Mailbox) aberto no aplicativo host. Em um aplicativo de painel de tarefas, é indefinido.

Suporte para aplicativos de painel de tarefas e de conteúdono modelo de objeto Para aplicativos de painel de tarefas e de conteúdo, o objeto Document representa o documento, pasta de trabalho, apresentação ou projeto no qual o aplicativo foi inserido. O objeto Document fornece o nível mais alto de acesso ao conteúdo do arquivo — essencialmente, é o ponto de contato principal entre um aplicativo e um documento do Office.

Quase todas as técnicas para acessar o conteúdo no documento do Office exigem o uso do objeto Document. Por esse motivo, convém capturar uma referência ao objeto Document quando o aplicativo for inicializado, conforme mostrado na Figura 3.

Figura 3 Armazenando uma referência ao objeto Document quando o aplicativo for inicializado

 

// Add a handler to the initialize event of the Office object Office.initialize = function (reason) {   $(document).ready(function () {     app.get_Document(Office.context.document);       // Other initialization logic goes here   }) }   // Use a self-executing anonymous function to encapsulate the // functionality that the app uses var app = (function () {     var _document;   function get_Document(officeDocument) {     _document = officeDocument;   }     // Other fields and functions associated with the app     return {     get_Document: get_Document     // Other exposed members   }; })()

Quando um aplicativo for ativado em um arquivo do Project, o objeto Document apresentará recursos adicionais e específicos destinados a arquivos do Project. Por meio do objeto Document, um aplicativo pode obter dados para tarefas, exibições, campos e recursos específicos no projeto. Um aplicativo também pode adicionar ouvintes de eventos para monitorar quando o usuário altera a exibição, tarefa ou recurso selecionado no projeto. (Falaremos mais sobre o uso do objeto Document em um aplicativo para Project no próximo artigo.)

O objeto Document também apresenta o objeto Settings, que representa o “recipiente de propriedades” de um aplicativo. Um aplicativo pode armazenar e manter propriedades personalizadas entre sessões do aplicativo no mesmo documento usando o objeto Settings. As propriedades viajam com o documento: Se você compartilhar com outra pessoa um arquivo do Office que contém um aplicativo, as propriedades personalizadas armazenadas no aplicativo ficarão disponíveis quando essa outra pessoa ler o arquivo.

Armazenar e recuperar as configurações usando o recipiente de propriedades é simples. O método Settings.set cria a configuração na memória como um par chave/valor. Para retirar as propriedades do recipiente de propriedades, usamos o método Settings.get, passando o nome da configuração (chave), para obter o valor. Os métodos set e get são síncronos. Para armazenar as configurações entre sessões, precisamos chamar o método Settings.saveAsync, que salva todas as propriedades personalizadas contidas no aplicativo quando o documento é salvo.

O exemplo de código, “Aplicativos para Office: manter as configurações personalizadas” (bit.ly/UEiZff), fornece exemplos adicionais de como usar o objeto Settings e como armazenar dados em um aplicativo.

Suporte para aplicativos de email no modelo de objeto Para aplicativos de email, o objeto Mailbox fornece o ponto de entrada de acesso a dados para a funcionalidade específica do aplicativo de email. Como o nome indica, o objeto Mailbox corresponde à caixa de correio do usuário atual e é transmitido para qualquer lugar em que os usuários lerem o email — independentemente se for no aplicativo cliente Outlook ou no Outlook Web App. Além de fornecer acesso a mensagens de email e compromissos individuais (por meio da propriedade Mailbox.item), o objeto Mailbox permite que o aplicativo crie novos compromissos, acesse o perfil do usuário local e até mesmo obtenha a hora local do usuário.

Assim como o objeto Document para aplicativos de conteúdo e de painel de tarefas, convém capturar uma referência ao objeto Mailbox quando o aplicativo for inicializado, conforme mostrado na Figura 4.

Figura 4 Armazenando uma referência ao objeto Mailbox em uma variável global quando o aplicativo for inicializado

// Add a handler to the initialize event of the Office object Office.initialize = function (reason) {   $(document).ready(function () {     app.get_Mailbox(Office.context.mailbox);       // Other initialization logic goes here   }) }   // Use a self-executing anonymous function to encapsulate the // functionality that the app uses var app = (function () {     var _mailbox;   function get_Mailbox(mailbox) {     _mailbox = mailbox;   }     // Other fields and functions associated with the app     return {     get_Mailbox: get_Mailbox     // Other exposed members   }; })()

O objeto RoamingSettings, que também está disponível apenas em aplicativos de email, é semelhante ao objeto Settings para aplicativos centrados em documentos (aplicativos de painel de tarefas e de conteúdo). Permite que os aplicativos mantenham propriedades personalizadas, como pares nome/valor entre as sessões. No entanto, ao contrário do objeto Settings, que salva as propriedades personalizadas no arquivo host do Office, o objeto RoamingSettings salva as propriedades personalizadas na caixa de correio atual do usuário. Isso torna as propriedades personalizadas disponíveis para o aplicativo, independentemente da mensagem que o usuário estiver vendo e da forma como o usuário acessa essa caixa de correio (no Outlook ou no Outlook Web App).

Para obter mais informações sobre a hierarquia de modelo de objeto na API de JavaScript para Office, consulte a página de documentação do MSDN, “Compreendendo a API de JavaScript para Office” (bit.ly/UV2POY).

Testando se um recurso pode ser usado em um aplicativo host

Conforme mencionamos anteriormente, um dos pontos fortes da API de JavaScript para Office é a natureza “desenvolva uma vez e hospede vários locais” dos aplicativos para o Office. Por exemplo, o mesmo aplicativo de painel de tarefas pode ser ativado no Word, Excel, Project e PowerPoint (contanto que seu manifesto permita todos esses recursos).

Ainda assim, como nem todos os aplicativos têm acesso a exatamente a mesma lista de recursos, um aplicativo pode ser inserido em um aplicativo host que não permite os recursos que o aplicativo exige. Por exemplo, atualmente o Project não fornece acesso ao objeto Settings. Um aplicativo que tentar acessar o objeto Settings quando estiver inserido no Project emitirá um erro “objeto indefinido”.

Portanto, os desenvolvedores devem incluir lógica em seus aplicativos para testar a disponibilidade dos recursos que forem necessários. No exemplo com o Project, a melhor técnica para detectar os recursos em um aplicativo host é por meio de um bloco if simples:

// Test for Settings object in host application if (Office.context.document.settings) {     // Provide implementation that uses the Settings object   } else {     // Use some other technique for saving custom properties,   // like localStorage, sessionStorage or cookies   }

Para obter mais informações sobre como detectar se um membro está disponível no aplicativo host, consulte a página de documentação do MSDN, “Como: determinar o suporte a um aplicativo host para membros específicos da API”, em bit.ly/TR5ZlB.

Para resumir este artigo, discutimos as partes fundamentais da API de JavaScript para Office. Descrevemos a hierarquia de modelo de objeto em um alto nível e abordamos o padrão assíncrono conforme implementado no modelo de objeto. Também descrevemos como testar se um recurso tem suporte em um aplicativo host.

No próximo artigo desta séria, examinaremos de perto as maneiras mais simples, mas eficazes, de trabalhar com dados em um aplicativo para o Office. Descreveremos como obter e definir dados selecionados mais detalhadamente. Veremos como obter todo o conteúdo do arquivo e analisá-lo. Além disso, discutiremos aplicativos no Project e como ler tarefas e recursos, bem como exibir dados. Por fim, analisaremos o modelo de evento na API de JavaScript para Office: quais códigos de eventos você pode escrever e como lidar com os resultados.

Stephen Oliver* *é um escritor de programação na Divisão do Office e um Microsoft Certified Professional Developer (SharePoint 2010). Escreve a documentação do desenvolvedor para Serviços do Excel e Word Automation Services, bem como para PowerPoint Automation Services. Ajudou a organizar e desenvolver o site Excel Mashup, em ExcelMashup.com.

Eric Schmidt* *é um escritor de programação na Divisão do Office. Criou vários exemplos de código para aplicativos para o Office, incluindo o popular “Manter as configurações personalizadas”. Além disso, escreveu artigos e criou vídeos sobre outros produtos e tecnologias na programação do Office.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo:Mark Brewster, Shilpa Kothari e Juan Balmori Labra