Ich generiere dynamisch ein div, das wie folgt aussieht:
<div id='PrintDiv'>
<table id="mainTable">
<tr>
<td>
Col1
</td>
<td>
Col2
</td>
<td>
Col3
</td>
</tr>
<tr>
<td>
Val1
</td>
<td>
Val2
</td>
<td>
Val3
</td>
</tr>
<tr>
<td>
Val11
</td>
<td>
Val22
</td>
<td>
Val33
</td>
</tr>
<tr>
<td>
Val111
</td>
<td>
Val222
</td>
<td>
Val333
</td>
</tr>
</table>
</div>
Und es gibt noch viele weitere Elemente auf der Seite ... Nun, wie bekomme ich eine CSV-Datei wie diese:
Col1,Col2,Col3
Val1,Val2,Val3
Val11,Val22,Val33
Val111,Val222,Val333
jQuery verwenden?
brauche auch eine Dateispeicher-Dailog-Box wie diese:
Vielen Dank.
Sie können dies nur auf der Clientseite in einem Browser tun, der Data URIs akzeptiert:
data:application/csv;charset=utf-8,content_encoded_as_url
In Ihrem Beispiel muss der Daten-URI sein:
data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333
Sie können diese URI aufrufen, indem Sie:
window.open
verwenden window.location
einstellenKopieren Sie zum Testen einfach die oben genannten URIs und fügen Sie sie in die Adressleiste Ihres Browsers ein. Oder testen Sie den Anker unten in einer HTML-Seite:
<a download="somedata.csv" href="data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333">Example</a>
Um den Inhalt zu erstellen und die Werte aus der Tabelle abzurufen, können Sie table2CSV und folgende Schritte ausführen:
var data = $table.table2CSV({delivery:'value'});
$('<a></a>')
.attr('id','downloadFile')
.attr('href','data:text/csv;charset=utf8,' + encodeURIComponent(data))
.attr('download','filename.csv')
.appendTo('body');
$('#downloadFile').ready(function() {
$('#downloadFile').get(0).click();
});
Die meisten, wenn nicht alle Versionen von IE unterstützen die Navigation zu einer Datenverbindung nicht. Daher muss ein Hack implementiert werden, häufig mit einer iframe
. Wenn Sie eine iFrame
kombiniert mit document.execCommand('SaveAs'..)
verwenden, können Sie ein ähnliches Verhalten bei den meisten derzeit verwendeten IE-Versionen erzielen.
Dies ist meine Implementierung (basierend auf: https://Gist.github.com/3782074 ):
Usage: HTML:
<table class="download">...</table>
<a href="" download="name.csv">DOWNLOAD CSV</a>
JS:
$("a[download]").click(function(){
$("table.download").toCSV(this);
});
Code:
jQuery.fn.toCSV = function(link) {
var $link = $(link);
var data = $(this).first(); //Only one table
var csvData = [];
var tmpArr = [];
var tmpStr = '';
data.find("tr").each(function() {
if($(this).find("th").length) {
$(this).find("th").each(function() {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.Push('"' + tmpStr + '"');
});
csvData.Push(tmpArr);
} else {
tmpArr = [];
$(this).find("td").each(function() {
if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
tmpArr.Push(parseFloat($(this).text()));
} else {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.Push('"' + tmpStr + '"');
}
});
csvData.Push(tmpArr.join(','));
}
});
var output = csvData.join('\n');
var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);
$link.attr("href", uri);
}
Anmerkungen:
UPDATE:
Meine vorherige Implementierung hat gut funktioniert, aber der csv-Dateiname wurde nicht festgelegt. Der Code wurde geändert, um einen Dateinamen zu verwenden, er erfordert jedoch ein <a> -Element. Es scheint, dass Sie das <a> -Element nicht dynamisch generieren und das "click" -Ereignis auslösen können (vielleicht aus Sicherheitsgründen?).
DEMO
(Leider erzeugt jsfiddle die Datei nicht und erzeugt stattdessen eine Fehlermeldung: 'please use POST request', lassen Sie sich durch diesen Fehler nicht davon abhalten, diesen Code in Ihrer Anwendung zu testen).
Ich habe vor kurzem eine kostenlose Software-Bibliothek veröffentlicht: "html5csv.js" - GitHub
Es soll die Erstellung kleiner Simulatoranwendungen rationalisierenIn Javascript, das möglicherweise CSV-Dateien importieren oder exportieren, bearbeiten, anzeigen, bearbeiten, Daten bearbeiten, verschiedene mathematische Verfahren wie Anpassen usw. ausführen muss.
Nach dem Laden von "html5csv.js" ist das Problem beim Scannen einer Tabelle und beim Erstellen einer CSV ein Einzeiler:
CSV.begin('#PrintDiv').download('MyData.csv').go();
Hier ist eine JSFiddle-Demo Ihres Beispiels mit diesem Code .
Intern ist für Firefox/Chrome eine auf Daten-URLs ausgerichtete Lösung ähnlich der von @italo, @lepe und @adeneo (zu einer anderen Frage) vorgeschlagenen Lösung. Für IE
Mit dem Aufruf CSV.begin()
wird das System so eingerichtet, dass die Daten in ein internes Array eingelesen werden. Dieser Abruf erfolgt dann. Dann generiert .download()
intern eine Daten-URL-Verknüpfung und klickt sie mit einem Link-Clicker an. Dadurch wird eine Datei an den Endbenutzer gesendet.
Gemäß caniuse unterstützt IE10 <a download=...>
nicht. Für IE ruft meine Bibliothek navigator.msSaveBlob()
intern auf, wie von @Manu Sharma vorgeschlagen .
Hier sind zwei [~ # ~] Problemumgehungen [~ # ~] für das Problem, nur Downloads vom Client auszulösen. In späteren Browsern solltest du dir "blob" ansehen
1. Tabelle ziehen und ablegen
Wussten Sie, dass Sie Ihren Tisch einfach in Excel umwandeln können?
So wählen Sie die Tabelle aus, die Sie ausschneiden und einfügen oder ziehen möchten
Wählen Sie eine vollständige Tabelle mit Javascript aus (zum Kopieren in die Zwischenablage)
2. Erstelle eine Popup-Seite von deinem Div
Obwohl es keinen Speicherdialog erzeugt , ist das resultierende Popup gespeichert mit der Endung . csv, wird es von Excel korrekt behandelt.
Die Zeichenfolge könnte seinw.document.write("row1.1\trow1.2\trow1.3\nrow2.1\trow2.2\trow2.3");
z.B. tabulatorgetrennt mit einem Zeilenvorschub für die Zeilen.
Es gibt Plugins, mit denen Sie die Zeichenfolge erstellen können, z. B. http://plugins.jquery.com/project/table2csv
var w = window.open('','csvWindow'); // popup, may be blocked though
// the following line does not actually do anything interesting with the
// parameter given in current browsers, but really should have.
// Maybe in some browser it will. It does not hurt anyway to give the mime type
w.document.open("text/csv");
w.document.write(csvstring); // the csv string from for example a jquery plugin
w.document.close();
[~ # ~] Haftungsausschluss [~ # ~] : Dies sind Problemumgehungen, und die Frage, die derzeit für die meisten Browser beantwortet wird, wird nicht vollständig beantwortet: Nicht nur auf dem Client möglich
Wenn Sie nur jQuery verwenden, können Sie einen Serveraufruf nicht vermeiden.
Um dieses Ergebnis zu erreichen, verwende ich jedoch Downloadify , wodurch ich Dateien speichern kann, ohne einen weiteren Serveranruf tätigen zu müssen. Dadurch wird die Serverlast reduziert und die Benutzererfahrung verbessert.
Um eine korrekte CSV zu erhalten, müssen Sie nur alle nicht benötigten Tags entfernen und ein "," zwischen die Daten setzen.
Sie können einen Serveraufruf hier nicht vermeiden, JavaScript kann (aus Sicherheitsgründen) eine Datei einfach nicht im Dateisystem des Benutzers speichern. Sie müssen Ihre Daten an den Server senden und it den .csv
als Link oder Anhang direkt senden.
HTML5 hat etwas Fähigkeit, dies zu tun (obwohl Speichern wirklich nicht angegeben ist - nur ein Anwendungsfall, Sie können die Datei lesen, wenn Sie möchten), aber es gibt keine Browserübergreifende Lösung jetzt an Ort und Stelle.
Probieren Sie einfach folgendes Coding aus ... sehr einfach, um CSV mit den Werten von HTML-Tabellen zu generieren. Es werden keine Browserprobleme auftreten
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://www.csvscript.com/dev/html5csv.js"></script>
<script>
$(document).ready(function() {
$('table').each(function() {
var $table = $(this);
var $button = $("<button type='button'>");
$button.text("Export to CSV");
$button.insertAfter($table);
$button.click(function() {
CSV.begin('table').download('Export.csv').go();
});
});
})
</script>
</head>
<body>
<div id='PrintDiv'>
<table style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
</body>
</html>