Comment puis-je exporter des tableaux vers Excel à partir d'une page Web [fermé]

97

Comment puis-je exporter des tableaux vers Excel à partir d'une page Web. Je veux que l'exportation contienne toute la mise en forme et les couleurs.

code511788465541441
la source
9
Le moyen le plus simple est probablement d'exporter un document HTML, qu'Excel peut ouvrir.
Pekka le
@Pekka J'ai essayé ça, il perd tout le formatage / css / taille de colonne etc
code511788465541441
3
@user où déclarez-vous les tailles de colonne et autres? Je ne suis pas très familier avec l'exportation de données vers Excel, mais vous devrez peut-être les déclarer en ligne, c'est<td style="background-color: ...
Pekka
@user - il y a au moins deux problèmes différents ici: 1) formatage des données pour qu'elles apparaissent correctement dans Excel, et 2) exportation des données à l'aide de Javascript afin qu'il définisse correctement le type mime, invitant l'utilisateur à enregistrer le fichier . Essayez-vous de résoudre ces deux problèmes?
nrabinowitz
10
Pourquoi cela a-t-il été considéré comme "basé sur l'opinion"? C'est une question technique très simple.
brandizzi

Réponses:

75

De loin, l'exportation la plus propre et la plus simple des tableaux vers Excel est le plugin Jquery DataTables Table Tools. Vous obtenez une grille qui trie, filtre, ordonne et page vos données, et avec seulement quelques lignes de code supplémentaires et deux petits fichiers inclus, vous obtenez une exportation vers Excel, PDF, CSV, vers le presse-papiers et vers l'imprimante.

C'est tout le code requis:

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

Donc, rapide à déployer, aucune limitation de navigateur, aucun langage côté serveur requis et surtout très FACILE à comprendre. C'est gagnant-gagnant. La seule chose sur laquelle il a des limites, cependant, est le formatage strict des colonnes.

Si le formatage et les couleurs sont des facteurs de rupture absolus, la seule méthode de navigation croisée à 100% fiable que j'ai trouvée consiste à utiliser un langage côté serveur pour traiter les fichiers Excel appropriés à partir de votre code. Ma solution de choix est PHPExcel C'est la seule que j'ai trouvée jusqu'à présent qui gère positivement l'exportation avec mise en forme vers une version MODERNE d'Excel à partir de n'importe quel navigateur lorsque vous ne lui donnez que du HTML. Permettez-moi de clarifier cependant, ce n'est certainement pas aussi facile que la première solution, et c'est aussi un peu une corvée de ressources. Cependant, du côté positif, il peut également sortir directement au format PDF. Et, une fois que vous l'avez configuré, cela fonctionne, à chaque fois.

MISE À JOUR - 15 septembre 2016: TableTools a été abandonné au profit d'un nouveau plugin appelé " boutons ". Ces outils remplissent les mêmes fonctions que l'ancienne extension TableTools, mais sont BEAUCOUP plus faciles à installer et utilisent des téléchargements HTML5 pour les navigateurs modernes, avec la possibilité de revenir au téléchargement Flash d'origine pour les navigateurs qui ne prennent pas en charge la norme HTML5. Comme vous pouvez le voir dans les nombreux commentaires depuis que j'ai publié cette réponse en 2011, la principale faiblesse de TableTools a été corrigée. Je ne peux toujours pas recommander suffisamment DataTables pour gérer simplement de grandes quantités de données, à la fois pour le développeur et l'utilisateur.

bpeterson76
la source
2
DataTables est entièrement Javascript. Seul l'élément TableTools utilise Flash, et c'est minuscule. Je n'utiliserais JAMAIS volontairement Flash dans aucun de mes produits!
bpeterson76
16
Je comprends et je suis d'accord. Mais quand même - même minuscule - il y a un objet .swf là, et il ne peut pas fonctionner sans Flash.
magma
8
Une si bonne solution, mais une telle honte qu'elle a besoin de Flash.
jnthnclrk
Bonjour pouvez-vous montrer un exemple complet, je suis trop noob pour le faire fonctionner sans l'exemple!
NoobTom
1
@PramodGaikwad, non, Datatables remplacerait NG-table. Ce sont en fait les mêmes fonctionnalités, mais Datatables est BEAUCOUP plus mature et a beaucoup plus de fonctionnalités. Il existe un spin-off de Datatables créé spécifiquement pour Angular: l-lin.github.io/angular-datatables/#/welcome
bpeterson76
42

