Não muito tempo atrás, recebi a tarefa de adicionar um botão export-array-to-excel a algumas páginas de um aplicativo React. Os critérios dados para este botão foram:

  • Tinha que ser reutilizável, para que pudesse ser importado para qualquer página e usado conforme necessário
  • Quando clicado, deve abrir um modal que permite aos usuários escolher entre baixar todas as colunas (todas as propriedades de cada objeto individual da matriz) ou colunas selecionadas (apenas propriedades selecionadas de objetos individuais da matriz)
  • O modal deve conter um botão de download que fará o download de uma matriz de resposta da API JSON diretamente em um arquivo de planilha com base nas colunas selecionadas
Uma captura de tela do componente export-array-to-excel
Uma captura de tela do componente export-array-to-excel.

Descobri que esta é uma solicitação de recurso comum (talvez com uma pequena variação) fornecida aos desenvolvedores, especialmente aqueles que trabalham em projetos do tipo painel de administração, e é por isso que estou escrevendo este artigo.

Este artigo pressupõe que você tenha um bom conhecimento de JavaScript e React. Neste artigo, mostrarei primeiro os conceitos fundamentais envolvidos na exportação de uma matriz de objetos para uma planilha do Excel. Em seguida, com base nisso, crie o componente export-array-to-excel reutilizável mostrado acima, usando Chakra UI como a biblioteca de componentes de escolha.

A primeira coisa que precisa ser descoberta é como solicitar um download no navegador.

Em HTML simples, criar um botão para solicitar um download no navegador é bastante simples usando uma tag âncora e seu atributo de download. Basta passar o URL ou o caminho do arquivo a ser baixado para o atributo href :

  

O atributo download faz parte da especificação HTML5 e especifica que o destino deve ser baixado quando o link é clicado. O valor passado para o atributo download especifica o nome do arquivo para o arquivo baixado.

Infelizmente, a solução acima não funcionará exatamente para nosso caso de uso porque não há um arquivo Excel pré-existente para vincular.

Teremos que realizar quatro tarefas espontaneamente quando o botão de download for clicado:

  1. Obtenha a matriz de resposta da API e converta-a em uma tabela
  2. Incorpore a tabela em um modelo XML de planilha
  3. Crie programaticamente um URL de arquivo para o modelo de planilha usando os métodos Blob e URL.createObjectURL ()
  4. Finalmente, atribua o URL criado ao href de uma tag âncora com um atributo de download e, em seguida, clique programaticamente na tag âncora para solicitar um download

Vamos repassar cada etapa e escrever o código necessário para isso. Mas, primeiro, precisamos configurar um aplicativo React e uma IU do Chakra.

Configurando um aplicativo React

Para configurar um aplicativo React de demonstração, use Criar aplicativo React . Certifique-se de ter Node>=8.10 e npm>=5.6 instalado:

 npx create-react-app export-array-demo
cd export-array-demo
npm start

Em seguida, instale a IU do Chakra:

 npm i @ chakra-ui/react @ emotion/react @ emotion/estilizado framer-motion
npm i @ chakra-ui/icons

Chakra UI é uma biblioteca de componentes de código aberto para React que fornece um conjunto de componentes simples, modulares e acessíveis que tornam mais fácil construir a IU dos aplicativos. Ele será usado para montar rapidamente os elementos da IU que serão necessários.

Para que a IU do Chakra funcione corretamente, você precisa configurar o ChakraProvider (que é o provedor de contexto da biblioteca usando a React Context API ) em index.js :

 import React from'react';
…………
importar {ChakraProvider} de"@ chakra-ui/react" ReactDOM.render (     , document.getElementById ('root')
);

Essa é toda a configuração inicial necessária. Em seguida, é escrever funções para cuidar da matriz para exportação do Excel.

Escreva ArrayToExcel

Para manter a lógica matriz-para-excel separada, crie uma pasta Components/ArrayToExcel em src . Dentro desta pasta, crie dois arquivos ArrayToExcel.js que conterá a função que cuidará da conversão e download, e ArrayToExcelButton.js , que abrigará o botão , modal e outros elementos de IU necessários.

Em ArrayToExcel.js , copie o código aqui , que agora examinarei em bits:

 export const arrayToExcel=(function () {
....
}) ();

Primeiro, todas as funções são agrupadas em um IIFE para garantir que o escopo das variáveis ​​esteja sempre protegido.

