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.
<td style="background-color: ...
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.
<td style="background-color: ...
Respostas:
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.
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.
document.getElementById('id').innerHTML
para 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
É 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.
<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>
<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>
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.
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:
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
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); ?>
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.
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
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 () .
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>
Premissas:
determinado url
a conversão deve ser feita no lado do cliente
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
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":
E agora existe uma maneira melhor.
SDK do OpenXML para JavaScript.
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.
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, '');
}