Il y a longtemps, j'ai découvert qu'Excel ouvrirait un fichier HTML avec un tableau si nous l'envoyions avec le type de contenu Excel. Considérez le document ci-dessus:

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

J'ai couru le bookmarklet suivant dessus:

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

et en fait je l'ai téléchargé sous forme de fichier Excel. Cependant , je n'ai pas obtenu le résultat attendu - le fichier était ouvert dans OpenOffice.org Writer. C'est mon problème: je n'ai pas Excel dans cette machine donc je ne peux pas mieux l'essayer. De plus, cette astuce a fonctionné il y a plus ou moins six ans avec des navigateurs plus anciens et une ancienne version de MS Office, donc je ne peux vraiment pas dire si cela fonctionnera aujourd'hui.

Quoi qu'il en soit, dans le document ci-dessus, j'ai ajouté un bouton qui téléchargerait l'intégralité du document sous forme de fichier Excel, en théorie:

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

Enregistrez-le dans un fichier et cliquez sur le bouton. J'adore savoir si cela a fonctionné ou non, je vous demande de commentaires , même pour dire que cela n'a pas fonctionné.

brandizzi
la source
11
Cela a fonctionné en ajoutant un remplacement à la fin: window.open ('data: application / vnd.ms-excel,' + document.getElementById ('table'). ExternalHTML.replace (/ / g, '% 20')) ;
VSP du
6
Méthode alternative (recommandée): window.open ('data: application / vnd.ms-excel,' + encodeURIComponent (document.getElementById ('table'). OutsideHTML));
VSP
5
Fonctionne parfaitement dans Firefox, enveloppez votre table dans un div, puis appelez l'identifiant avec document.getElementById('id').innerHTMLpour saisir sélectivement la table uniquement, sinon tout votre contenu est exporté vers la feuille de calcul. Ne fonctionne pas dans l'ancien IE cependant, ouvre juste une nouvelle fenêtre avec tout le code HTML dans le titre
Abraham Brookes
1
Cette solution simple fonctionne très bien. Regardez cette question en double afin de pouvoir définir le nom de fichier et définir également un nom de feuille de travail. Même type de solution; stackoverflow.com/questions/17126453/…
Espen Schulstad
2
Cela ne fonctionne plus dans Office 365 en raison de mesures de sécurité plus strictes. Le fichier Excel doit être un vrai document Excel ou il générera une erreur lors de l'ouverture.
Phil
12

Il est possible d'utiliser l'ancien format XML Excel 2003 (avant OpenXML) pour créer une chaîne contenant le XML souhaité, puis côté client, vous pouvez utiliser un URI de données pour ouvrir le fichier en utilisant le type mime XSL, ou envoyer le fichier au client en utilisant le type MIME Excel "Content-Type: application / vnd.ms-excel" du côté serveur.

  1. Ouvrez Excel et créez une feuille de calcul avec la mise en forme et les couleurs souhaitées.
  2. Enregistrez le classeur Excel sous «Feuille de calcul XML 2003 (* .xml)»
  3. Ouvrez le fichier résultant dans un éditeur de texte comme le bloc-notes et copiez la valeur dans une chaîne dans votre application
  4. En supposant que vous utilisez l'approche côté client avec un uri de données, le code ressemblerait à ceci:
    
    <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. Ensuite, vous pouvez utiliser le remplacement de chaîne pour créer une collection de lignes à insérer dans votre modèle de feuille de calcul
    
    <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. Une fois les informations collectées, créez la chaîne finale et ouvrez une nouvelle fenêtre en utilisant l'URI de données

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

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

Il est à noter que les navigateurs plus anciens ne prennent pas en charge le schéma URI de données, vous devrez peut-être produire le côté serveur de fichiers pour les navigateurs qui ne le prennent pas en charge.

Vous devrez peut-être également effectuer un encodage en base64 sur le contenu de l'URI de données, ce qui peut nécessiter une bibliothèque js , ainsi que l'ajout de la chaîne '; base64' après le type mime dans l'URI de données.

