Exportieren in CSV mit jQuery und HTML

75

Ich habe tabellarische Daten, die ich ohne Verwendung eines externen Plugins oder einer API nach CSV exportieren muss. Ich habe die window.openMethode verwendet, um die MIME-Typen zu übergeben, hatte aber folgende Probleme:

So ermitteln Sie mithilfe von jquery, ob Microsoft Excel oder Open Office auf dem System installiert ist

Der Code sollte unabhängig von der Tatsache sein, dass das, was auf dem System installiert wird, dh openoffice oder ms excel. Ich glaube, CSV ist das Format, das in beiden Editoren erwartet werden kann.

CODE

    <html>

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>  

<script type="text/JavaScript">
$(document).ready(function(){
    $("#btnExport").click(function(e) {
        var msg = GetMimeTypes();
        //OpenOffice
        window.open('data:application/vnd.oasis.opendocument.spreadsheet,' + $('#dvData').html());
        //MS-Excel
        window.open('data:application/vnd.ms-excel,' + $('#dvData').html());
        //CSV
        window.open('data:application/csv,charset=utf-8,' + $('#dvData').html());
        e.preventDefault();
    });
});

function GetMimeTypes () {
    var message = "";
        // Internet Explorer supports the mimeTypes collection, but it is always empty
    if (navigator.mimeTypes && navigator.mimeTypes.length > 0) {
        var mimes = navigator.mimeTypes;
        for (var i=0; i < mimes.length; i++) {
            message += "<b>" + mimes[i].type + "</b> : " + mimes[i].description + "<br />";
        }
    }
    else {
        message = "Your browser does not support this ";
       //sorry!
    }

    return ( message);
}
</script>

</head>
<body>
<div id="dvData">
<table>
    <tr>
        <th>Column One </th>
        <th>Column Two</th>
        <th>Column Three</th>
    </tr>
    <tr>
        <td>row1 Col1</td>
        <td>row1 Col2</td>
        <td>row1 Col3</td>
   </tr>
   <tr>
        <td>row2 Col1</td>
        <td>row2 Col2</td>
        <td>row2 Col3</td>
   </tr>
      <tr>
        <td>row3 Col1</td>
        <td>row3 Col2</td>
        <td>row3 Col3</td>  
   </tr>
</table>
</div>
<br/>
<input type="button" id="btnExport" value=" Export Table data into Excel " />

</body>

Fehler:

CSV: Über die Browser nicht erkannt

ODS & Excel: Funktioniert, aber ich kann nicht finden, welches generiert werden soll, wenn auf dem System ein Excel oder ein Openoffice installiert ist?

IE Version 8: Es funktioniert überhaupt nicht, öffnet sich in einem neuen Fenster und wie unten Screenshot.

Geben Sie hier die Bildbeschreibung ein

GOK
quelle
Vor welchem ​​Problem stehen Sie genau? Ich verstehe nicht.
Pekka
Ich bin nicht in der Lage, es mit JQuery und HTML nach CSV zu exportieren ... Ich möchte kein Plugin dafür verwenden. Ich habe MIME-Typ verwendet, aber es scheint nicht zu funktionieren
GOK
Zeigen Sie dann Code und beschreiben Sie, was genau nicht wie funktioniert. Welche Fehlermeldungen erhalten Sie? Usw.
Pekka
@ Pekka 웃: Siehe die BEARBEITUNG, wenn Sie jetzt auch nicht verstehen, seien Sie spezifisch, um Fragen zu stellen, danke
GOK
Was ist passiert @Pekka 웃 .... Keine Lösungen von deiner Seite ???
GOK

Antworten:

126

Demo

Eine Erklärung finden Sie unten.

