Como posso exportar tabelas para o Excel de uma página da web [fechado]

97

Como posso exportar tabelas para o Excel de uma página da web. Quero que a exportação contenha toda a formatação e cores.

code511788465541441
fonte
9
A maneira mais fácil é provavelmente exportar um documento HTML, que o Excel pode abrir.
Pekka,
@Pekka Eu tentei isso, ele perde toda a formatação / css / tamanho da coluna etc
code511788465541441
3
@user onde você está declarando tamanhos de coluna e tal? Não estou muito familiarizado com a exportação de dados para o Excel, mas você pode precisar declará-los inline, ou seja,<td style="background-color: ...
Pekka
@ usuário - há pelo menos dois problemas diferentes aqui: 1) formatar os dados para que apareçam corretamente no Excel e 2) exportar os dados usando Javascript para que defina o tipo MIME corretamente, solicitando ao usuário que salve o arquivo . Você está tentando resolver esses dois problemas?
nrabinowitz de
10
Por que isso foi considerado "baseado em opinião"? Esta é uma questão técnica muito direta.
brandizzi

Respostas:

75

De longe, a exportação mais limpa e fácil de tabelas para o Excel é o plugin Jquery DataTables Table Tools. Você obtém uma grade que classifica, filtra, ordena e pagina seus dados e, com apenas algumas linhas extras de código e dois pequenos arquivos incluídos, você exporta para Excel, PDF, CSV, para a área de transferência e para a impressora.

Este é todo o código necessário:

  $(document).ready( function () {
    $('#example').dataTable( {
        "sDom": 'T<"clear">lfrtip',
        "oTableTools": {
            "sSwfPath": "/swf/copy_cvs_xls_pdf.swf"
        }
    } );
} );

Portanto, rápido de implantar, sem limitações do navegador, nenhuma linguagem do lado do servidor necessária e, acima de tudo, muito FÁCIL de entender. É uma situação em que todos ganham. A única coisa que ela tem limites, no entanto, é a formatação estrita de colunas.

Se a formatação e as cores são destruidores absolutos, o único método 100% confiável para vários navegadores que descobri é usar uma linguagem do lado do servidor para processar arquivos Excel adequados a partir do seu código. Minha solução preferida é PHPExcel. É o único que encontrei até agora que lida positivamente com a exportação com formatação para uma versão MODERNA do Excel de qualquer navegador quando você não fornece nada além de HTML. Deixe-me esclarecer, porém, definitivamente não é tão fácil quanto a primeira solução e também consome alguns recursos. No entanto, o lado positivo também pode gerar saída direta para PDF. E, depois de configurá-lo, ele simplesmente funciona, sempre.

ATUALIZAÇÃO - 15 de setembro de 2016: O TableTools foi descontinuado em favor de um novo plug-in chamado " botões ". Essas ferramentas executam as mesmas funções da antiga extensão TableTools, mas são MUITO mais fáceis de instalar e usam downloads de HTML5 para navegadores modernos, com a capacidade de retornar ao download do Flash original para navegadores que não suportam o padrão HTML5. Como você pode ver pelos muitos comentários desde que publiquei esta resposta em 2011, a principal fraqueza do TableTools foi abordada. Ainda não consigo recomendar DataTables o suficiente para lidar com grandes quantidades de dados de forma simples, tanto para o desenvolvedor quanto para o usuário.

bpeterson76
fonte
2
DataTables é totalmente Javascript. Apenas o elemento TableTools usa Flash, e é minúsculo. Eu NUNCA usaria Flash de boa vontade em nenhum dos meus produtos!
bpeterson76
16
Eu entendo e concordo. Mesmo assim - embora minúsculo - há um objeto .swf lá e ele não pode ser executado sem o Flash.
magma
8
Uma solução tão boa, mas é uma pena que precisa do Flash.
jnthnclrk
Olá, você pode mostrar um exemplo completo, eu sou muito novato para fazer funcionar sem o exemplo!
NoobTom
1
@PramodGaikwad, não, Datatables substituiria a tabela NG. Eles são efetivamente a mesma funcionalidade, mas o Datatables é MUITO mais maduro e tem muitos, muitos mais recursos. Há um spinoff de Datatables criado especificamente para Angular: l-lin.github.io/angular-datatables/#/welcome
bpeterson76
42

