我知道有很多这种性质的问题,但我需要使用JavaScript来做到这一点。我使用Dojo 1.8并在数组中拥有所有属性信息,它看起来像这样:

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

知道我如何在客户端将此导出为CSV吗?


当前回答

我来这里是为了寻求更多的RFC 4180遵从性,但我没有找到一个实现,所以我根据自己的需要做了一个(可能效率很低)实现。我想跟大家分享一下。

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');

希望这能在未来帮助到一些人。这结合了CSV的编码和下载文件的能力。在jsfiddle的例子中。您可以下载该文件(假设HTML 5浏览器)或在控制台中查看输出。

更新:

Chrome现在似乎已经失去了命名文件的能力。我不确定发生了什么或如何修复它,但每当我使用这段代码(包括jsfiddle)时,下载的文件现在被命名为download.csv。

其他回答

在Chrome 35更新中,下载属性行为发生改变。

https://code.google.com/p/chromium/issues/detail?id=373182

要在chrome中工作,使用这个

var pom = document.createElement('a');
var csvContent=csv; //here we load our csv data 
var blob = new Blob([csvContent],{type: 'text/csv;charset=utf-8;'});
var url = URL.createObjectURL(blob);
pom.href = url;
pom.setAttribute('download', 'foo.csv');
pom.click();

就是这样:

<!doctype html>  
<html>  
<head></head>  
<body>
<a href='#' onclick='downloadCSV({ filename: "stock-data.csv" });'>Download CSV</a>

<script type="text/javascript">  
    var stockData = [
        {
            Symbol: "AAPL",
            Company: "Apple Inc.",
            Price: "132.54"
        },
        {
            Symbol: "INTC",
            Company: "Intel Corporation",
            Price: "33.45"
        },
        {
            Symbol: "GOOG",
            Company: "Google Inc",
            Price: "554.52"
        },
    ];

    function convertArrayOfObjectsToCSV(args) {
        var result, ctr, keys, columnDelimiter, lineDelimiter, data;

        data = args.data || null;
        if (data == null || !data.length) {
            return null;
        }

        columnDelimiter = args.columnDelimiter || ',';
        lineDelimiter = args.lineDelimiter || '\n';

        keys = Object.keys(data[0]);

        result = '';
        result += keys.join(columnDelimiter);
        result += lineDelimiter;

        data.forEach(function(item) {
            ctr = 0;
            keys.forEach(function(key) {
                if (ctr > 0) result += columnDelimiter;

                result += item[key];
                ctr++;
            });
            result += lineDelimiter;
        });

        return result;
    }

    window.downloadCSV = function(args) {
        var data, filename, link;

        var csv = convertArrayOfObjectsToCSV({
            data: stockData
        });
        if (csv == null) return;

        filename = args.filename || 'export.csv';

        if (!csv.match(/^data:text\/csv/i)) {
            csv = 'data:text/csv;charset=utf-8,' + csv;
        }
        data = encodeURI(csv);

        link = document.createElement('a');
        link.setAttribute('href', data);
        link.setAttribute('download', filename);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
       }
</script>  
</body>  
</html>  

老问题,有很多好的答案,但这里有另一个简单的选择,它依赖于两个流行的库来完成。有些回答提到了Papa Parse,但在下载部分提供了自己的解决方案。结合Papa Parse和FileSaver.js,你可以尝试以下方法:

const dataString = Papa.unparse(data, config);
const blob = new Blob([dataString], { type: 'text/csv;charset=utf-8' });
FileSaver.saveAs(blob, 'myfile.csv');

这里描述了unparse的配置选项。

用csv数据创建一个blob。ie var blob = new blob ([data], type:"text/csv");

如果浏览器支持保存blob,即如果window.navigator. msaveoropenblob)===true,则使用:window.navigator保存csv数据。“filename.csv”msSaveBlob (blob)

如果浏览器不支持保存和打开blob,则将csv数据保存为:

var downloadLink = document.createElement('<a></a>');
downloadLink.attr('href', window.URL.createObjectURL(blob));
downloadLink.attr('download', filename);
downloadLink.attr('target', '_blank');
document.body.append(downloadLink);

完整代码片段:

var filename = 'data_'+(new Date()).getTime()+'.csv';
var charset = "utf-8";
var blob = new Blob([data], {
     type: "text/csv;charset="+ charset + ";"
});
if (window.navigator.msSaveOrOpenBlob) {
     window.navigator.msSaveBlob(blob, filename);
} else {
    var downloadLink = document.element('<a></a>');
    downloadLink.attr('href', window.URL.createObjectURL(blob));
    downloadLink.attr('download', filename);
    downloadLink.attr('target', '_blank');  
    document.body.append(downloadLink); 
    downloadLink[0].click(); 
}

下面是一个Angular友好的版本:

  constructor(private location: Location, private renderer: Renderer2) {}

  download(content, fileName, mimeType) {

    const a = this.renderer.createElement('a');

    mimeType = mimeType || 'application/octet-stream';

    if (navigator.msSaveBlob) {

      navigator.msSaveBlob(new Blob([content], {
        type: mimeType
      }), fileName);
    }
    else if (URL && 'download' in a) {

      const id = GetUniqueID();

      this.renderer.setAttribute(a, 'id', id);
      this.renderer.setAttribute(a, 'href', URL.createObjectURL(new Blob([content], {
        type: mimeType
      })));

      this.renderer.setAttribute(a, 'download', fileName);

      this.renderer.appendChild(document.body, a);

      const anchor = this.renderer.selectRootElement(`#${id}`);

      anchor.click();

      this.renderer.removeChild(document.body, a);
    }
    else {
      this.location.go(`data:application/octet-stream,${encodeURIComponent(content)}`);
    }
  };