$(document).ready(function() {

  function exportTableToCSV($table, filename) {

    var $rows = $table.find('tr:has(td)'),

      // Temporary delimiter characters unlikely to be typed by keyboard
      // This is to avoid accidentally splitting the actual contents
      tmpColDelim = String.fromCharCode(11), // vertical tab character
      tmpRowDelim = String.fromCharCode(0), // null character

      // actual delimiter characters for CSV format
      colDelim = '","',
      rowDelim = '"\r\n"',

      // Grab text from table into CSV formatted string
      csv = '"' + $rows.map(function(i, row) {
        var $row = $(row),
          $cols = $row.find('td');

        return $cols.map(function(j, col) {
          var $col = $(col),
            text = $col.text();

          return text.replace(/"/g, '""'); // escape double quotes

        }).get().join(tmpColDelim);

      }).get().join(tmpRowDelim)
      .split(tmpRowDelim).join(rowDelim)
      .split(tmpColDelim).join(colDelim) + '"';

    // Deliberate 'false', see comment below
    if (false && window.navigator.msSaveBlob) {

      var blob = new Blob([decodeURIComponent(csv)], {
        type: 'text/csv;charset=utf8'
      });

      // Crashes in IE 10, IE 11 and Microsoft Edge
      // See MS Edge Issue #10396033
      // Hence, the deliberate 'false'
      // This is here just for completeness
      // Remove the 'false' at your own risk
      window.navigator.msSaveBlob(blob, filename);

    } else if (window.Blob && window.URL) {
      // HTML5 Blob        
      var blob = new Blob([csv], {
        type: 'text/csv;charset=utf-8'
      });
      var csvUrl = URL.createObjectURL(blob);

      $(this)
        .attr({
          'download': filename,
          'href': csvUrl
        });
    } else {
      // Data URI
      var csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

      $(this)
        .attr({
          'download': filename,
          'href': csvData,
          'target': '_blank'
        });
    }
  }

  // This must be a hyperlink
  $(".export").on('click', function(event) {
    // CSV
    var args = [$('#dvData>table'), 'export.csv'];

    exportTableToCSV.apply(this, args);

    // If CSV, don't do event.preventDefault() or return false
    // We actually need this to be a typical hyperlink
  });
});
a.export,
a.export:visited {
  display: inline-block;
  text-decoration: none;
  color: #000;
  background-color: #ddd;
  border: 1px solid #ccc;
  padding: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" class="export">Export Table data into Excel</a>
<div id="dvData">
  <table>
    <tr>
      <th>Column One</th>
      <th>Column Two</th>
      <th>Column Three</th>
    </tr>
    <tr>
      <td>row1 Col1</td>
      <td>row1 Col2</td>
      <td>row1 Col3</td>
    </tr>
    <tr>
      <td>row2 Col1</td>
      <td>row2 Col2</td>
      <td>row2 Col3</td>
    </tr>
    <tr>
      <td>row3 Col1</td>
      <td>row3 Col2</td>
      <td>row3 Col3</td>
    </tr>
    <tr>
      <td>row4 'Col1'</td>
      <td>row4 'Col2'</td>
      <td>row4 'Col3'</td>
    </tr>
    <tr>
      <td>row5 &quot;Col1&quot;</td>
      <td>row5 &quot;Col2&quot;</td>
      <td>row5 &quot;Col3&quot;</td>
    </tr>
    <tr>
      <td>row6 "Col1"</td>
      <td>row6 "Col2"</td>
      <td>row6 "Col3"</td>
    </tr>
  </table>
</div>


Ab 2017

Verwendet jetzt HTML5 Blobund URLals bevorzugte Methode mit Data URIals Fallback.

Im Internet Explorer

Andere Antworten schlagen vor window.navigator.msSaveBlob; Es ist jedoch bekannt, dass IE10 / Windows 7 und IE11 / Windows 10 abstürzen . Ob es mit Microsoft Edge funktioniert, ist zweifelhaft (siehe Microsoft Edge Issue Ticket Nr. 10396033 ).

Wenn Sie dies nur in den Microsoft Developer Tools / Console aufrufen, stürzt der Browser ab:

navigator.msSaveBlob(new Blob(["hello"], {type: "text/plain"}), "test.txt");


Vier Jahre nach meiner ersten Antwort enthalten die neuen IE-Versionen IE10, IE11 und Edge. Sie alle stürzen bei einer von Microsoft erfundenen Funktion ab (langsames Klatschen).

Fügen Sie navigator.msSaveBlobSupport auf eigenes Risiko hinzu.


Ab 2013

Normalerweise wird dies mit einer serverseitigen Lösung durchgeführt, aber dies ist mein Versuch einer clientseitigen Lösung. Das einfache Speichern von HTML als Data URIwird nicht funktionieren, ist aber ein hilfreicher Schritt. Damit:

  1. Konvertieren Sie den Tabelleninhalt in eine gültige CSV-formatierte Zeichenfolge. (Dies ist der einfache Teil.)
  2. Erzwingen Sie den Browser zum Herunterladen. Der window.openAnsatz würde in Firefox nicht funktionieren, also habe ich ihn verwendet <a href="{Data URI here}">.
  3. Weisen Sie mithilfe des Attributs des <a>Tags einen Standarddateinamen zu download, der nur in Firefox und Google Chrome funktioniert. Da es sich nur um ein Attribut handelt, wird es elegant abgebaut.

Anmerkungen

Kompatibilität

Das Testen von Browsern umfasst:

  • Firefox 20+, Win / Mac ( funktioniert )
  • Google Chrome 26+, Win / Mac ( funktioniert )
  • Safari 6, Mac ( funktioniert , aber Dateiname wird ignoriert)
  • IE 9+ ( schlägt fehl )

Inhaltskodierung

Die CSV wird korrekt exportiert, aber beim Import in Excel wird das Zeichen üals ausgedrucktä . Excel interpretiert den Wert falsch.

Einführen var csv = '\ufeff';und dann Excel 2013+ richtig interpretiert die Werte.

Wenn Sie Kompatibilität mit Excel 2007 benötigen, fügen Sie an jedem Datenwert UTF-8-Präfixe hinzu. Siehe auch:

Terry Young
quelle
Es funktioniert ganz gut für meine Anforderung; Nur für nimmt nicht das <th> oder den Header für die betreffende Tabelle auf. Ist das beabsichtigt? Was ist, wenn wir zwei Header mit Colspans haben? können wir damit umgehen?
GOK
Ups .. aber ist dere eine Möglichkeit, es zu beheben? Ich überprüfe es auf IE8
GOK
19
Nur eine kurze Anmerkung: Um auch <th> einzuschließen, ersetzen Sie das 'tr: has (td)' durch 'tr: has (td), tr: has (th)' und das 'td' etwas weiter unten durch ' td, th '.
Wouter
PS Wenn jemand Probleme hat, den Dateinamen zum Laufen zu bringen, hat diese verwandte SO-Frage eine Lösung: stackoverflow.com/questions/23816005/…
clifgriffin
4
Fügen Sie den Tabellenkopf (Implementierung von @ Wouter-Vorschlägen) wie folgt ein: 1) var $ rows = $ table.find ('tr: has (td), tr: has (th)'), 2) $ cols = $ row.find ( 'td, th');
Bala
7

