Eksport danych javascript do pliku CSV bez interakcji z serwerem

Gdybyśmy byli na serwerze nodeJS, moglibyśmy napisać nagłówek, ustawić typ mime i wysłać go:

res.header("Content-Disposition", "attachment;filename="+name+".csv"); 
res.type("text/csv");
res.send(200, csvString);

I ze względu na nagłówki, przeglądarka utworzy pobieranie dla nazwanego pliku csv.

Gdy przydatne dane są generowane w przeglądarce, jednym z rozwiązań, aby uzyskać go w pliku CSV jest użycie ajax, przesłać go do serwera, (być może opcjonalnie zapisać go tam) i uzyskać serwer, aby wysłać go z powrotem z tymi nagłówkami, aby stać się csv pobrać z powrotem w przeglądarka.

[[2]}jednak chciałbym mieć rozwiązanie w 100% przeglądarkowe, które nie wiąże się z ping-pongiem z serwerem.

Przyszło mi więc do głowy, że można otworzyć nowe okno i spróbować ustawić nagłówek z równoważnym META tagiem.

Ale to nie działa dla mnie w ostatnim Chrome.

Dostaję nowe okno, które zawiera plik csvString, ale nie działa jako plik do pobrania.

Myślę, że spodziewałem się pobrać albo w dolnej zakładce lub puste nowe okno z pobierz w dolnej zakładce.

Zastanawiam się, czy meta tagi są poprawne lub czy inne tagi są również potrzebne.

Czy Jest jakiś sposób, aby to działało bez wysyłania go na serwer?

JsFiddle do tworzenia pliku CSV w przeglądarce (nie działa - wyświetla okno, ale nie pobiera)

var A = [['n','sqrt(n)']];  // initialize array of rows with header row as 1st item
for(var j=1;j<10;++j){ A.push([j, Math.sqrt(j)]) }
var csvRows = [];
for(var i=0,l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));   // unquoted CSV row
}
var csvString = csvRows.join("\n");
console.log(csvString);
var csvWin = window.open("","","");
csvWin.document.write('<meta name="content-type" content="text/csv">');
csvWin.document.write('<meta name="content-disposition" content="attachment;  filename=data.csv">  ');
csvWin.document.write(csvString);
Author: Paul, 2013-07-24

6 answers

Zawsze jest HTML5 download atrybut:

Ten atrybut, jeśli jest obecny, wskazuje, że autor zamierza hiperłącze do pobrania zasobu, tak aby gdy użytkownik kliknięcia w link zostaną poproszone o zapisanie go jako pliku lokalnego.

Jeśli atrybut ma wartość, wartość zostanie użyta jako wstępnie wypełniona nazwa pliku w monicie Zapisz, który otwiera się, gdy użytkownik kliknie na link.

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));
}

var csvString = csvRows.join("%0A");
var a         = document.createElement('a');
a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
a.target      = '_blank';
a.download    = 'myFile.csv';

document.body.appendChild(a);
a.click();

FIDDLE

Testowany w Chrome i Firefox, działa dobrze w najnowszych wersjach (Stan na Lipiec 2013) .
Działa również w Operze, ale nie ustawia nazwy pliku (Stan na Lipiec 2013) .
Nie działa w IE9 (big suprise) (Stan na Lipiec 2013) .

Przegląd przeglądarek obsługujących atrybut download można znaleźć Proszę.
W przypadku nie obsługujących przeglądarek należy ustawić odpowiednie nagłówki po stronie serwera.


Najwyraźniej istniejehack dla IE10 i IE11 , który nie obsługuje atrybutu download (Edge jednak robi).

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.push(A[i].join(','));
}

var csvString = csvRows.join("%0A");

if (window.navigator.msSaveOrOpenBlob) {
    var blob = new Blob([csvString]);
    window.navigator.msSaveOrOpenBlob(blob, 'myFile.csv');
} else {
    var a         = document.createElement('a');
    a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
    a.target      = '_blank';
    a.download    = 'myFile.csv';
    document.body.appendChild(a);
    a.click();
}
 161
Author: adeneo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 22:25:40

@ Adeneo answer działa na Firefoksa i chrome... W przypadku IE można użyć poniższego.

if (window.navigator.msSaveOrOpenBlob) {
  var blob = new Blob([decodeURIComponent(encodeURI(result.data))], {
    type: "text/csv;charset=utf-8;"
  });
  navigator.msSaveBlob(blob, 'FileName.csv');
}
 31
Author: Manu Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-23 02:30:11

Zobacz odpowiedź adeneo, ale nie zapomnij encodeURIComponent!

a.href     = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvString);

Również, musiałem zrobić "\r\n" nie tylko "\N" dla ogranicznika wiersza.

var csvString = csvRows.join("\r\n");

Poprawione: http://jsfiddle.net/7Q3c6/

 15
Author: user2608223,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-26 23:40:28

Kiedyś spakowałem kod JS robiąc to do małej biblioteki:

Https://github.com/AlexLibs/client-side-csv-generator

Kod, dokumentacja i Demo / Playground są dostępne na Githubie.

Enjoy:)

Żądania pobierania są mile widziane.

 7
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-06 09:22:41

Zobacz odpowiedź adeneo, ale aby to działało w Excelu we wszystkich krajach należy dodać "SEP=," do pierwszej linii pliku. Spowoduje to ustawienie standardowego separatora w programie Excel i nie pojawi się w rzeczywistym dokumencie

var csvString = "SEP=, \n" + csvRows.join("\r\n");
 2
Author: Thyselius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-15 11:59:19

Możemy w prosty sposób utworzyć i wyeksportować/pobrać plik Excela za pomocą dowolnego separatora (w tej odpowiedzi używam separatora przecinków) przy użyciu javascript. Nie używam żadnego zewnętrznego pakietu do tworzenia pliku excel.

    var Head = [[
        'Heading 1',
        'Heading 2', 
        'Heading 3', 
        'Heading 4'
    ]];

    var row = [
       {key1:1,key2:2, key3:3, key4:4},
       {key1:2,key2:5, key3:6, key4:7},
       {key1:3,key2:2, key3:3, key4:4},
       {key1:4,key2:2, key3:3, key4:4},
       {key1:5,key2:2, key3:3, key4:4}
    ];

for (var item = 0; item < row.length; ++item) {
       Head.push([
          row[item].key1,
          row[item].key2,
          row[item].key3,
          row[item].key4
       ]);
}

var csvRows = [];
for (var cell = 0; cell < Head.length; ++cell) {
       csvRows.push(Head[cell].join(','));
}
            
var csvString = csvRows.join("\n");
let csvFile = new Blob([csvString], { type: "text/csv" });
let downloadLink = document.createElement("a");
downloadLink.download = 'MYCSVFILE.csv';
downloadLink.href = window.URL.createObjectURL(csvFile);
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();
 1
Author: Pulkit Aggarwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-28 10:03:16