Làm cách nào để xuất thông tin mảng JavaScript sang csv (về phía máy khách)?


513

Tôi biết có rất nhiều câu hỏi về bản chất này nhưng tôi cần phải làm điều này bằng cách sử dụng JavaScript. Tôi đang sử dụng Dojo 1.8và có tất cả các thông tin thuộc tính trong mảng, trông như thế này:

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

Bất cứ ý tưởng làm thế nào tôi có thể xuất cái này sang CSVphía khách hàng?

Câu trả lời:


837

Bạn có thể làm điều này trong JavaScript gốc. Bạn sẽ phải phân tích dữ liệu của mình thành định dạng CSV chính xác như vậy (giả sử bạn đang sử dụng một mảng các mảng cho dữ liệu của mình như bạn đã mô tả trong câu hỏi):

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";
});

hoặc cách ngắn hơn (sử dụng các chức năng mũi tên ):

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

Sau đó, bạn có thể sử dụng JavaScript window.openvà các encodeURIchức năng để tải xuống tệp CSV như vậy:

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

Biên tập:

Nếu bạn muốn đặt cho tệp của mình một tên cụ thể, bạn phải thực hiện mọi thứ hơi khác một chút vì điều này không được hỗ trợ khi truy cập URI dữ liệu bằng window.openphương thức. Để đạt được điều này, bạn có thể tạo một <a>nút DOM ẩn và đặt downloadthuộc tính của nó như sau:

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".

4
Từ những gì tôi biết, không có cách nào để làm điều đó bằng cách sử dụng window.open. Tuy nhiên, bạn có thể tạo một liên kết ẩn có downloadthuộc tính được đặt thành tên tệp bạn muốn. Sau đó "nhấp" liên kết này sẽ tải xuống tệp theo tên bạn mong muốn, tôi sẽ thêm nó vào câu trả lời của mình.
Mặc định

14
Tôi đã phải thêm document.body.appendChild(link);để nhận được hỗ trợ đầy đủ trong FF.
Hardbyte

9
Câu trả lời này là sai: nó sẽ thất bại cho trường hợp data = [["Hello, world"]]. Điều đó sẽ xuất ra hai cột khi cần xuất một cột.
aredridel

18
Điều này hoạt động tốt cho khoảng ~ 7000 hàng. Nhưng bắt đầu đưa ra lỗi này: NETWORK_INVALID_REQUEST . Có ai khác phải đối mặt với vấn đề này quá? Có bất kỳ giới hạn trên của dữ liệu về encodeURIComponent()chức năng hoặc một cái gì đó? Tôi đang sử dụng Chrome làm trình duyệt.
Abhidemon

13
@Abhidemon Câu trả lời là bạn phải sử dụng loại blob cho một cái gì đó lớn thì nó sẽ hoạt động tốt, ví dụ: blob = new Blob ([csvContent], {type: "text / csv"}); href = window.URL.createObjectURL (blob); Thêm chi tiết: stackoverflow.com/a/19328891/1854079
mdubez

256

Dựa trên các câu trả lời ở trên, tôi đã tạo ra chức năng này mà tôi đã thử nghiệm trên IE 11, Chrome 36 và Firefox 29

