¿Cómo puedo exportar tablas a Excel desde una página web? [Cerrado]

97

¿Cómo puedo exportar tablas a Excel desde una página web? Quiero que la exportación contenga todos los formatos y colores.

código511788465541441
fuente
9
La forma más fácil es probablemente exportar un documento HTML, que Excel puede abrir.
Pekka
@Pekka Lo he intentado, pierde todo el formato / css / tamaño de columna
etc.Código511788465541441
3
@usuario, ¿dónde declara los tamaños de columna y demás? No estoy muy familiarizado con la exportación de datos a Excel, pero es posible que deba declararlos en línea, es decir<td style="background-color: ...
Pekka
@user: aquí hay al menos dos problemas diferentes: 1) formatear los datos para que aparezcan correctamente en Excel, y 2) exportar los datos usando Javascript para que establezca el tipo de mime correctamente, lo que le pide al usuario que guarde el archivo . ¿Está tratando de resolver ambos problemas?
nrabinowitz
10
¿Por qué se consideró esto "basado en opiniones"? Ésta es una cuestión técnica muy sencilla.
brandizzi

Respuestas:

75

De lejos, la exportación más limpia y fácil de tablas a Excel es el complemento Jquery DataTables Table Tools. Obtiene una cuadrícula que ordena, filtra, ordena y pagina sus datos, y con solo unas pocas líneas adicionales de código y dos archivos pequeños incluidos, puede exportar a Excel, PDF, CSV, al portapapeles y a la impresora.

Este es todo el código que se requiere:

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

Por lo tanto, rápido de implementar, sin limitaciones del navegador, sin necesidad de un idioma del lado del servidor y, sobre todo, muy FÁCIL de entender. Es un ganar-ganar. Sin embargo, en lo único que tiene límites es en el formato estricto de las columnas.

Si el formato y los colores son factores absolutos, el único método 100% confiable y de navegador cruzado que he encontrado es usar un lenguaje del lado del servidor para procesar archivos de Excel adecuados desde su código. Mi solución de elección es PHPExcel. Es la única que he encontrado hasta ahora que maneja positivamente la exportación con formato a una versión MODERNA de Excel desde cualquier navegador cuando no le da nada más que HTML. Sin embargo, permítanme aclarar que definitivamente no es tan fácil como la primera solución, y también es un poco acaparador de recursos. Sin embargo, en el lado positivo, también se puede imprimir directamente en PDF. Y, una vez que lo configura, simplemente funciona, siempre.

ACTUALIZACIÓN - 15 de septiembre de 2016: TableTools ha sido descontinuado a favor de un nuevo complemento llamado " botones " Estas herramientas realizan las mismas funciones que la antigua extensión TableTools, pero son MUCHO más fáciles de instalar y hacen uso de descargas HTML5 para navegadores modernos. con la capacidad de recurrir a la descarga Flash original para navegadores que no son compatibles con el estándar HTML5. Como puede ver en los muchos comentarios desde que publiqué esta respuesta en 2011, se ha abordado la principal debilidad de TableTools. Todavía no puedo recomendar DataTables lo suficiente para manejar grandes cantidades de datos de manera simple, tanto para el desarrollador como para el usuario.

bpeterson76
fuente
2
DataTables es completamente Javascript. Solo el elemento TableTools usa Flash, y es minúsculo. ¡NUNCA usaría Flash voluntariamente en ninguno de mis productos!
bpeterson76
16
Entiendo y estoy de acuerdo. Pero aún así, por minúsculo que sea, hay un objeto .swf allí y no puede ejecutarse sin Flash.
magma
8
Es una gran solución, pero es una pena que necesite Flash.
jnthnclrk
Hola, ¿puedes mostrar un ejemplo completo, soy demasiado novato para hacerlo funcionar sin el ejemplo?
NoobTom
1
@PramodGaikwad, no, Datatables reemplazaría a NG-table. Son efectivamente la misma funcionalidad, pero Datatables es MUCHO más maduro y tiene muchas, muchas más características. Hay un derivado de Datatables creado específicamente para Angular: l-lin.github.io/angular-datatables/#/welcome
bpeterson76
42