samshull
la source
Bien qu'il soit agréable d'utiliser OpenXML, cette solution ne fonctionnera pas sur les tables avec des colspans ou des rowspans sans beaucoup de travail sur le générateur javascript
Eduardo Molteni
1
Merci de m'apprendre quelque chose plutôt que de me dire d'utiliser un plugin, très apprécié. Il convient de mentionner que cette approche fonctionne toujours bien aujourd'hui.
Benjamin Gruenbaum
Intéressant, a essayé cette approche. Je viens de récupérer l'intégralité de <? 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: Tableau> valeurs avec mes chaînes écrites dans une cellule, y compris toutes les lignes d'une cellule. Qu'est-ce que je rate?
CromeX
6

Excel a une fonctionnalité peu connue appelée "requêtes Web" qui vous permet de récupérer des données de presque toutes les pages Web sans programmation supplémentaire.

Une requête Web exécute essentiellement une requête HTTP directement à partir d'Excel et copie une partie ou la totalité des données reçues (et éventuellement le formatage) dans la feuille de calcul.

Après avoir défini la requête Web, vous pouvez l'actualiser à tout moment sans même quitter Excel. Vous n'avez donc pas à "exporter" les données et à les enregistrer dans un fichier - vous préférez actualiser les données comme à partir d'une base de données.

Vous pouvez même utiliser les paramètres d'URL en demandant à Excel de vous demander certains critères de filtre, etc.

Cependant, les inconvénients que j'ai remarqués jusqu'à présent sont:

  • les données chargées de manière dynamique ne sont pas accessibles, car Javascript n'est pas exécuté
  • La longueur de l'URL est limitée

Voici une question sur la façon de créer des requêtes Web dans Excel. Il renvoie à un site d'aide Microsoft sur la procédure d'obtention de données externes à partir d'une page Web

HAL 9000
la source
Cela ne fonctionnera pas non plus si l'URL est derrière un mur de connexion.
Achshar le
Cela fonctionne avec l'authentification de base et également basée sur le formulaire, mais avec cette dernière, vous devrez peut-être cliquer sur "modifier la requête" pour saisir à nouveau les informations d'identification et obtenir un nouveau cookie à partir du moment
HAL 9000
5

Ceci est un php mais vous pourrez peut-être le changer en 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
la source
5

Tout d'abord, je ne recommanderais pas d' essayer d'exporter Html et j'espère que l'instance d'Excel de l'utilisateur la récupérera. Mon expérience que cette solution est lourde de problèmes, y compris des incompatibilités avec les clients Macintosh et jette une erreur à l'utilisateur que le fichier en question n'est pas du format spécifié. La solution la plus fiable et la plus conviviale est une solution côté serveur où vous utilisez une bibliothèque pour créer un fichier Excel réel et le renvoyer à l'utilisateur. La meilleure solution suivante et la solution la plus universelle serait d'utiliser le format Open XML. J'ai rencontré quelques rares problèmes de compatibilité avec les anciennes versions d'Excel, mais dans l'ensemble, cela devrait vous donner une solution qui fonctionnera sur n'importe quelle version d'Excel, y compris les Mac.

Open XML

Thomas
la source
4

mozilla prend toujours en charge les URI de base 64. Cela vous permet de composer dynamiquement le contenu binaire en utilisant javascript:

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

si votre fichier excel n'est pas très sophistiqué (pas de diagrammes, de formules, de macros) vous pouvez creuser dans le format et composer des octets pour votre fichier, puis les encoder avec base64 et les mettre dans le href

se référer à https://developer.mozilla.org/en/data_URIs

Pavlonateur
la source
2

C'est en fait plus simple que vous ne le pensez: "Il suffit" de copier le tableau HTML (c'est-à-dire: le code HTML du tableau) dans le presse-papiers. Excel sait comment décoder les tableaux HTML; il essaiera même de préserver les attributs.

La partie la plus difficile est de «copier le tableau dans le presse-papiers» puisqu'il n'y a pas de moyen standard d'accéder au presse-papiers à partir de JavaScript. Voir ce billet de blog: Accéder au presse-papiers système avec JavaScript - Un Saint Graal?

Maintenant, tout ce dont vous avez besoin est le tableau au format HTML. Je suggère jQuery et la méthode html () .

Aaron Digulla
la source
2