function exportToCsv(filename, rows) {
    var processRow = function (row) {
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0)
                result = '"' + result + '"';
            if (j > 0)
                finalVal += ',';
            finalVal += result;
        }
        return finalVal + '\n';
    };

    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }

    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    } else {
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

Ví dụ: https://jsfiddle.net/jossef/m3rrLzk0/


6
Có thể rơi trở lại vào window.opentrong một elsecủa link.download !== undefined.
MrYellow 6/2/2015

2
Đây là một đoạn mã đẹp. Bất kỳ cơ hội nào bạn sẵn sàng cấp phép này theo thứ gì đó tự do hơn so với mặc định SO của CC-BY-SA? Ví dụ: Muff, MIT, BSD, Apache, X11. . . meta.stackexchange.com/questions/12527/
Mạnh

1
Tôi đã sử dụng phương pháp này để thực hiện xuất Excel trong một số ứng dụng web. Nhưng Chrome 43+ hiện đã chuyển các thuộc tính DOM sang chuỗi nguyên mẫu. Một ngoại lệ được ném vào link.style.visibility='hidden'. B / c thuộc tính DOM là chỉ đọc. Thông tin chi tiết có thể được tìm thấy trong update.html5rocks.com/2015/04/ trên phần "Viết thuộc tính chỉ đọc ở chế độ nghiêm ngặt sẽ gây ra lỗi"
Blaise

1
Phản ứng này là tốt nhất cho đến nay. Nó bao gồm các trường hợp với các ký tự đặc biệt và dấu ngoặc đơn.
Vladimir Kostov

2
Tôi đã sử dụng phần tải xuống của câu trả lời này và nó hoạt động tốt trên Chrome, cảm ơn!
Liran H

77

Giải pháp này sẽ hoạt động với Internet Explorer 10+, Edge, các phiên bản cũ và mới của Chrome, FireFox, Safari, ++

Câu trả lời được chấp nhận sẽ không hoạt động với IE và Safari.

// Example data given in question text
var data = [
  ['name1', 'city1', 'some other info'],
  ['name2', 'city2', 'more info']
];

// Building the CSV from the Data two-dimensional array
// Each column is separated by ";" and new line "\n" for next row
var csvContent = '';
data.forEach(function(infoArray, index) {
  dataString = infoArray.join(';');
  csvContent += index < data.length ? dataString + '\n' : dataString;
});

// The download function takes a CSV string, the filename and mimeType as parameters
// Scroll/look down at the bottom of this snippet to see how download is called
var download = function(content, fileName, mimeType) {
  var a = document.createElement('a');
  mimeType = mimeType || 'application/octet-stream';

  if (navigator.msSaveBlob) { // IE10
    navigator.msSaveBlob(new Blob([content], {
      type: mimeType
    }), fileName);
  } else if (URL && 'download' in a) { //html5 A[download]
    a.href = URL.createObjectURL(new Blob([content], {
      type: mimeType
    }));
    a.setAttribute('download', fileName);
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  } else {
    location.href = 'data:application/octet-stream,' + encodeURIComponent(content); // only this mime type is supported
  }
}

download(csvContent, 'dowload.csv', 'text/csv;encoding:utf-8');

Chạy đoạn mã sẽ tải xuống dữ liệu giả định là csv

Tín dụng cho dandavis https://stackoverflow.com/a/16377813/1350598


1
(Ít nhất, mã HTML5) hoạt động mà không có setTimeout.
StubbornShowaGuy

@StubbornShowaGuy tuyệt vời rồi, tôi sẽ xóa setTimeout khỏi mã ví dụ :)
Arne H. Bitubekk

Hoạt động trong Chrome, IE và Firefox mới nhất. Cảm ơn!
walla

Giải pháp trình duyệt chéo thực sự duy nhất ở đây. Lưu ý rằng nó hoạt động trên Safari 10.10 và Safari di động. Tuy nhiên, iframephần này có thể được thay thế bằng chỉ vị trí.href = ...
Dan

2
LƯU Ý: Có một lỗi đánh máy trong hàm, nó thực sự URL.createObjectURL(kết thúc bằng URLkhông Url).
Nathan Hinchey

35

Tôi đến đây để tìm kiếm thêm một chút tuân thủ RFC 4180 và tôi đã thất bại trong việc tìm kiếm một triển khai, vì vậy tôi đã thực hiện một (có thể không hiệu quả) cho nhu cầu của riêng tôi. Tôi nghĩ rằng tôi sẽ chia sẻ nó với mọi người.

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