Há muito tempo, descobri que o Excel abriria um arquivo HTML com uma tabela se o enviássemos com o tipo de conteúdo do Excel. Considere o documento acima:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Java Friends</title>
</head>
<body>
  <table style="font-weight: bold">
    <tr style="background-color:red"><td>a</td><td>b</td></tr>
    <tr><td>1</td><td>2</td></tr>
  </table>    
</body>
</html>

Corri o seguinte bookmarklet nele:

javascript:window.open('data:application/vnd.ms-excel,'+document.documentElement.innerHTML);

e, na verdade, baixei como um arquivo Excel. No entanto , não obtive o resultado esperado - o arquivo foi aberto no OpenOffice.org Writer. Esse é o meu problema: não tenho Excel nesta máquina, por isso não posso experimentá-lo melhor. Além disso, esse truque funcionou mais ou menos seis anos atrás com navegadores mais antigos e uma versão antiga do MS Office, então realmente não posso dizer se funcionará hoje.

De qualquer forma, no documento acima adicionei um botão que faria o download de todo o documento como um arquivo Excel, em teoria:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Java Friends</title>
</head>
<body>
  <table style="font-weight: bold">
    <tr style="background-color:red"><td>a</td><td>b</td></tr>
    <tr><td>1</td><td>2</td></tr>
    <tr>
      <td colspan="2">
        <button onclick="window.open('data:application/vnd.ms-excel,'+document.documentElement.innerHTML);">
            Get as Excel spreadsheet
        </button>
      </td>
    </tr>
  </table>    
</body>
</html>

Salve em um arquivo e clique no botão. Eu amo saber se funcionou ou não, então eu pedir-lhe para comentar até mesmo para dizer que não funcionou.

Brandizzi
fonte
11
Funcionou adicionando uma substituição no final: window.open ('data: application / vnd.ms-excel,' + document.getElementById ('table'). OuterHTML.replace (/ / g, '% 20')) ;
VSP
6
Forma alternativa (recomendada): window.open ('data: application / vnd.ms-excel,' + encodeURIComponent (document.getElementById ('table'). OuterHTML));
VSP de
5
Funciona perfeitamente no firefox, envolva sua tabela em um div e depois chame o id com document.getElementById('id').innerHTMLpara selecionar seletivamente apenas a mesa, caso contrário, todo o seu material será exportado para a planilha. Não funciona no IE antigo, apenas abre uma nova janela com todo o html do título
Abraham Brookes
1
Esta solução simples funciona muito bem. Veja esta pergunta duplicada para poder definir o nome do arquivo e também o nome da planilha. Mesmo tipo de solução; stackoverflow.com/questions/17126453/…
Espen Schulstad
2
Isso não funciona mais no Office 365 devido a medidas de segurança mais rígidas. O arquivo do Excel deve ser um documento VERDADEIRO do Excel ou irá gerar um erro ao abrir.
Phil
12

É possível usar o antigo formato XML do Excel 2003 (antes do OpenXML) para criar uma string que contém o XML desejado e, no lado do cliente, você pode usar um URI de dados para abrir o arquivo usando o tipo Mime XSL ou enviar o arquivo para o cliente usando o tipo MIME do Excel "Content-Type: application / vnd.ms-excel" do lado do servidor.

  1. Abra o Excel e crie uma planilha com a formatação e as cores desejadas.
  2. Salve a pasta de trabalho do Excel como "Planilha XML 2003 (* .xml)"
  3. Abra o arquivo resultante em um editor de texto como o bloco de notas e copie o valor em uma string em seu aplicativo
  4. Supondo que você use a abordagem do lado do cliente com um uri de dados, o código ficaria assim:
    
    <script type="text/javascript">
    var worksheet_template = '<?xml version="1.0"?><ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'+
                 '<ss:Styles><ss:Style ss:ID="1"><ss:Font ss:Bold="1"/></ss:Style></ss:Styles><ss:Worksheet ss:Name="Sheet1">'+
                 '<ss:Table>{{ROWS}}</ss:Table></ss:Worksheet></ss:Workbook>';
    var row_template = '<ss:Row ss:StyleID="1"><ss:Cell><ss:Data ss:Type="String">{{name}}</ss:Data></ss:Cell></ss:Row>';
    </script>
    
    
  5. Em seguida, você pode usar a substituição de string para criar uma coleção de linhas a serem inseridas em seu modelo de planilha
    
    <script type="text/javascript">
    var rows = document.getElementById("my-table").getElementsByTagName('tr'),
      row_data = '';
    for (var i = 0, length = rows.length; i < length; ++i) {
    row_data += row_template.replace('{{name}}', rows[i].getElementsByTagName('td')[0].innerHTML);
    }
    </script>
    
    
  6. Depois de coletar as informações, crie a string final e abra uma nova janela usando o URI de dados

    
    <script type="text/javascript">
    var worksheet = worksheet_template.replace('{{ROWS}}', row_data);

    window.open('data:application/vnd.ms-excel,'+worksheet); </script>