Hace mucho tiempo, descubrí que Excel abriría un archivo HTML con una tabla si lo enviamos con el tipo de contenido de Excel. Considere el documento anterior:

<!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>

Ejecuté el siguiente marcador en él:

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

y de hecho lo tengo descargable como un archivo de Excel. Sin embargo , no obtuve el resultado esperado: el archivo estaba abierto en OpenOffice.org Writer. Ese es mi problema: no tengo Excel en esta máquina, así que no puedo probarlo mejor. Además, este truco funcionó hace más o menos seis años con navegadores más antiguos y una versión antigua de MS Office, por lo que realmente no puedo decir si funcionará hoy.

De todos modos, en el documento anterior agregué un botón que descargaría el documento completo como un archivo de Excel, en teoría:

<!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>

Guárdelo en un archivo y haga clic en el botón. Me encantaría saber si funcionó o no, así que les pido que comenten incluso por decir que no funcionó.

brandizzi
fuente
11
Lo hizo funcionar agregando un reemplazo al final: window.open ('data: application / vnd.ms-excel,' + document.getElementById ('table'). OuterHTML.replace (/ / g, '% 20')) ;
VSP
6
Vía alternativa (recomendada): window.open ('datos: aplicación / vnd.ms-excel,' + encodeURIComponent (document.getElementById ('tabla'). OuterHTML));
VSP
5
Funciona perfectamente en Firefox, envuelve tu tabla en un div y luego llama a la identificación con document.getElementById('id').innerHTMLpara tomar selectivamente solo la tabla; de lo contrario, todas tus cosas se exportan a la hoja de cálculo. Sin embargo, no funciona en el IE antiguo, solo abre una nueva ventana con todo el html en el título
Abraham Brookes
1
Esta sencilla solución funciona bien. Mire esta pregunta duplicada para poder establecer un nombre de archivo y también un nombre de hoja de trabajo. Mismo tipo de solución; stackoverflow.com/questions/17126453/…
Espen Schulstad
2
Esto ya no funciona en Office 365 debido a medidas de seguridad más estrictas. El archivo de Excel debe ser un documento de Excel VERDADERO o arrojará un error al abrir.
Phil
12

Es posible usar el antiguo formato XML de Excel 2003 (antes de OpenXML) para crear una cadena que contenga el XML deseado, luego, en el lado del cliente, podría usar un URI de datos para abrir el archivo usando el tipo de mime XSL, o enviar el archivo al cliente utilizando el tipo MIME de Excel "Content-Type: application / vnd.ms-excel" desde el lado del servidor.

  1. Abra Excel y cree una hoja de trabajo con el formato y los colores que desee.
  2. Guarde el libro de Excel como "Hoja de cálculo XML 2003 (* .xml)"
  3. Abra el archivo resultante en un editor de texto como el bloc de notas y copie el valor en una cadena en su aplicación
  4. Suponiendo que utiliza el enfoque del lado del cliente con una uri de datos, el código se vería así:
    
    <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. Luego, puede usar el reemplazo de cadenas para crear una colección de filas que se insertarán en su plantilla de hoja de trabajo
    
    <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. Una vez que tenga la información recopilada, cree la cadena final y abra una nueva ventana usando el URI de datos

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

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

Vale la pena señalar que los navegadores más antiguos no admiten el esquema de URI de datos, por lo que es posible que deba generar el lado del servidor de archivos para aquellos navegadores que no lo admitan.

También es posible que deba realizar la codificación base64 en el contenido del URI de datos, lo que puede requerir una biblioteca js , además de agregar la cadena '; base64' después del tipo mime en el URI de datos.