Hy vọng điều này sẽ giúp ai đó trong tương lai. Điều này kết hợp cả mã hóa của CSV cùng với khả năng tải xuống tệp. Trong ví dụ của tôi trên jsfiddle . Bạn có thể tải xuống tệp (giả sử trình duyệt HTML 5) hoặc xem đầu ra trong bảng điều khiển.

CẬP NHẬT:

Chrome hiện dường như đã mất khả năng đặt tên tệp. Tôi không chắc chắn điều gì đã xảy ra hoặc cách khắc phục nó, nhưng bất cứ khi nào tôi sử dụng mã này (bao gồm cả jsfiddle), tệp đã tải xuống sẽ được đặt tên download.csv.


Bắt tốt Chris, tôi đã không kiểm tra nó với dữ liệu số :)
Uxonith

Tôi không biết nếu kiểm tra null cuối cùng có nhất thiết phải là hành vi dự kiến ​​hay không. Null rất khác so với một chuỗi rỗng. Nếu ai đó thực hiện điều này, tôi sẽ đề xuất một giá trị null tùy chỉnh (ví dụ: '[[NULL]]'). Một ngoại lệ cho không xác định cũng có thể được mong muốn, nhưng tôi khuyên bạn không nên thay thế null bằng một chuỗi rỗng.
Uxonith

Tôi đã thử nghiệm và thấy rằng bạn là chính xác. Điều này dường như hoạt động trong Chrome và Opera. Safari chỉ mở một trang với nội dung. Internet Explorer ... cũng là IE. Đối với tình huống của tôi, tôi sẽ tạo ra phía máy chủ CSV của mình và phục vụ theo cách đó, thật đáng buồn.
Xin chào

33

Giải pháp từ @Default hoạt động hoàn hảo trên Chrome (cảm ơn rất nhiều vì điều đó!) Nhưng tôi gặp vấn đề với IE.

Đây là một giải pháp (hoạt động trên 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")

23

Trong bản cập nhật Chrome 35, hành vi thuộc tính tải xuống đã được thay đổi.

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

để làm việc này trong chrome, sử dụng cái này

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

1
Bạn cũng có thể kiểm tra cái này: github.com/mholt/PapaPude/issues/175#issuecomment-201308792
Gabriel

Đây là câu trả lời chính xác tại thời điểm này, không phải là câu trả lời được chấp nhận!
meo

17

Làm việc cho tất cả các ngôn ngữ

        function convertToCsv(fName, rows) {
        var csv = '';
        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            for (var j = 0; j < row.length; j++) {
                var val = row[j] === null ? '' : row[j].toString();
                val = val.replace(/\t/gi, " ");
                if (j > 0)
                    csv += '\t';
                csv += val;
            }
            csv += '\n';
        }

        // for UTF-16
        var cCode, bArr = [];
        bArr.push(255, 254);
        for (var i = 0; i < csv.length; ++i) {
            cCode = csv.charCodeAt(i);
            bArr.push(cCode & 0xff);
            bArr.push(cCode / 256 >>> 0);
        }

        var blob = new Blob([new Uint8Array(bArr)], { type: 'text/csv;charset=UTF-16LE;' });
        if (navigator.msSaveBlob) {
            navigator.msSaveBlob(blob, fName);
        } else {
            var link = document.createElement("a");
            if (link.download !== undefined) {
                var url = window.URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", fName);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                window.URL.revokeObjectURL(url);
            }
        }
    }



    convertToCsv('download.csv', [
        ['Order', 'Language'],
        ['1', 'English'],
        ['2', 'Español'],
        ['3', 'Français'],
        ['4', 'Português'],
        ['5', 'čeština'],
        ['6', 'Slovenščina'],
        ['7', 'Tiếng Việt'],
        ['8', 'Türkçe'],
        ['9', 'Norsk bokmål'],
        ['10', 'Ελληνικά'],
        ['11', 'беларускі'],
        ['12', 'русский'],
        ['13', 'Українська'],
        ['14', 'հայերեն'],
        ['15', 'עִברִית'],
        ['16', 'اردو'],
        ['17', 'नेपाली'],
        ['18', 'हिंदी'],
        ['19', 'ไทย'],
        ['20', 'ქართული'],
        ['21', '中国'],
        ['22', '한국어'],
        ['23', '日本語'],
    ])