É importante notar que os navegadores mais antigos não suportam o esquema de URI de dados, portanto, pode ser necessário produzir o lado do servidor de arquivos para os navegadores que não o suportam.

Você também pode precisar realizar a codificação base64 no conteúdo do URI de dados, o que pode exigir uma biblioteca js , bem como adicionar a string '; base64' após o tipo mime no URI de dados.

samshull
fonte
Embora seja bom usar OpenXML, esta solução não funcionará em tabelas com colspans ou rowspans sem muito trabalho no gerador de javascript
Eduardo Molteni
1
Obrigado por me ensinar algo em vez de me dizer para usar um plugin, muito apreciado. Vale a pena mencionar que essa abordagem ainda funciona bem hoje.
Benjamin Gruenbaum
Interessante, tentei essa abordagem. Acabei de obter todo o <? Xml version = "1.0"?> <Ss: Workbook xmlns: ss = "urn: schemas-microsoft-com: office: spreadsheet"> '+' <ss: Styles> <ss: Style ss : ID = "1"> <ss: Font ss: Bold = "1" /> </ ss: Style> </ ss: Styles> <ss: Worksheet ss: Name = "Sheet1"> '+' <ss: Tabela> valores com minhas strings escritas em uma célula, incluindo todas as linhas em uma célula. o que estou perdendo?
CromeX
6

O Excel tem um recurso pouco conhecido chamado "consultas da Web", que permite recuperar dados de quase todas as páginas da Web sem programação adicional.

Uma consulta da web basicamente executa uma solicitação HTTP diretamente do Excel e copia alguns ou todos os dados recebidos (e, opcionalmente, a formatação) para a planilha.

Depois de definir a consulta da web, você pode atualizá-la a qualquer momento, mesmo sem sair do Excel. Assim, você não precisa realmente "exportar" os dados e salvá-los em um arquivo - você prefere atualizar os dados como em um banco de dados.

Você pode até mesmo fazer uso de parâmetros de URL, fazendo com que o Excel solicite determinados critérios de filtro, etc ...

No entanto, os contras que observei até agora são:

  • os dados carregados dinamicamente não são acessíveis porque o Javascript não é executado
  • O comprimento do URL é limitado

Aqui está uma pergunta sobre como criar consultas da web no Excel. Ele leva a um site de Ajuda da Microsoft sobre como obter dados externos de uma página da Web

HAL 9000
fonte
Isso também não funcionará se o url estiver atrás de uma parede de login.
Achshar
Ele funciona com autenticação básica e também baseada em formulário, mas com a última talvez você precise clicar em "editar consulta" para inserir novamente as credenciais e obter um novo cookie a partir do momento
HAL 9000
5

Este é um php, mas talvez você possa alterá-lo para javascript:

<?php>
$colgroup = str_repeat("<col width=86>",5);
$data = "";
$time = date("M d, y g:ia");
$excel = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns=\"http://www.w3.org/TR/REC-html40\">
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html>
<head>
<meta http-equiv=\"Content-type\" content=\"text/html;charset=utf-8\" />
<style id=\"Classeur1_16681_Styles\">
.xl4566 {
color: red;
}
</style>
</head>
<body>
<div id=\"Classeur1_16681\" align=center x:publishsource=\"Excel\">
<table x:str border=0 cellpadding=0 cellspacing=0 style=\"border-collapse: collapse\">
<colgroup>$colgroup</colgroup>
<tr><td class=xl2216681><b>Col1</b></td><td class=xl2216681><b>Col2</b></td><td class=xl2216681 ><b>Col3</b></td><td class=xl2216681 ><b>Col4</b></td><td class=xl2216681 ><b>Col5</b></td></tr>
<tr><td class=xl4566>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
</table>
</div>
</body>
</html>";
  $fname = "Export".time().".xls";
  $file = fopen($fname,"w+");
  fwrite($file,$excel);
  fclose($file);
  header('Content-Type: application/vnd.ms-excel');
  header('Content-Disposition: attachment; filename="'.basename($fname).'"');
  readfile($fname);
  unlink($fname); ?>    