Ich bin mir nicht sicher, ob der obige CSV-Generierungscode so gut ist, dass er zu überspringen scheint th Zellen und auch keine Kommas im Wert zulässt. Hier ist mein CSV-Generierungscode, der nützlich sein könnte.

Es muss davon ausgehen , Sie haben $tableVariable , die ein jQuery - Objekt (z. B. var $table = $('#yourtable');)

$rows = $table.find('tr');

var csvData = "";

for(var i=0;i<$rows.length;i++){
                var $cells = $($rows[i]).children('th,td'); //header or content cells

                for(var y=0;y<$cells.length;y++){
                    if(y>0){
                      csvData += ",";
                    }
                    var txt = ($($cells[y]).text()).toString().trim();
                    if(txt.indexOf(',')>=0 || txt.indexOf('\"')>=0 || txt.indexOf('\n')>=0){
                        txt = "\"" + txt.replace(/\"/g, "\"\"") + "\"";
                    }
                    csvData += txt;
                }
                csvData += '\n';
 }
Aktion Dan
quelle
2
 <a id="export" role='button'>
        Click Here To Download Below Report
    </a>
    <table id="testbed_results" style="table-layout:fixed">
        <thead>
            <tr width="100%" style="color:white" bgcolor="#3195A9" id="tblHeader">
                <th>Name</th>
                <th>Date</th>
                <th>Speed</th>
                <th>Column2</th>
                <th>Interface</th>
                <th>Interface2</th>
                <th>Sub</th>
                <th>COmpany result</th>
                <th>company2</th>
                <th>Gen</th>
            </tr>
        </thead>
        <tbody>
            <tr id="samplerow">
                <td>hello</td>
                <td>100</td>
                <td>200</td>
                <td>300</td>
                <td>html2svc</td>
                <td>ajax</td>
                <td>200</td>
                <td>7</td>
                <td>8</td>
                <td>9</td>
            </tr>
            <tr>
                <td>hello</td>
                <td>100</td>
                <td>200</td>
                <td>300</td>
                <td>html2svc</td>
                <td>ajax</td>
                <td>200</td>
                <td>7</td>
                <td>8</td>
                <td>9</td>
            </tr>
        </tbody>
    </table>

    $(document).ready(function () {
        Html2CSV('testbed_results', 'myfilename','export');
    });



    function Html2CSV(tableId, filename,alinkButtonId) {
        var array = [];
        var headers = [];
        var arrayItem = [];
        var csvData = new Array();
        $('#' + tableId + ' th').each(function (index, item) {
            headers[index] = '"' + $(item).html() + '"';
        });
        csvData.push(headers);
        $('#' + tableId + ' tr').has('td').each(function () {

            $('td', $(this)).each(function (index, item) {
                arrayItem[index] = '"' + $(item).html() + '"';
            });
            array.push(arrayItem);
            csvData.push(arrayItem);
        });




        var fileName = filename + '.csv';
        var buffer = csvData.join("\n");
        var blob = new Blob([buffer], {
            "type": "text/csv;charset=utf8;"
        });
        var link = document.getElementById(alinkButton);

        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            link.setAttribute("href", window.URL.createObjectURL(blob));
            link.setAttribute("download", fileName);
        }
        else if (navigator.msSaveBlob) { // IE 10+
            link.setAttribute("href", "#");
            link.addEventListener("click", function (event) {
                navigator.msSaveBlob(blob, fileName);
            }, false);
        }
        else {
            // it needs to implement server side export
            link.setAttribute("href", "http://www.example.com/export");
        }
    }