Ấn tượng! (+1). Chào mừng bạn đến với StackOverflow, anh bạn!
Rann Lifshitz

bạn có thể vui lòng giúp tôi hiểu khối mã UTF-16 đó là gì và được sử dụng cho mục đích gì không?
Mar1009

Xin chào Mar1009. Điều này là cần thiết cho một số ngôn ngữ. Ví dụ, bảng chữ cái Cyrillic.
Serdar Didan

13

Bạn đi đây

<!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>  

1
Câu trả lời tuyệt vời. Tôi ủng hộ câu trả lời này vì câu trả lời được chấp nhận vì một số lý do đặt mọi thứ vào một cột duy nhất. Điều này chia tất cả thành các cột riêng biệt và hỗ trợ định dạng dữ liệu JSON như cực kỳ hữu ích.
Hoser

Điều này hoạt động khi liên kết đầu tiên được thêm vào thân tài liệu và sau đó nhấp vào được gọi. Và sau đó nó được gỡ bỏ khỏi dom.
Jay Dubal

1
Câu trả lời hay, chỉ có một nhược điểm là nó không hoạt động chính xác khi dữ liệu có dấu phân cách cột "," tức là Địa chỉ: '10 Làn đường vô hạn, Phòng 56 ', chú ý dấu phẩy sau làn đường. Tôi khuyên bạn nên sử dụng liên kết PapaPude để chuyển đổi dữ liệu sang CSV sau đó sử dụng phương thức downloadCSV ở trên để tải xuống tệp thực tế
phil

Điều này làm việc hoàn hảo cho tôi. Chỉ có một vấn đề, tôi có một số số trong mảng như '000002342' nhưng khi xuất sang csv, các số 0 đứng đầu sẽ bị xóa. Có cách nào để ngăn chặn điều này?
Aakarsh Dhawan

13

Mọi người đang cố gắng tạo chuỗi csv của riêng họ, thất bại trong các trường hợp cạnh, ví dụ như các ký tự đặc biệt và như vậy, chắc chắn đây là một vấn đề được giải quyết phải không?

papapude - sử dụng cho mã hóa JSON sang CSV. Papa.unparse().

import Papa from "papaparse";

const downloadCSV = (args) => {  

  let filename = args.filename || 'export.csv';
  let columns = args.columns || null;

  let csv = Papa.unparse({ data: args.data, fields: columns})
  if (csv == null) return;

  var blob = new Blob([csv]);
  if (window.navigator.msSaveOrOpenBlob)  // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
      window.navigator.msSaveBlob(blob, args.filename);
  else
  {
      var a = window.document.createElement("a");
      a.href = window.URL.createObjectURL(blob, {type: "text/plain"});
      a.download = filename;
      document.body.appendChild(a);
      a.click();  // IE: "Access is denied"; see: https://connect.microsoft.com/IE/feedback/details/797361/ie-10-treats-blob-url-as-cross-origin-and-denies-access
      document.body.removeChild(a);
  }

}

Ví dụ sử dụng

