Como exportar informações de array JavaScript para csv (no lado do cliente)?

Eu sei que há muitas perguntas desta natureza, mas preciso fazer isto usando o JavaScript. Estou utilizando `Dojo 1.8' e tenho todas as informações de atributos em array, que se parece com isto:

[["name1", "city_name1", ...]["name2", "city_name2", ...]]

Alguma ideia de como eu posso exportar isto para o CSV do lado do cliente?

Solução

Você pode fazer isso em JavaScript nativo. Você'terá que analisar seus dados no formato CSV correto (assumindo que você esteja usando um array de arrays para seus dados como você descreveu na pergunta):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8,";

rows.forEach(function(rowArray) {
    let row = rowArray.join(",");
    csvContent += row + "\r\n";
});

ou o caminho mais curto (usando funções de seta):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8," 
    + rows.map(e => e.join(",")).join("\n");

Então você pode utilizar as funções window.open' eencodeURI' do JavaScript's para baixar o arquivo CSV assim:

var encodedUri = encodeURI(csvContent);
window.open(encodedUri);

Edit:

Se você quiser dar um nome específico ao seu arquivo, você tem que fazer as coisas de forma um pouco diferente, já que isso não é suportado acessando um URI de dados utilizando o método `window.open`. Para conseguir isso, você pode criar um nó DOM oculto ``DOM e definir seu atributo `download` como a seguir:
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for FF

link.click(); // This will download the data file named "my_data.csv".
Comentários (34)

Vim aqui à procura de um pouco mais de conformidade com o RFC 4180 e não consegui encontrar uma implementação, por isso fiz uma (possivelmente ineficiente) para as minhas próprias necessidades. Pensei em compartilhá-la com todos.

var content = [['1st title', '2nd title', '3rd title', 'another title'], ['a a a', 'bb\nb', 'cc,c', 'dd"d'], ['www', 'xxx', 'yyy', 'zzz']];

var finalVal = '';

for (var i = 0; i < content.length; i++) {
    var value = content[i];

    for (var j = 0; j < value.length; j++) {
        var innerValue =  value[j]===null?'':value[j].toString();
        var result = innerValue.replace(/"/g, '""');
        if (result.search(/("|,|\n)/g) >= 0)
            result = '"' + result + '"';
        if (j > 0)
            finalVal += ',';
        finalVal += result;
    }

    finalVal += '\n';
}

console.log(finalVal);

var download = document.getElementById('download');
download.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(finalVal));
download.setAttribute('download', 'test.csv');

Espero que isto ajude alguém no futuro. Isto combina tanto a codificação do CSV quanto a capacidade de baixar o arquivo. No meu exemplo em [jsfiddle](http://jsfiddle.net/a5E9m/2/). Você pode baixar o arquivo (assumindo o navegador HTML 5) ou visualizar a saída no console.

UPDATE:

O cromado parece agora ter perdido a capacidade de nomear o ficheiro. I'não tenho certeza do que's aconteceu ou como corrigi-lo, mas sempre que eu uso este código (incluindo o jsfiddle), o arquivo baixado agora é chamado de download.csv.

Comentários (3)

A solução de @Default funciona perfeitamente no Chrome (muito obrigado por isso!), mas eu tive um problema com o IE.

Aqui's uma solução (funciona no IE10):

var csvContent=data; //here we load our csv data 
var blob = new Blob([csvContent],{
    type: "text/csv;charset=utf-8;"
});

navigator.msSaveBlob(blob, "filename.csv")
Comentários (0)