samshull
fuente
Aunque es bueno usar OpenXML, esta solución no funcionará en tablas con colspans o rowspans sin mucho trabajo en el generador de JavaScript
Eduardo Molteni
1
Gracias por enseñarme algo en lugar de decirme que use un complemento, muy apreciado. Vale la pena mencionar que este enfoque todavía funciona muy bien hoy.
Benjamin Gruenbaum
Interesante, probé este enfoque. Acabo de obtener la <? 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: Tabla> valores con mis cadenas escritas en una celda, incluidas todas las filas en una celda. ¿Qué me estoy perdiendo?
CromeX
6

Excel tiene una característica poco conocida llamada "consultas web" que le permite recuperar datos de casi todas las páginas web sin programación adicional.

Una consulta web básicamente ejecuta una solicitud HTTP directamente desde Excel y copia algunos o todos los datos recibidos (y, opcionalmente, el formato) en la hoja de trabajo.

Una vez que haya definido la consulta web, puede actualizarla en cualquier momento sin siquiera salir de Excel. Por lo tanto, no tiene que "exportar" datos y guardarlos en un archivo; prefiere actualizar los datos como si fuera una base de datos.

Incluso puede hacer uso de parámetros de URL haciendo que Excel le solicite ciertos criterios de filtro, etc.

Sin embargo, las desventajas que he notado hasta ahora son:

  • Los datos cargados dinámicamente no son accesibles porque Javascript no se ejecuta
  • La longitud de la URL es limitada

Aquí hay una pregunta sobre cómo crear consultas web en Excel. Se vincula a un sitio de ayuda de Microsoft sobre cómo obtener datos externos de una página web

HAL 9000
fuente
Esto tampoco funcionará si la URL está detrás de un muro de inicio de sesión.
Achshar
Funciona con autenticación básica y también basada en formularios, pero con esta última es posible que deba hacer clic en "editar consulta" para volver a ingresar las credenciales y obtener una nueva cookie a partir del tiempo
HAL 9000
5

Este es un php pero quizás puedas cambiarlo a 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
fuente
5

Primero, no recomendaría intentar exportar Html y espero que la instancia del usuario de Excel lo recoja. Mi experiencia de que esta solución está plagada de problemas que incluyen incompatibilidades con clientes Macintosh y arrojan un error al usuario de que el archivo en cuestión no tiene el formato especificado. La solución más fácil de usar y a prueba de balas es la del lado del servidor en la que se utiliza una biblioteca para crear un archivo de Excel real y enviarlo de vuelta al usuario. La siguiente mejor solución y solución más universal sería utilizar el formato Open XML. Me he encontrado con algunos problemas raros de compatibilidad con versiones anteriores de Excel, pero en general esto debería brindarle una solución que funcionará en cualquier versión de Excel, incluidas las Mac.

XML abierto

Thomas
fuente
4

mozilla todavía admite URI base 64. Esto le permite componer dinámicamente el contenido binario usando javascript:

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

si su archivo de Excel no es muy elegante (sin diagramas, fórmulas, macros), puede profundizar en el formato y componer bytes para su archivo, luego codificarlos con base64 y ponerlos en el href

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

Pavlonador
fuente
2

En realidad, esto es más simple de lo que piensas: "Simplemente" copie la tabla HTML (es decir: el código HTML de la tabla) en el portapapeles. Excel sabe cómo decodificar tablas HTML; incluso intentará preservar los atributos.

La parte difícil es "copiar la tabla en el portapapeles", ya que no existe una forma estándar de acceder al portapapeles desde JavaScript. Vea esta publicación de blog: Acceso al portapapeles del sistema con JavaScript: ¿un santo grial?

Ahora todo lo que necesita es la tabla como HTML. Sugiero jQuery y el método html () .

Aaron Digulla
fuente
2