downloadCSV({ 
  filename: 'filename.csv',
  data: [{'a': '1', 'b': 2'}],
  columns: ['a','b']
});

https://github.com/mholt/PapaPude/issues/175 - Xem bình luận này để thảo luận hỗ trợ trình duyệt.


10

Bạn có thể sử dụng đoạn mã dưới đây để xuất mảng sang tệp CSV bằng Javascript.

Điều này cũng xử lý một phần ký tự đặc biệt

var arrayContent = [["Séjour 1, é,í,ú,ü,ű"],["Séjour 2, é,í,ú,ü,ű"]];
var csvContent = arrayContent.join("\n");
var link = window.document.createElement("a");
link.setAttribute("href", "data:text/csv;charset=utf-8,%EF%BB%BF" + encodeURI(csvContent));
link.setAttribute("download", "upload_data.csv");
link.click(); 

Đây là liên kết để làm việc jsfiddle


1
Câu trả lời hay nhất cho các nhân vật đặc biệt
Alejandro

# (hashtag) không hoạt động!
Nakres

7
//It work in Chrome and IE ... I reviewed and readed a lot of answer. then i used it and tested in both ... 

var link = document.createElement("a");

if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var blob = new Blob([CSV], { type: 'text/csv;charset=utf-8;' });
    var url = URL.createObjectURL(blob);            
    link.setAttribute("href", url);
    link.setAttribute("download", fileName);
    link.style = "visibility:hidden";
}

if (navigator.msSaveBlob) { // IE 10+
   link.addEventListener("click", function (event) {
     var blob = new Blob([CSV], {
       "type": "text/csv;charset=utf-8;"
     });
   navigator.msSaveBlob(blob, fileName);
  }, false);
}

document.body.appendChild(link);
link.click();
document.body.removeChild(link);

//Regards

6

Tạo một blob với dữ liệu csv .ie var blob = new Blob([data], type:"text/csv");

Nếu trình duyệt hỗ trợ lưu blobs tức là if window.navigator.mSaveOrOpenBlob)===truelưu dữ liệu csv bằng cách sử dụng: window.navigator.msSaveBlob(blob, 'filename.csv')

Nếu trình duyệt không hỗ trợ lưu và mở các đốm màu, thì hãy lưu dữ liệu csv dưới dạng:

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

Đoạn mã đầy đủ:

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(); 
}

5

Có hai câu hỏi ở đây:

  1. Cách chuyển đổi một mảng thành chuỗi csv
  2. Cách lưu chuỗi đó vào một tệp

Tất cả các câu trả lời cho câu hỏi đầu tiên (ngoại trừ câu hỏi của Milimetric) ở đây có vẻ như quá mức cần thiết. Và một bởi Milimetric không bao gồm các yêu cầu về độ cao, như các chuỗi xung quanh có dấu ngoặc kép hoặc chuyển đổi các mảng của các đối tượng.

Dưới đây là của tôi về điều này:

Đối với một csv đơn giản, một bản đồ () và tham gia () là đủ:

    var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];
    var csv = test_array.map(function(d){
        return d.join();
    }).join('\n');

    /* Results in 
    name1,2,3
    name2,4,5
    name3,6,7
    name4,8,9
    name5,10,11

Phương pháp này cũng cho phép bạn chỉ định dấu tách cột khác với dấu phẩy trong phép nối bên trong. ví dụ: một tab:d.join('\t')

Mặt khác, nếu bạn muốn thực hiện đúng cách và gửi các chuỗi trong dấu ngoặc kép "", thì bạn có thể sử dụng một số phép thuật JSON:

var csv = test_array.map(function(d){
       return JSON.stringify(d);
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, ''); // remove opening [ and closing ]
                                   // brackets from each line 

/* would produce
"name1",2,3
"name2",4,5
"name3",6,7
"name4",8,9
"name5",10,11

nếu bạn có mảng các đối tượng như:

var data = [
  {"title": "Book title 1", "author": "Name1 Surname1"},
  {"title": "Book title 2", "author": "Name2 Surname2"},
  {"title": "Book title 3", "author": "Name3 Surname3"},
  {"title": "Book title 4", "author": "Name4 Surname4"}
];

// use
var csv = data.map(function(d){
        return JSON.stringify(Object.values(d));
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, '');

Nếu tôi không nhầm, tôi tin rằng .replacenên chỉ định dấu ngoặc nhọn so với dấu ngoặc vuông.
aaronbartell

.replaceđược thực hiện trên một chuỗi được trả về bằng cách values()lấy một đối tượng và trả về một mảng các giá trị
Konstantin

Các values()phương pháp không được tìm thấy khi tôi đã cố gắng mã của bạn.
aaronbartell

Cảm ơn! Trong Chrome, nó hoạt động mà không cần gọi values()rõ ràng Object. Tôi đã sửa lại ví dụ.
Konstantin

5

Rất nhiều giải pháp của riêng bạn ở đây để chuyển đổi dữ liệu sang CSV, nhưng tất cả chúng đều có những cảnh báo khác nhau về loại dữ liệu mà chúng sẽ định dạng chính xác mà không bị vấp Excel hoặc lượt thích.

Tại sao không sử dụng một cái gì đó đã được chứng minh: Papa Parse

Papa.unparse(data[, config])

Sau đó, chỉ cần kết hợp điều này với một trong những giải pháp tải xuống cục bộ ở đây, vd. một bởi @ArneHB có vẻ tốt.


4

Chức năng một mũi tên với ES6:

const dataToCsvURI = (data) => encodeURI(
`data:text/csv;charset=utf-8,${data.map((row, index) =>  row.join(',')).join(`\n`)}`
);

Sau đó :

window.open(
  dataToCsvURI(
   [["name1", "city_name1"/*, ...*/], ["name2", "city_name2"/*, ...*/]]
  )
);

Trong trường hợp bất cứ ai cần điều này cho , react-csvcó đó không


3
Các react-csvthư viện hoạt động như một nét duyên dáng. Giải pháp tuyệt vời cho bất cứ ai sử dụng các mô-đun.
Matt Parrilla

Điều này không quan sát được trường hợp có các trường bên trong tệp CSV có dấu phẩy bên trong.
unpollito

2

Đây là cách tôi tải xuống các tệp CSV ở phía máy khách trong ứng dụng Java GWT của mình. Đặc biệt cảm ơn Xavier John cho giải pháp của mình. Nó đã được xác minh để hoạt động trong FF 24.6.0, IE 11.0.20 và Chrome 45.0.2454.99 (64-bit). Tôi hy vọng điều này sẽ giúp ai đó tiết kiệm được một chút thời gian:

public class ExportFile 
{

    private static final String CRLF = "\r\n";

    public static void exportAsCsv(String filename, List<List<String>> data) 
    {
        StringBuilder sb = new StringBuilder();
        for(List<String> row : data) 
        {
            for(int i=0; i<row.size(); i++)
            {
                if(i>0) sb.append(",");
                sb.append(row.get(i));
            }
            sb.append(CRLF);
        }

        generateCsv(filename, sb.toString());
    }

    private static native void generateCsv(String filename, String text)
    /*-{
        var blob = new Blob([text], { type: 'text/csv;charset=utf-8;' });

        if (navigator.msSaveBlob) // IE 10+
        { 
            navigator.msSaveBlob(blob, filename);
        } 
        else 
        {
            var link = document.createElement("a");
            if (link.download !== undefined) // feature detection
            { 
                // Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", filename);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        }
    }-*/;
}

2

Sau đây là một giải pháp js bản địa.

