자바스크립트 JavaScript 배열 정보를 csv(클라이언트 측)로 내보내는 방법은 무엇입니까?




자바스크립트 배열 선언 (18)

나는이 문제에 대해 많은 질문을하지만 JavaScript를 사용하여이 작업을 수행해야한다는 것을 알고 있습니다. 나는 Dojo 1.8 하고 있으며 다음과 같은 배열의 모든 속성 정보를 갖고있다.

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

클라이언트 측에서 이것을 어떻게 CSV 내보낼 수 있습니까?


이 솔루션은 Internet Explorer 10 이상, Edge, 이전 버전 및 새로운 버전의 Chrome, FireFox, Safari, ++

허용 된 대답은 IE와 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');

코드 스 니펫을 실행하면 모의 데이터가 csv로 다운로드됩니다.

dandavis의 크레딧 https://.com/a/16377813/1350598


기본 JavaScript에서이 작업을 수행 할 수 있습니다. 데이터를 올바른 CSV 형식으로 구문 분석해야합니다 (질문에 설명 된대로 데이터에 대한 배열 배열을 사용한다고 가정).

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

그런 다음 JavaScript의 window.openencodeURI 함수를 사용하여 CSV 파일을 다운로드 할 수 있습니다.

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

편집하다:

파일에 특정 이름을 지정하려면 window.open 메서드를 사용하여 데이터 URI에 액세스하는 것이 지원되지 않으므로 약간 다르게해야합니다. 이를 달성하기 위해 숨겨진 <a> DOM 노드를 만들고 다음과 같이 download 속성을 설정할 수 있습니다.

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

이 함수를 사용하여 string[][] 을 csv 파일로 변환합니다. " , 또는 다른 공백 (공백 제외)이 들어있는 경우 셀을 인용합니다.

/**
 * 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

}

참고 : map 이 폴리 폴리되지 않으면 Internet Explorer <11에서 작동하지 않습니다.

참고 : 셀에 숫자가 들어있는 if (cell.replace... 숫자를 문자열로 변환하려면 if (cell.replace... 앞에 cell=''+cell 추가 할 수 있습니다.

또는 ES6을 사용하여 한 줄로 작성할 수 있습니다.

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

누군가가 녹아웃 js이 필요하면, 그것은 기본적으로 제안 된 솔루션으로 확인 작동 :

html :

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

모델보기 :

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

모든 언어 작업

        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', '日本語'],
    ])

Xavier Johns 함수를 추가하여 필요한 경우 필드 머리글을 포함하고 jQuery를 사용합니다. $. 각 비트는 기본 자바 스크립트 루프를 변경해야합니다.

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

여기에 두 가지 질문이 있습니다.

  1. 배열을 csv 문자열로 변환하는 방법
  2. 해당 문자열을 파일에 저장하는 방법

첫 번째 질문 (밀리미터 식으로 작성한 질문 제외)에 대한 모든 답은 과장된 것 같습니다. 그리고 밀리 메트릭 (Milimetric)은 따옴표가있는 문자열을 둘러 보거나 객체 배열을 변환하는 등의 다른 요구 사항을 다루지 않습니다.

여기 내 걸릴이 있습니다 :

간단한 CSV의 경우 하나의 map ()과 join ()으로 충분합니다.

    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

또한이 방법을 사용하면 내부 조인에서 쉼표 이외의 열 구분 기호를 지정할 수 있습니다. 예 : 탭 : d.join('\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

다음과 같은 객체 배열이있는 경우 :

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

위의 답변을 바탕으로 IE 11, Chrome 36 및 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);
        }
    }
}

예 : https://jsfiddle.net/jossef/m3rrLzk0/


ES6의 화살표 기능 하나 :

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

다음 :

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

누군가가 reactjs 필요로하는 경우에, react-csv 가 거기에 있습니다.


PapaParse와 같은 라이브러리를 사용하는 것이 좋습니다. https://github.com/mholt/PapaParse

수락 된 답변에는 현재 다음과 같은 여러 가지 문제가 있습니다.

  • 데이터에 쉼표가 있으면 실패합니다.
  • 데이터에 줄 바꿈이 있으면 실패합니다.
  • 데이터에 따옴표가 들어 있으면 (종류) 실패합니다.

Chrome 35 업데이트에서 다운로드 속성 동작이 변경되었습니다.

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

크롬에서이 작업을하려면 다음을 사용하십시오.

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

csv 데이터와 함께 blob 만들기 .ie var blob = new Blob([data], type:"text/csv");

브라우저가 blob의 저장을 지원 if window.navigator.mSaveOrOpenBlob)===true 예 : if window.navigator.mSaveOrOpenBlob)===true 이면 다음을 사용하여 csv 데이터를 저장합니다. window.navigator.msSaveBlob(blob, 'filename.csv')

브라우저가 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 friendly 버전입니다.

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

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

여기에 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 됩니다.


이것은 데이터가 JSON에서 오는 것으로 대답 한 대답을 기반으로 수정 된 답변입니다.

            JSON Data Ouptut:
             0 :{emails: "SAMPLE Co., [email protected]"}, 1:{emails: "Another CO. , [email protected]"}


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

다음은 Java GWT 애플리케이션의 클라이언트 측에서 CSV 파일을 다운로드하는 방법입니다. 그의 솔루션에 대한 Xavier John에게 특별히 감사드립니다. FF 24.6.0, IE 11.0.20 및 Chrome 45.0.2454.99 (64 비트)에서 작동하는 것으로 확인되었습니다. 나는 이것이 누군가에게 약간의 시간을 절약하기를 희망한다.

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);
            }
        }
    }-*/;
}

@Default의 솔루션은 Chrome에서 완벽하게 작동합니다 (덕분에 많은 도움이되었지만!)하지만 IE에는 문제가있었습니다.

해결책은 다음과 같습니다 (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")






client-side