Ce code est IE uniquement, il n'est donc utile que dans les situations où vous savez que tous vos utilisateurs utiliseront IE (comme, par exemple, dans certains environnements d'entreprise.)

<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>
NuBrunch
la source
J'ai essayé d'utiliser ce code, il a ouvert la table dans Excel, mais le format correct ne semble pas avoir copié le code html dans les tables. comme ceci: <TD class = "" bgColor = # ed9fff> SARTIN, DAN </TD> <TD class = "" bgColor = # ed9fff> BALAEZ, BARBARA </TD> Des suggestions?
Fahad
C'est parce qu'il a utilisé innerHTML. L'élément qu'il obtient EST la table, il devrait donc être externalHTML. J'ai fait le montage
user1566694
J'obtiens l'erreur: «Le serveur d'automatisation ne peut pas créer d'objet» lors de la création d'ActiveXObject. Comment puis-je y remédier?
Nk SP
2

Hypothèses:

  1. URL donnée

  2. la conversion doit être effectuée côté client

  3. les systèmes sont Windows, Mac et Linux

Solution pour Windows:

code python qui ouvre la fenêtre ie et y a accès: la variableeurl contient l'url ('http: //')

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

Remarque: si la page n'est pas accessible directement, mais que vous vous connectez, vous devrez gérer cela en entrant les données du formulaire et en émulant les actions de l'utilisateur avec python

voici l'exemple

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

de la même manière pour la récupération des données de la page Web Supposons que l'élément avec l'identifiant 'el1' contienne les données. récupérer le texte de l'élément dans la variable

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

alors, lorsque les données sont dans la variable python, vous pouvez ouvrir l'écran Excel de la même manière en utilisant 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

Solution pour Mac:

seulement le conseil: utilisez AppleScript - il a une API simple et similaire à win32com.client Dispatch

Solution pour Linux:

java.

Pavlonateur
la source
1

une simple recherche Google a révélé ceci:

Si les données sont en fait une page HTML et n'ont PAS été créées par ASP, PHP ou un autre langage de script, et que vous utilisez Internet Explorer 6 et que Excel est installé sur votre ordinateur, cliquez simplement avec le bouton droit sur la page et regardez à travers le menu. Vous devriez voir «Exporter vers Microsoft Excel». Si toutes ces conditions sont remplies, cliquez sur l'élément de menu et après quelques invites, il sera importé dans Excel.

si vous ne pouvez pas faire cela, il donne une autre méthode "glisser-déposer":

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

SQueryL
la source
1

Et maintenant, il existe un meilleur moyen.

SDK OpenXML pour JavaScript.

https://openxmlsdkjs.codeplex.com/

Eric Hartford
la source
hmmm, téléchargé et essayé d'exécuter les exemples dans le dernier chrome, vient de recevoir des erreurs :(
Josh Mc
0

Il existe deux façons pratiques de le faire automatiquement, alors qu'une seule solution peut être utilisée dans tous les navigateurs. Tout d'abord, vous devez utiliser la spécification open xml pour créer la feuille Excel. Il existe des plugins gratuits de Microsoft qui rendent ce format également disponible pour les anciennes versions de bureau. Le xml ouvert est standard depuis Office 2007. Les deux manières sont évidentes du côté serveur ou côté client.

L'implémentation côté client utilise une nouvelle norme de CSS qui vous permet de stocker des données au lieu de simplement l'URL des données. C'est une excellente approche car vous n'avez besoin d'aucun appel de serveur, juste des données et du javascript. L'inconvénient est que Microsoft ne prend pas en charge toutes ses parties dans les versions actuelles d'IE (je ne sais pas pour IE9). Microsoft limite les données à une image mais nous aurons besoin d'un document. Dans Firefox, cela fonctionne très bien. Pour moi, l'IE était le point mortel.

L'autre moyen consiste à utiliser une implémentation côté serveur. Il devrait y avoir beaucoup d'implémentations d'Open XML pour toutes les langues. Vous avez juste besoin d'en attraper un. Dans la plupart des cas, ce sera le moyen le plus simple de modifier un modèle de vue pour obtenir un document, mais vous pouvez certainement renvoyer toutes les données du côté client vers le serveur et faire de même.

sra
la source
L'électeur à la baisse peut-il expliquer quelle est la raison du vote à la baisse?
sra le
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
la source