Este código es solo IE, por lo que solo es útil en situaciones en las que sabe que todos sus usuarios usarán IE (como, por ejemplo, en algunos entornos 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>
DesnudoBrunch
fuente
Intenté usar este código, abrió la tabla en Excel, pero no el formato correcto parece que simplemente copió el código html en las tablas. así: <TD class = "" bgColor = # ed9fff> SARTIN, DAN </TD> <TD class = "" bgColor = # ed9fff> BALAEZ, BARBARA </TD> ¿Alguna sugerencia?
Fahad
Eso es porque usó innerHTML. El elemento que obtiene ES la tabla, por lo que debería ser HTML externo. Hice la edición
user1566694
Recibo el error: "El servidor de automatización no puede crear un objeto" al crear ActiveXObject. ¿Cómo puedo arreglarlo?
Nk SP
2

Supuestos:

  1. URL dada

  2. la conversión debe realizarse en el lado del cliente

  3. Los sistemas son Windows, Mac y Linux.

Solución para Windows:

código python que abre la ventana ie y tiene acceso a ella: la variable url contiene la url ('http: //')

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

Nota: si no se puede acceder a la página directamente, pero inicie sesión, deberá manejar esto ingresando los datos del formulario y emulando las acciones del usuario con python

aquí está el ejemplo

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

de la misma manera para la recuperación de datos de la página web. Digamos que el elemento con id 'el1' contiene los datos. recuperar el texto del elemento en la variable

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

luego, cuando los datos están en la variable de Python, puede abrir la pantalla de Excel de manera similar 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

Solución para Mac:

solo el consejo: use AppleScript: tiene una API simple y similar a win32com.client Dispatch

Solución para Linux:

java.awt.Robot podría funcionar para esto, tiene clic, presionar tecla (se pueden usar teclas de acceso rápido), pero ninguna API para Linux que yo sepa que puede funcionar tan simple como AppleScript

Pavlonador
fuente
1

La simple búsqueda de Google mostró esto:

Si los datos son en realidad una página HTML y NO han sido creados por ASP, PHP o algún otro lenguaje de programación, y está utilizando Internet Explorer 6 y tiene Excel instalado en su computadora, simplemente haga clic derecho en la página y busque a través del menú. Debería ver "Exportar a Microsoft Excel". Si se cumplen todas estas condiciones, haga clic en el elemento del menú y, después de algunas indicaciones, se importará a Excel.

si no puede hacer eso, le da un método alternativo de "arrastrar y soltar":

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

SQueryL
fuente
1

Y ahora hay una forma mejor.

SDK de OpenXML para JavaScript.

https://openxmlsdkjs.codeplex.com/

Eric Hartford
fuente
hmmm, descargué e intenté ejecutar los ejemplos en la última versión de Chrome, solo obtuve errores :(
Josh Mc
0

Hay dos formas prácticas de hacer esto automáticamente, mientras que solo se puede usar una solución en todos los navegadores. En primer lugar, debe utilizar la especificación xml abierta para crear la hoja de Excel. Hay disponibles complementos gratuitos de Microsoft que hacen que este formato también esté disponible para versiones de Office anteriores. El xml abierto es estándar desde Office 2007. Las dos formas son obvias en el lado del servidor o en el lado del cliente.

La implementación del lado del cliente utiliza un nuevo estándar de CSS que le permite almacenar datos en lugar de solo la URL de los datos. Este es un gran enfoque porque no necesita ninguna llamada al servidor, solo los datos y algo de javascript. La desventaja mortal es que microsoft no admite todas sus partes en las versiones actuales de IE (no sé acerca de IE9). Microsoft restringe los datos para que sean una imagen, pero necesitaremos un documento. En Firefox funciona bastante bien. Para mí, el IE fue el punto de muerte.

La otra forma es utilizar una implementación del lado del servidor. Debería haber muchas implementaciones de XML abierto para todos los lenguajes. Solo necesitas agarrar uno. En la mayoría de los casos, será la forma más sencilla de modificar un modelo de vista para que resulte en un documento, pero seguro que puede enviar todos los datos del lado del cliente al servidor y hacer lo mismo.

sra
fuente
¿Puede el votante en contra por favor comentar cuál es la razón para votar en contra?
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
fuente