Então, há o método convertArrayToTable retornado da função arrayToExcel :

 convertArrayToTable: async (apiArray, fileName)=> { //use as chaves do primeiro objeto de array para formar os cabeçalhos das colunas da tabela const tableHeaders=` $ {Object.keys (apiArray [0]). map (key=>`  $ {key}  `).join ('')} ` ; //agora percorre todos os objetos da matriz para formar as linhas da tabela const tableRows=apiArray.map (obj=> [` $ {Object.keys (obj).map (key=> ` $ {obj [key]===null || obj [key]===''?'': Obj [key]}  `).join ('')}  `]). join (''); const table=` $ {tableHeaders} $ {tableRows} 
`.trim (); const xmlTable=createXMLTable (tabela, fileName); const downloadURL=createFileUrl (xmlTable); downloadFile (downloadURL, fileName); }

A função convertArrayToTable recebe uma matriz de resposta da API JSON (que é uma matriz de objetos) como parâmetro e faz um loop pelas chaves do primeiro objeto para formar a primeira linha, que representará a tabela cabeçalhos ou colunas. Ele também percorre cada objeto e usa seus valores para criar linhas. Cada função map retorna uma matriz, que então join método que converte em uma string. Em seguida, usando literais de modelo, concatenar tableHeader e tableRows para formar uma tabela completa e passá-la para createXMLTable :

 const createXMLTable=(table, fileName)=> { const xmlTable=`         $ {fileName}           $ {mesa}   ` return xmlTable; }

A função createXMLTable usa o SpreadsheetDataXML especificação da Microsoft para descrever como um arquivo de planilha deve ser estruturado. No modelo XML, você está instruindo que o arquivo deve ser uma pasta de trabalho com planilhas e que a planilha específica que exibe a tabela deve ter um título de qualquer que seja o parâmetro fileName e deve exibir linhas de grade.

XML é uma linguagem de marcação usada principalmente para transferir dados entre diferentes programas. No nosso caso, entre a web e um arquivo.xls (extensão de arquivo para arquivos de planilha).

Você pode escrever CSS embutido aqui para definir como deve ser a aparência da planilha exportada.

A seguir está a função createXMLTable que retorna um modelo de arquivo Excel que é passado para createFileUrl :

 const createFileUrl=(xmlTable)=> { const tableBlob=new Blob ([xmlTable], {type:'application/vnd.ms-excel; base64,'}); const downloadURL=URL.createObjectURL (tableBlob); return downloadURL; }

Para criar programaticamente um URL de arquivo para o modelo do Excel, você precisará convertê-lo em um arquivo ou objeto semelhante a um arquivo usando o blob . O método blob leva em uma matriz e um Tipo MIME como argumentos. O método blob retorna um objeto blob, que é passado para o método createObjectURL para criar um URL de arquivo exclusivo que pode então ser passado para um a tag.

A função downloadFile obtém o URL resultante de createFileUrl, e finalmente inicia o download:

 const downloadFile=(downloadURL, fileName)=> { const downloadLink=document.createElement ('a'); document.body.appendChild (downloadLink); downloadLink.download=fileName; downloadLink.href=downloadURL; downloadLink.click (); }

A função downloadFile passa o URL do arquivo para o href da tag âncora que é criada programaticamente e, em seguida, invoca o método de clique no link para acionar o processo de download. O parâmetro fileName atribuído ao download será o nome do arquivo.

E isso é tudo que você precisa fazer para fazer o download de uma série de objetos em um arquivo Excel.

A seguir, vamos configurar nosso componente array-to-excel com elementos da IU do Chakra e também importar arrayToExcel .

Montagem de elementos de IU com Chakra IU

Para construir o componente export-array-to-excel conforme mostrado no início, você precisará de um botão, modal, selecionar entrada e verificar os elementos da IU.

Em ArrayToExcelButton.js , importe estes elementos da IU do Chakra:

 import React, {useState} de"react";
import { Botão, Modal, ModalOverlay, ModalContent, ModalHeader, ModalFooter, ModalBody, ModalCloseButton, Selecione, Caixa de seleção,
} de"@ chakra-ui/react"
importar {DownloadIcon} de'@ chakra-ui/icons'

Chakra exporta esses sete componentes baseados em modais para ajudá-lo a criar qualquer tipo de diálogo modal.

Lembre-se, a partir do fluxo de trabalho declarado no início, quando o botão principal é clicado, ele deve abrir um modal que permite aos usuários escolher entre baixar todas as colunas ou algumas colunas selecionadas (ou seja, selecionar propriedades de cada objeto da matriz):

 const ArrayToExcelButton=({apiArray, fileName, buttonTitle})=> { const [showDownloadModal, setShowDownloadModal]=useState (false); const [columnType, setColumnsType]=useState ("1"); const [selectedColumns, setSelectedColumns]=useState ([]); Retorna ( <>  {showDownloadModal &&  setShowDownloadModal (false)}>    {buttonTitle}    

Selecione o tipo de download:

setColumnsType (e.target.value)}> {columnType==="1"&&

{Object.keys (apiArray [0]). Map ((chave, índice)=> { Retorna ( {(key)}, ) })}

} {columnType==="2"&&
{Object.keys (apiArray [0]). Map ((chave, índice)=> { Retorna (
updateSelectedColumns (e, chave)} > {chave}
) })}
}
} ) } exportar ArrayToExcelButton padrão;

O botão principal que recebe uma prop buttonTitle , alterna a abertura e o fechamento do modal de download usando o estado showDownloadModal .

Dentro do ModalBody , há um elemento Select que alterna o tipo de download a ser executado, “Todas as colunas” ou “Personalizado” usando setColumnsType . Se “All Column” for selecionado, percorra o primeiro objeto de apiArray e liste todas as propriedades do objeto em um parágrafo. Se “Colunas” for selecionado, também percorra o primeiro objeto de apiArray e liste as propriedades de cada objeto ao lado de uma caixa de seleção.

Para controlar as caixas de seleção marcadas, usaremos a função updateSelectedColumns :

 const ArrayToExcelButton=({apiArray, fileName, buttonTitle})=> { ... const updateSelectedColumns=(e, coluna)=> { if (e.target.checked) { setSelectedColumns ([... selectedColumns, coluna]); } outro { setSelectedColumns (selectedColumns.filter (value=> value!==column)); } } ...

Quando uma caixa de seleção é clicada, updateSelectedColumns adiciona ou remove a propriedade do objeto de destino da matriz de estado selectedColumns .

Por último, clicar no botão de download do modal ativa o download de array para excel com a função apiArrayToExcel :

 import React, {useState} de"react";
...
import {arrayToExcel} de"./ArrayToExcel";
importar cloneDeep de"lodash.clonedeep"; const ArrayToExcelButton=({apiArray, fileName, buttonTitle})=> { .... const apiArrayToExcel=()=> { if (columnType==="1") { arrayToExcel.convertArrayToTable (apiArray, fileName) } outro { const customArray=cloneDeep (apiArray); customArray.map (obj=> Object.keys (obj).forEach ((key)=> { if (! selectedColumns.includes (key)) { excluir obj [chave]; } })) arrayToExcel.convertArrayToTable (customArray, fileName) setSelectedColumns ([]); } } ....

Se o valor do tipo de download selecionado for “Todas as colunas”, a função apiArrayToExcel simplesmente chama o método convertArrayToTable de arrayToExcel passando apiArray e fileName props como argumentos. Caso contrário, se o valor for Custom , ele duplica a matriz apiArray usando cloneDeep do lodash e percorre objetos individuais em customArray excluindo chaves de objeto (junto com seus valores correspondentes) que não estão presentes na matriz selectedColumns .

Como os arrays JavaScript são tipos de referência, simplesmente atribuir apiArray a uma nova variável criará apenas uma cópia superficial e qualquer alteração feita em customArray afetará apiArray . Para evitar isso, clone profundo a matriz usando cloneDeep . O método lodash cloneDeep cria um clone profundo de uma matriz:

 npm i-salvar lodash.clonedeep

Com isso, o componente export-array-to-excel está pronto!

Observação, adicionei alguns estilos embutidos para manter as coisas simples e harmoniosas. Idealmente, você deve manter os estilos separados.

Para testar nosso componente array-to-excel, vamos fazer uma simulação de chamada de busca de API em App.js :

 import React, {useState, useEffect} de"react";
import ArrayToExcelButton de"./Components/ArrayToExcel/ArrayToExcelButton" const App=()=> { const [userData, setUserData]=useState ([]); const [carregando, setLoading]=useState (true); const fetchJsonArray=async ()=> { tentar { resposta const=aguarda busca ('https://jsonfy.com/users'); deixe jsonArray=esperar a resposta.json (); setUserData (jsonArray); setLoading (false); } catch (erro) { console.log (error.message); setLoading (false); } } useEffect (()=> { fetchJsonArray (); }, []) Retorna ( 
{carregando ?

Carregando

: }
); } exportar aplicativo padrão;

Importe ArrayToExcelButton e passe userData para ele como adereços. Inicie o aplicativo com npm run start e verifique se o botão funciona bem.

Uma captura de tela do componente export-array-to-excel

O código completo para este projeto de demonstração pode ser encontrado em meu GitHub .

Conclusão

Parabéns! Você acabou de aprender como exportar uma matriz de objetos para um arquivo Excel usando um componente React reutilizável. Como mencionei antes, esta é uma solicitação de recurso que você provavelmente encontrará ocasionalmente como desenvolvedor, especialmente se estiver trabalhando em projetos de painel de administrador. Agora, vá em frente e crie algo ótimo 🙂

A postagem Construir um componente React reutilizável para exportar arrays para o Excel apareceu primeiro no LogRocket Blog .

Source link