function export2csv() {
  let data = "";
  const tableData = [];
  const rows = [
    ['111', '222', '333'],
    ['aaa', 'bbb', 'ccc'],
    ['AAA', 'BBB', 'CCC']
  ];
  for (const row of rows) {
    const rowData = [];
    for (const column of row) {
      rowData.push(column);
    }
    tableData.push(rowData.join(","));
  }
  data += tableData.join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  a.setAttribute("download", "data.csv");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
<button onclick="export2csv()">Export array to csv file</button>


làm việc hoàn hảo cho tôi cảm ơn!
Sriigate Ghosh

1

Đây là phiên bản thân thiện với góc cạnh:

  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)}`);
    }
  };

1

Các câu trả lời ở trên hoạt động, nhưng hãy nhớ rằng nếu bạn đang mở ở định dạng .xls, các cột ~ ~ có thể ~ ~ được phân tách bằng '\t'thay vì ',', câu trả lời https://stackoverflow.com/a/14966131/6169225 hoạt động tốt đối với tôi, miễn là tôi sử dụng .join('\t')trên các mảng thay vì .join(',').


Hoạt động tốt cho các tệp .xls, BTW Tôi có một vấn đề nhỏ, khi văn bản quá dài và vượt quá kích thước của lưới, trang tính trông không được tốt lắm, có gợi ý nào để giải quyết điều đó không?
gabrielAnzaldo

1

Tôi sử dụng chức năng này để chuyển đổi một string[][]tập tin csv. Nó trích dẫn một ô, nếu nó chứa a ", a ,hoặc khoảng trắng khác (trừ khoảng trắng):

/**
 * Takes an array of arrays and returns a `,` sparated csv file.
 * @param {string[][]} table
 * @returns {string}
 */
function toCSV(table) {
    return table
        .map(function(row) {
            return row
                .map(function(cell) {
                    // We remove blanks and check if the column contains
                    // other whitespace,`,` or `"`.
                    // In that case, we need to quote the column.
                    if (cell.replace(/ /g, '').match(/[\s,"]/)) {
                        return '"' + cell.replace(/"/g, '""') + '"';
                    }
                    return cell;
                })
                .join(',');
        })
        .join('\n'); // or '\r\n' for windows

}

Lưu ý : không hoạt động trên Internet Explorer <11 trừ khi mapđược điền đầy đủ.