RedSoxFan
fonte
5

Primeiro, eu não recomendaria tentar exportar Html e espero que a instância do Excel do usuário o pegue. Minha experiência mostra que esta solução está repleta de problemas, incluindo incompatibilidades com clientes Macintosh e enviar um erro para o usuário de que o arquivo em questão não é do formato especificado. A solução mais amigável e à prova de balas é aquela do lado do servidor, onde você usa uma biblioteca para construir um arquivo Excel real e enviar de volta para o usuário. A próxima melhor solução e uma solução mais universal seria usar o formato Open XML. Eu encontrei alguns raros problemas de compatibilidade com versões mais antigas do Excel, mas, de modo geral, isso deve fornecer uma solução que funcionará em qualquer versão do Excel, incluindo Macs.

XML aberto

Thomas
fonte
4

mozilla ainda suporta URIs de base 64. Isso permite que você componha dinamicamente o conteúdo binário usando javascript:

<a href="data:application/vnd.ms-excel<base64 encoded binary excel content here>"> download xls</a>

se o seu arquivo Excel não for muito sofisticado (sem diagramas, fórmulas, macros), você pode pesquisar o formato e compor bytes para o seu arquivo, então codificá-los com base64 e colocá-los no href

consulte https://developer.mozilla.org/en/data_URIs

Pavlonator
fonte
2

Na verdade, isso é mais simples do que você pensa: "Apenas" copie a tabela HTML (ou seja: O código HTML da tabela) para a área de transferência. O Excel sabe decodificar tabelas HTML; vai até tentar preservar os atributos.

A parte difícil é "copiar a tabela para a área de transferência", uma vez que não existe uma maneira padrão de acessar a área de transferência do JavaScript. Veja esta postagem do blog: Acessando a área de transferência do sistema com JavaScript - Um Santo Graal?

Agora tudo que você precisa é a tabela como HTML. Eu sugiro jQuery e o método html () .

Aaron Digulla
fonte
2

Este código é apenas para o IE, por isso só é útil em situações em que você sabe que todos os seus usuários usarão o IE (como, por exemplo, em alguns ambientes corporativos).

<script Language="javascript">
function ExportHTMLTableToExcel()
{
   var thisTable = document.getElementById("tbl").innerHTML;
   window.clipboardData.setData("Text", thisTable);
   var objExcel = new ActiveXObject ("Excel.Application");
   objExcel.visible = true;

   var objWorkbook = objExcel.Workbooks.Add;
   var objWorksheet = objWorkbook.Worksheets(1);
   objWorksheet.Paste;
}
</script>
NakedBrunch
fonte
Tentei usar este código, ele abriu a tabela no excel, mas não no formato correto parece que apenas copiou o código html nas tabelas. desta forma: <TD class = "" bgColor = # ed9fff> SARTIN, DAN </TD> <TD class = "" bgColor = # ed9fff> BALAEZ, BARBARA </TD> Alguma sugestão?
Fahad de
Isso porque ele usou innerHTML. O elemento que ele está obtendo É a tabela, então deve ser outerHTML. Fiz a edição
user1566694
Recebo o erro: "O servidor de automação não pode criar o objeto" ao criar ActiveXObject. Como posso corrigir isso?
Nk SP
2

Premissas:

  1. determinado url

  2. a conversão deve ser feita no lado do cliente

  3. sistemas são Windows, Mac e Linux

Solução para Windows:

código python que abre a janela ie e tem acesso a ela: a variável theurl contém o url ('http: //')

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate(theurl)

Nota: se a página não estiver acessível diretamente, mas faça o login, você precisará lidar com isso inserindo os dados do formulário e emulando as ações do usuário com python

aqui está o exemplo

from win32com.client import Dispatch
ie.Document.all('username').value=usr
ie.Document.all('password').value=psw

da mesma maneira para recuperação de dados de uma página da web. Digamos que o elemento com id 'el1' contenha os dados. recupere o texto do elemento para a variável

el1 = ie.Document.all('el1').value

então, quando os dados estão na variável python, você pode abrir a tela do Excel de maneira semelhante usando python:

from win32com.client import Dispatch
xlApp = Dispatch("Excel.Application")
xlWb = xlApp.Workbooks.Open("Read.xls")
xlSht = xlWb.WorkSheets(1)
xlSht.Cells(row, col).Value = el1

Solução para Mac:

apenas a dica: use AppleScript - tem API simples e semelhante à win32com.client Dispatch