</script>
Shahid wali
quelle
2
Sie sollten einen Text hinzufügen, warum und wie Ihr Code das Problem löst
Reeno
2

Ein winziges Update für die Antwort von @Terry Young , dh Unterstützung für IE 10+

if (window.navigator.msSaveOrOpenBlob) {
  // IE 10+
  var blob = new Blob([decodeURIComponent(encodeURI(csvString))], {
    type: 'text/csv;charset=' + document.characterSet
  });
  window.navigator.msSaveBlob(blob, filename);
} else {
  // actual real browsers
  //Data URI
  csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvData);

    $(this).attr({
      'download': filename,
      'href': csvData,
      'target': '_blank'
    });
}
Dušan Maďar
quelle
Funktioniert dies für IE9, um HTML-Tabellen zu exportieren, um wie zu übertreffen type: 'data:application/vnd.ms-excel;'? Vielen Dank
Disera
1

Was ist, wenn Sie Ihre Daten im CSV-Format haben und sie zur Anzeige auf der Webseite in HTML konvertieren? Sie können das Plugin http://code.google.com/p/js-tables/ verwenden . Überprüfen Sie dieses Beispiel http://code.google.com/p/js-tables/wiki/Table Da Sie bereits die jQuery-Bibliothek verwenden, habe ich angenommen, dass Sie andere Javascript-Toolkit-Bibliotheken hinzufügen können.

Wenn die Daten im CSV-Format vorliegen, sollten Sie den generischen MIME-Typ "application / octetstream" verwenden können. Alle 3 MIME-Typen, die Sie ausprobiert haben, hängen von der auf dem Client-Computer installierten Software ab.

Zlatin Zlatev
quelle
1

Soweit ich weiß, haben Sie Ihre Daten in einer Tabelle und möchten die CSV aus diesen Daten erstellen. Sie haben jedoch Probleme beim Erstellen der CSV.

Meine Gedanken wären, den Inhalt der Tabelle zu iterieren und zu analysieren und aus den analysierten Daten eine Zeichenfolge zu generieren. Sie können anhand eines Beispiels überprüfen, wie JSON in das CSV-Format konvertiert und in einer Variablen gespeichert wird . Sie verwenden in Ihrem Beispiel jQuery, damit dies nicht als externes Plugin gilt. Dann müssen Sie nur noch die resultierende Zeichenfolge verwenden window.openund application/octetstreamwie vorgeschlagen verwenden.

MervS
quelle