Lưu ý : Nếu các ô chứa số, bạn có thể thêm cell=''+celltrước if (cell.replace...để chuyển đổi số thành chuỗi.

Hoặc bạn có thể viết nó thành một dòng bằng ES6:

t.map(r=>r.map(c=>c.replace(/ /g, '').match(/[\s,"]/)?'"'+c.replace(/"/g,'""')+'"':c).join(',')).join('\n')

1

Tôi khuyên bạn nên sử dụng thư viện như PapaPude: https://github.com/mholt/PapaPude

Câu trả lời được chấp nhận hiện có nhiều vấn đề bao gồm:

  • nó không thành công nếu dữ liệu chứa dấu phẩy
  • nó không thành công nếu dữ liệu chứa một ngắt dòng
  • nó (loại) không thành công nếu dữ liệu chứa dấu ngoặc kép

1

Đơn giản chỉ cần thử điều này, một số câu trả lời ở đây không xử lý dữ liệu unicode và dữ liệu có dấu phẩy ví dụ ngày.

function downloadUnicodeCSV(filename, datasource) {
    var content = '', newLine = '\r\n';
    for (var _i = 0, datasource_1 = datasource; _i < datasource_1.length; _i++) {
        var line = datasource_1[_i];
        var i = 0;
        for (var _a = 0, line_1 = line; _a < line_1.length; _a++) {
            var item = line_1[_a];
            var it = item.replace(/"/g, '""');
            if (it.search(/("|,|\n)/g) >= 0) {
                it = '"' + it + '"';
            }
            content += (i > 0 ? ',' : '') + it;
            ++i;
        }
        content += newLine;
    }
    var link = document.createElement('a');
    link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(content));
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};

1

Tải xuống tệp CSV

  let csvContent = "data:text/csv;charset=utf-8,";
  rows.forEach(function (rowArray) {
    for (var i = 0, len = rowArray.length; i < len; i++) {
      if (typeof (rowArray[i]) == 'string')
        rowArray[i] = rowArray[i].replace(/<(?:.|\n)*?>/gm, '');
      rowArray[i] = rowArray[i].replace(/,/g, '');
    }

    let row = rowArray.join(",");
    csvContent += row + "\r\n"; // add carriage return
  });
  var encodedUri = encodeURI(csvContent);
  var link = document.createElement("a");
  link.setAttribute("href", encodedUri);
  link.setAttribute("download", "fileName.csv");
  document.body.appendChild(link);
  link.click();

0

Trong trường hợp bất cứ ai cần điều này cho js loại trực tiếp, nó hoạt động tốt với cơ bản là giải pháp được đề xuất:

html:

<a data-bind="attr: {download: filename, href: csvContent}">Download</a>

xem mô hình:

// for the download link
this.filename = ko.computed(function () {
    return ko.unwrap(this.id) + '.csv';
}, this);
this.csvContent = ko.computed(function () {
    if (!this.csvLink) {
        var data = ko.unwrap(this.data),
            ret = 'data:text/csv;charset=utf-8,';

        ret += data.map(function (row) {
            return row.join(',');
        }).join('\n');

        return encodeURI(ret);
    }
}, this);

0

Tôi đã thêm vào hàm Xavier Johns để bao gồm các tiêu đề trường nếu cần, sử dụng jQuery mặc dù. Bit $ .each sẽ cần thay đổi cho vòng lặp javascript gốc

function exportToCsv(filename, rows, headers = false) {
    var processRow = function (row) {
        row = $.map(row, function(value, index) {
            return [value];
        });
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            if(i == 0 && j == 0 && headers == true){
                var ii = 0;
                $.each(rows[i], function( index, value ) {
                    //console.log(index);
                    var fieldName = index === null ? '' : index.toString();
                    //console.log(fieldName);
                    var fieldResult = fieldName.replace(/"/g, '""');
                    //console.log(fieldResult);
                    if (fieldResult.search(/("|,|\n)/g) >= 0){
                        fieldResult = '"' + fieldResult + '"';
                    }
                    //console.log(fieldResult);
                    if (ii > 0){
                        finalVal += ',';
                        finalVal += fieldResult;
                    }else{
                        finalVal += fieldResult;
                    }
                    ii++;
                    //console.log(finalVal);
                });
                finalVal += '\n';
                //console.log('end: '+finalVal);
            }
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0){
                result = '"' + result + '"';
            }
            if (j > 0){
                finalVal += ',';
                finalVal += result;
            }else{
                finalVal += result;
            }
        }
        return finalVal + '\n';
    };
    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }
    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    }else{
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

0

Đây là câu trả lời được sửa đổi dựa trên câu trả lời được chấp nhận trong đó dữ liệu sẽ đến từ JSON.

            JSON Data Ouptut:
             0 :{emails: "SAMPLE Co., peter@samplecompany.com"}, 1:{emails: "Another CO. , ronald@another.com"}


            JS:
            $.getJSON('yourlink_goes_here', { if_you_have_parameters}, function(data) {
            var csvContent = "data:text/csv;charset=utf-8,";
            var dataString = '';
             $.each(data, function(k, v) {
                dataString += v.emails + "\n";
             });

            csvContent += dataString;

            var encodedUri = encodeURI(csvContent);
            var link = document.createElement("a");
            link.setAttribute("href", encodedUri);
            link.setAttribute("download", "your_filename.csv");
            document.body.appendChild(link); // Required for FF

            link.click();
        });

0

Nếu bạn đang tìm kiếm một giải pháp thực sự nhanh chóng, bạn cũng có thể tạo cơ hội cho thư viện nhỏ này sẽ tạo và tải xuống tệp CSV cho bạn: https://github.com/mbrn/filefy

Cách sử dụng rất đơn giản:

import { CsvBuilder } from 'filefy';

var csvBuilder = new CsvBuilder("user_list.csv")
  .setColumns(["name", "surname"])
  .addRow(["Eve", "Holt"])
  .addRows([
    ["Charles", "Morris"],
    ["Tracey", "Ramos"]
  ])
  .exportFile();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.