Solução para Linux:

java.awt.Robot pode funcionar para isso, basta clicar, pressionar a tecla (podem ser usadas teclas de atalho), mas nenhuma API para Linux que eu conheça que possa funcionar tão simples quanto AppleScript

Pavlonator
fonte
1

uma simples pesquisa no google mostrou isto:

Se os dados são na verdade uma página HTML e NÃO foram criados por ASP, PHP ou alguma outra linguagem de script, e você está usando o Internet Explorer 6 e tem o Excel instalado em seu computador, simplesmente clique com o botão direito na página e veja através do menu. Você deverá ver "Exportar para Microsoft Excel". Se todas essas condições forem verdadeiras, clique no item do menu e após alguns prompts ele será importado para o Excel.

se você não puder fazer isso, ele fornece um método alternativo de "arrastar e soltar":

http://www.mrkent.com/tools/converter/

SQueryL
fonte
1

E agora existe uma maneira melhor.

SDK do OpenXML para JavaScript.

https://openxmlsdkjs.codeplex.com/

Eric Hartford
fonte
hmmm, baixei e tentei executar os exemplos no Chrome mais recente, acabei de receber erros :(
Josh Mc
0

Existem duas maneiras práticas de fazer isso automaticamente, enquanto apenas uma solução pode ser usada em todos os navegadores. Em primeiro lugar, você deve usar a especificação open xml para construir a planilha do Excel. Existem plug-ins gratuitos da Microsoft disponíveis que tornam esse formato também disponível para versões anteriores do Office. O xml aberto é padrão desde o Office 2007. As duas formas são óbvias do lado do servidor ou do cliente.

A implementação do cliente usa um novo padrão de CSS que permite armazenar dados em vez de apenas a URL dos dados. Esta é uma ótima abordagem porque você não precisa de nenhum servercall, apenas os dados e algum javascript. A desvantagem de matar é que a Microsoft não oferece suporte a todas as partes dele nas versões atuais do IE (não sei sobre o IE9). A Microsoft restringe os dados para serem imagens, mas precisaremos de um documento. No firefox funciona muito bem. Para mim, o IE foi o ponto crucial.

A outra maneira é usar uma implementação do lado do servidor. Deve haver muitas implementações de XML aberto para todas as linguagens. Você só precisa agarrar um. Na maioria dos casos, será a maneira mais simples de modificar um Viewmodel para resultar em um Documento, mas com certeza você pode enviar todos os dados do Clientside de volta ao servidor e fazer o mesmo.

sra
fonte
O votante negativo pode comentar qual é o motivo do voto negativo?
sra
0
   function normalexport() {

       try {
           var i;
           var j;
           var mycell;
           var tableID = "tblInnerHTML";
           var drop = document.getElementById('<%= ddl_sections.ClientID %>');
           var objXL = new ActiveXObject("Excel.Application");
           var objWB = objXL.Workbooks.Add();
           var objWS = objWB.ActiveSheet;
           var str = filterNum(drop.options[drop.selectedIndex].text);
           objWB.worksheets("Sheet1").activate; //activate dirst worksheet
           var XlSheet = objWB.activeSheet; //activate sheet
           XlSheet.Name = str; //rename


           for (i = 0; i < document.getElementById("ctl00_ContentPlaceHolder1_1").rows.length - 1; i++) {
               for (j = 0; j < document.getElementById("ctl00_ContentPlaceHolder1_1").rows(i).cells.length; j++) {
                   mycell = document.getElementById("ctl00_ContentPlaceHolder1_1").rows(i).cells(j);

                   objWS.Cells(i + 1, j + 1).Value = mycell.innerText;

                   //                                                objWS.Cells(i + 1, j + 1).style.backgroundColor = mycell.style.backgroundColor;
               }
           }

           objWS.Range("A1", "L1").Font.Bold = true;
           //                objWS.Range("A1", "L1").Font.ColorIndex = 2;
           //                 objWS.Range("A1", "Z1").Interior.ColorIndex = 47;

           objWS.Range("A1", "Z1").EntireColumn.AutoFit();

           //objWS.Range("C1", "C1").ColumnWidth = 50;

           objXL.Visible = true;

       } catch (err) {
           alert("Error. Scripting for ActiveX might be disabled")
           return
       }
       idTmr = window.setInterval("Cleanup();", 1);

   }


   function filterNum(str) {

       return str.replace(/[ / ]/g, '');
   }
Sameh el Behairy
fonte