javascript를 사용하여 * .CSV 파일에서 데이터를 읽는 방법은 무엇입니까?


196

내 CSV 데이터는 다음과 같습니다.

heading1, head2, heading3, head4, heading5, value1_1, value2_1, value3_1, value4_1, value5_1, value1_2, value2_2, value3_2, value4_2, value5_2 ....

Javascript를 사용 하여이 데이터를 읽고 이와 같은 배열로 어떻게 변환합니까?

[heading1 : value1_1, heading2 : value2_1, heading3 : value3_1, heading4 : value4_1, heading5 : value5_1], [heading1 : value1_2, heading2 : value2_2, heading3 : value3_2, heading4 : value4_2, heading5 : value5_2] ....

나는이 코드를 시도했지만 운이 없다! :

<script type="text/javascript">
    var allText =[];
    var allTextLines = [];
    var Lines = [];

    var txtFile = new XMLHttpRequest();
    txtFile.open("GET", "file://d:/data.txt", true);
    txtFile.onreadystatechange = function()
    {
        allText = txtFile.responseText;
        allTextLines = allText.split(/\r\n|\n/);
    };

    document.write(allTextLines);<br>
    document.write(allText);<br>
    document.write(txtFile);<br>
</script>

CSV 파일에 줄 바꿈이 없으면 JavaScript 코드에서 한 배열 (또는 객체)이 어디에서 멈추고 다른 배열이 시작하는지 알 수 없습니다 (미리 정확히 5 개의 제목이 있음을 미리 알지 않는 한). 이것은 붙여 넣기 감독입니까?
Blazemonger

예, 정확히 5 개의 필드가 있음을 미리 알고 있습니다.
Mahesh Thumar

1
다음 질문 : 솔루션에서 jQuery가 허용됩니까? 태그를 사용했지만 샘플 코드는 순수한 JavaScript입니다.
Blazemonger

예, jQuery가 허용되므로 태그에 포함시킵니다.
Mahesh Thumar

1
의 사용 file://...이 허용 되지 않는다고 생각합니다 XMLHttpRequest.
Noel Llevares

답변:


118

참고 : 이스케이프 된 따옴표와 같이 유효한 CSV 파일에서 발생할 수있는 모든 "특수 사례"에 대해 상기시키기 전에이 솔루션을 조정했습니다. 나는 빠르고 더러운 것을 원하는 사람들을 위해 대답을 남기고 있지만 정확성을 위해 Evan의 대답 을 권장 합니다.


이 코드는 data.txt파일이 줄 바꿈없이 쉼표로 구분 된 하나의 긴 문자열 일 때 작동합니다 .

data.txt :

 heading1,heading2,heading3,heading4,heading5,value1_1,...,value5_2

자바 스크립트 :

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var record_num = 5;  // or however many elements there are in each row
    var allTextLines = allText.split(/\r\n|\n/);
    var entries = allTextLines[0].split(',');
    var lines = [];

    var headings = entries.splice(0,record_num);
    while (entries.length>0) {
        var tarr = [];
        for (var j=0; j<record_num; j++) {
            tarr.push(headings[j]+":"+entries.shift());
        }
        lines.push(tarr);
    }
    // alert(lines);
}

다음 코드는 각 레코드 집합 사이에 줄 바꿈이있는 "true"CSV 파일에서 작동합니다.

data.txt :

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

자바 스크립트 :

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var allTextLines = allText.split(/\r\n|\n/);
    var headers = allTextLines[0].split(',');
    var lines = [];

    for (var i=1; i<allTextLines.length; i++) {
        var data = allTextLines[i].split(',');
        if (data.length == headers.length) {

            var tarr = [];
            for (var j=0; j<headers.length; j++) {
                tarr.push(headers[j]+":"+data[j]);
            }
            lines.push(tarr);
        }
    }
    // alert(lines);
}

http://jsfiddle.net/mblase75/dcqxr/


4
그건 그렇고, 이것은 CSV 파일에 실제로 여러 행이 있다고 가정합니다 allText.split(/\r\n|\n/). 모든 데이터가 실제로 줄 바꿈이없는 쉼표로 구분 된 긴 문자열 인 경우 실제 CSV 파일이 아닙니다.
Blazemonger

1
안녕하세요.이 코드를 사용했지만 출력이 없습니다. 빈 알림 만 표시됩니다. 내 파일은 다음과 같습니다. heading1, heading2, heading3, heading4, heading5, value1_1, value2_1, value3_1, value4_1, value5_1, value1_2, value2_2, value3_2, value4_2, value5_2 csv.html과 data.txt는 모두 같은 폴더에 있습니다
Mahesh Thumar

이것이 올바른 파일 (또는 데이터)이 아닌 경우 내 파일은 어떻게 생겼습니까?
Mahesh Thumar

7
이 코드는 유효한 모든 IETF 표준 CSV 파일을 처리하지 못할 수 있으며 쉼표, 줄 바꿈 또는 큰 따옴표가 포함 된 문자열이 있으면 실패 할 수 있습니다. 예를 들어, 1, "IETF allows ""quotes"", commas and \nline breaks"문자열이 큰 따옴표로 묶여 있고 큰 따옴표는 이스케이프되므로 허용됩니다.
프로토 타입

1
Mac에서 .csv 파일을 읽으려고했습니다. 첫 번째 스플릿을 this로 변경했을 때 줄 바꿈 문자를 인식하도록이 스크립트를 얻을 수있었습니다 var allTextLines = allText.split("\r"); . 감사!
Joe

207

직접 쓸 필요가 없습니다 ...

jQuery를-CSV의 라이브러리라는 함수가 $.csv.toObjects(csv)자동으로 매핑을 수행합니다.

참고 :이 라이브러리는 대부분의 '간단한'솔루션이 간과하는 모든 까다로운 사례를 포함하여 RFC 4180을 준수 하는 모든 CSV 데이터를 처리하도록 설계되었습니다 .

@Blazemonger가 이미 언급했듯이 먼저 데이터를 유효한 CSV로 만들려면 줄 바꿈을 추가해야합니다.

다음 데이터 세트 사용 :

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

코드를 사용하십시오 :

var data = $.csv.toObjects(csv):

'데이터'에 저장된 출력은 다음과 같습니다.

[
  { heading1:"value1_1",heading2:"value2_1",heading3:"value3_1",heading4:"value4_1",heading5:"value5_1" } 
  { heading1:"value1_2",heading2:"value2_2",heading3:"value3_2",heading4:"value4_2",heading5:"value5_2" }
]

참고 : 기술적으로 키-값 매핑을 작성하는 방법은 유효하지 않은 JavaScript입니다. 키-값 쌍을 포함하는 객체는 괄호로 묶어야합니다.

직접 사용 해보고 싶다면 'toObjects ()'탭 에서 기본 사용 데모를 살펴보십시오 .

면책 조항 : 저는 jQuery-CSV의 최초 저자입니다.

최신 정보:

op가 제공 한 데이터 세트를 사용하도록 편집하고 데이터의 유효성을 테스트 할 수있는 데모 링크를 포함했습니다.

업데이트 2 :

Google 코드가 종료 되었기 때문에. jquery-csv가 GitHub로 이동했습니다


3
"toObject"가 "toJSON"이라고 생각 될 수 있습니까? 그리고 toObjects (csv) 호출 후 콜론이 오타입니까? IOW, 세미콜론이 아니어야합니까?
B. Clay Shannon

11
CSV는 파일 이름입니까?
bubble

10
환상적인 도서관. 참고로, csv전달 된 매개 변수 는 csv 문자열입니다. csv 파일을 텍스트로 읽어 csv 문자열을 가져옵니다.
callmekatootie

3
@Evan Plaice이 라이브러리를 사용하여 csv 파일을 읽는 방법은 무엇입니까?
Richa Sinha 2016 년

1
@RichaSinha HTML5 파일 API 또는 AJAX를 통해 파일을 텍스트 버퍼로 읽습니다. 그런 다음 문자열 버퍼를 파서에 전달하십시오. 결과적으로 데이터 배열을 뱉어냅니다. 예제는 프로젝트 페이지를 참조하십시오.
Evan Plaice

75

쉼표로 나누지 마십시오. 대부분의 CSV 파일에서는 작동하지 않으며이 질문에는 길잡이 종류의 입력 데이터가 모든 사람에게 적용 되기에는 너무 많은보기가 있습니다. CSV를 파싱하는 것은 실제로 공식적인 표준이 없기 때문에 무섭고, 많은 구분 된 텍스트 작성자는 가장자리를 고려하지 않습니다.

이 질문은 오래되었지만 지금은 Papa Parse 를 사용할 수 있는 더 나은 솔루션이 있다고 생각 합니다. CSV 텍스트 또는 파일을 구문 분석하는 컨트 리뷰 터의 도움을 받아 작성한 라이브러리입니다. 내가 아는 유일한 JS 라이브러리는 기가 바이트 크기의 파일을 지원합니다. 또한 잘못된 입력을 정상적으로 처리합니다.

1 분 내에 1GB 파일 구문 분석 : 1 분 내에 1GB 파일을 구문 분석했습니다.

( 업데이트 : Papa Parse 4를 사용하면 Firefox에서 동일한 파일이 약 30 초 밖에 걸리지 않았습니다. 이제 Papa Parse 4는 브라우저 에서 가장 빠른 알려진 CSV 파서 입니다.)

텍스트 파싱은 매우 쉽습니다.

var data = Papa.parse(csvString);

파일 파싱도 쉽습니다.

Papa.parse(file, {
    complete: function(results) {
        console.log(results);
    }
});

스트리밍 파일은 비슷합니다 (원격 파일을 스트리밍하는 예는 다음과 같습니다).

Papa.parse("http://example.com/bigfoo.csv", {
    download: true,
    step: function(row) {
        console.log("Row:", row.data);
    },
    complete: function() {
        console.log("All done!");
    }
});

구문 분석 중에 웹 페이지가 잠기는 경우 Papa는 웹 작업자를 사용하여 웹 사이트를 반응 적으로 유지할 수 있습니다.

헤더 행이 존재하는 경우 Papa는 구분 기호를 자동 감지하고 값을 헤더 열과 일치시킬 수 있습니다. 숫자 값을 실제 숫자 유형으로 바꿀 수도 있습니다. 줄 바꿈과 따옴표 및 기타 이상한 상황을 적절하게 구문 분석하고 잘못된 입력을 가능한 한 강력하게 처리합니다. Papa를 만들기 위해 기존 라이브러리에서 영감을 얻어 다른 JS 구현에 소품을 사용했습니다.


아빠는 사용하기 쉽고 빠릅니다! 감사!
Technotronic

Papa Parse에서 +1 잘했습니다. 언젠가 큰 파일과 스트리밍을 처리하는 방법을 알아보기 위해 자세히 연구하고 싶습니다. 다른 개발자가 jquery-csv가 중단 된 부분을 다루는 모든 기능을 갖춘 파서를 작성하는 것을 보게되어 매우 기쁩니다.
Evan Plaice

3
@EvanPlaice 감사합니다. 지난 밤 현지 모임에서 docs.google.com/presentation/d/…
Matt

1
@ Matt 그것은 파파에 대해 더 이해하기 쉽게 설명하는 멋진 프리젠 테이션이었습니다
siva

1
@ Malky.Kid 유효한 CSV가 아닙니다 (즉, 구분되지 않은 값의 공백은 좋지 않습니다). MS Excel의 CSV 형식 구현이 짜증납니다. 여전히 소스 파일에 액세스 할 수있는 경우 따옴표 구분 기호를 활성화하는 옵션이 있어야합니다. 일단 그렇게하면 데이터가 csv 파서와 함께 작동해야합니다.
Evan Plaice

10

CSV 파일을 구문 분석하기 위해 d3.js 를 사용하고 있습니다. 사용하기 매우 쉽습니다. 여기 문서가 있습니다.

단계 :

  • npm 설치 d3- 요청

Es6 사용;

import { csv } from 'd3-request';
import url from 'path/to/data.csv';

csv(url, function(err, data) {
 console.log(data);
})

자세한 내용은 문서 를 참조하십시오 .

업데이트 -d3- 요청은 더 이상 사용되지 않습니다. 당신은 d3-fetch를 사용할 수 있습니다



3

따옴표 안에 쉼표를 사용하여 CSV 데이터를 구문 분석하는 JavaScript 함수가 있습니다.

// Parse a CSV row, accounting for commas inside quotes                   
function parse(row){
  var insideQuote = false,                                             
      entries = [],                                                    
      entry = [];
  row.split('').forEach(function (character) {                         
    if(character === '"') {
      insideQuote = !insideQuote;                                      
    } else {
      if(character == "," && !insideQuote) {                           
        entries.push(entry.join(''));                                  
        entry = [];                                                    
      } else {
        entry.push(character);                                         
      }                                                                
    }                                                                  
  });
  entries.push(entry.join(''));                                        
  return entries;                                                      
}

함수를 사용하여 다음과 같은 CSV 파일을 구문 분석하는 예제 :

"foo, the column",bar
2,3
"4, the value",5

배열로 :

// csv could contain the content read from a csv file
var csv = '"foo, the column",bar\n2,3\n"4, the value",5',

    // Split the input into lines
    lines = csv.split('\n'),

    // Extract column names from the first line
    columnNamesLine = lines[0],
    columnNames = parse(columnNamesLine),

    // Extract data from subsequent lines
    dataLines = lines.slice(1),
    data = dataLines.map(parse);

// Prints ["foo, the column","bar"]
console.log(JSON.stringify(columnNames));

// Prints [["2","3"],["4, the value","5"]]
console.log(JSON.stringify(data));

D3의 csv 파서 (솔리드 써드 파티 솔루션) 와 같이 데이터를 오브젝트로 변환하는 방법은 다음과 같습니다 .

var dataObjects = data.map(function (arr) {
  var dataObject = {};
  columnNames.forEach(function(columnName, i){
    dataObject[columnName] = arr[i];
  });
  return dataObject;
});

// Prints [{"foo":"2","bar":"3"},{"foo":"4","bar":"5"}]
console.log(JSON.stringify(dataObjects));

이 코드작동하는 바이올린은 다음과 같습니다 .

즐겨! - 커란


1

jQuery를 사용하여 외부 CSV를 Javascript읽는 또 다른 방법이 있습니다.

조금 더 오래 감겨 있지만 데이터를 배열로 읽어서 프로세스를 정확하게 따르고 문제를 쉽게 해결할 수 있다고 생각합니다.

다른 사람을 도울 수 있습니다.

데이터 파일 예 :

Time,data1,data2,data2
08/11/2015 07:30:16,602,0.009,321

그리고 여기 코드가 있습니다 :

$(document).ready(function() {
 // AJAX in the data file
    $.ajax({
        type: "GET",
        url: "data.csv",
        dataType: "text",
        success: function(data) {processData(data);}
        });

    // Let's process the data from the data file
    function processData(data) {
        var lines = data.split(/\r\n|\n/);

        //Set up the data arrays
        var time = [];
        var data1 = [];
        var data2 = [];
        var data3 = [];

        var headings = lines[0].split(','); // Splice up the first row to get the headings

        for (var j=1; j<lines.length; j++) {
        var values = lines[j].split(','); // Split up the comma seperated values
           // We read the key,1st, 2nd and 3rd rows 
           time.push(values[0]); // Read in as string
           // Recommended to read in as float, since we'll be doing some operations on this later.
           data1.push(parseFloat(values[1])); 
           data2.push(parseFloat(values[2]));
           data3.push(parseFloat(values[3]));

        }

    // For display
    var x= 0;
    console.log(headings[0]+" : "+time[x]+headings[1]+" : "+data1[x]+headings[2]+" : "+data2[x]+headings[4]+" : "+data2[x]);
    }
})

이것이 미래의 누군가를 돕기를 바랍니다!


앞으로 부터이 답변을 시도했지만 )45 번째 줄에 부호 가 없어서 추가했지만 9 번째 줄에서 콘솔 오류가 발생 Uncaught ReferenceError: $ is not defined at index.html:9했습니다.이를 도와 줄 수 있습니까?
Lasagna Cat

1
function CSVParse(csvFile)
{
    this.rows = [];

    var fieldRegEx = new RegExp('(?:\s*"((?:""|[^"])*)"\s*|\s*((?:""|[^",\r\n])*(?:""|[^"\s,\r\n]))?\s*)(,|[\r\n]+|$)', "g");   
    var row = [];
    var currMatch = null;

    while (currMatch = fieldRegEx.exec(this.csvFile))
    {
        row.push([currMatch[1], currMatch[2]].join('')); // concatenate with potential nulls

        if (currMatch[3] != ',')
        {
            this.rows.push(row);
            row = [];
        }

        if (currMatch[3].length == 0)
            break;
    }
}

정규식을 최대한 많이 사용하고 싶습니다. 이 정규식은 모든 항목을 따옴표로 묶거나 따옴표로 묶지 않고 열 구분 기호 또는 행 구분 기호로 처리합니다. 또는 텍스트의 끝.

그렇기 때문에 마지막 조건은 패턴이 길이가 0 인 필드와 일치 할 수 있기 때문에 무한 루프 일 것입니다 (csv에서 완전히 유효 함). 그러나 $는 길이가 0 인 주장이므로 일치하지 않고 진행되지 않고 루프를 종료합니다.

그리고 참고로, 나는 가치를 둘러싼 두 번째 대안을 따옴표로 묶어야했습니다. 내 자바 스크립트 엔진의 첫 번째 대안 이전에 실행되고 따옴표를 인용되지 않은 값의 일부로 고려한 것처럼 보입니다. 묻지 않고 그냥 작동시킵니다.


불행히도 나는이 기능으로 무한 루프에 빠졌습니다.
Hauke

@Hauke-데이터를 여전히 무한 루프를 생성하는 몇 개의 열과 줄로 나눌 수 있다면 감사하겠습니다. 왜냐하면 내가 왜 실패했는지에 대한 통찰력을 줄 수 있습니다.
Gerard ONeill

1

허용 대답 ,

여기서 1을 0으로 변경 하여이 작업을 수행했습니다.

for (var i=1; i<allTextLines.length; i++) {

로 변경

for (var i=0; i<allTextLines.length; i++) {

allTextLines.length가 1 인 연속 행이 하나 인 파일을 계산합니다. 따라서 루프가 1에서 시작하여 1보다 작 으면 실행되지 않습니다. 따라서 빈 경고 상자입니다.


0

Ajax 를 사용 하지 않고이 문제를 해결 하려면 FileReader()Web API를 사용하십시오 .

구현 예 :

  1. .csv파일 선택
  2. 출력 참조

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }

  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    displayContents(contents);
    displayParsed(contents);
  };
  reader.readAsText(file);
}

function displayContents(contents) {
  var element = document.getElementById('file-content');
  element.textContent = contents;
}

function displayParsed(contents) {
  const element = document.getElementById('file-parsed');
  const json = contents.split(',');
  element.textContent = JSON.stringify(json);
}

document.getElementById('file-input').addEventListener('change', readSingleFile, false);
<input type="file" id="file-input" />

<h3>Raw contents of the file:</h3>
<pre id="file-content">No data yet.</pre>

<h3>Parsed file contents:</h3>
<pre id="file-parsed">No data yet.</pre>


0
$(function() {

      $("#upload").bind("click", function() {
            var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.xlsx)$/;
            if (regex.test($("#fileUpload").val().toLowerCase())) {
              if (typeof(FileReader) != "undefined") {
                var reader = new FileReader();
                reader.onload = function(e) {
                    var customers = new Array();
                    var rows = e.target.result.split("\r\n");
                    for (var i = 0; i < rows.length - 1; i++) {
                      var cells = rows[i].split(",");
                      if (cells[0] == "" || cells[0] == undefined) {
                        var s = customers[customers.length - 1];
                        s.Ord.push(cells[2]);
                      } else {
                        var dt = customers.find(x => x.Number === cells[0]);
                        if (dt == undefined) {
                          if (cells.length > 1) {
                            var customer = {};
                            customer.Number = cells[0];
                            customer.Name = cells[1];
                            customer.Ord = new Array();

                            customer.Ord.push(cells[2]);
                            customer.Point_ID = cells[3];
                            customer.Point_Name = cells[4];
                            customer.Point_Type = cells[5];
                            customer.Set_ORD = cells[6];
                            customers.push(customer);
                          }
                        } else {
                          var dtt = dt;
                          dtt.Ord.push(cells[2]);

                        }
                      }
                    }

이 코드가 문제를 해결하는 방법과 이유에 대한 설명포함 하여 문제를 해결할 수는 있지만 게시물의 품질을 향상시키는 데 도움이되며 더 많은 투표를 할 수 있습니다. 지금 질문하는 사람뿐만 아니라 앞으로 독자들에게 질문에 대답하고 있음을 기억하십시오. 제발 편집 설명을 추가하고 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을. 검토에서
이중 신호음

0

실제로 any-text 라는 경량 라이브러리를 사용할 수 있습니다 .

  • 의존성 설치
npm i -D any-text
  • 사용자 정의 명령을 사용하여 파일 읽기
var reader = require('any-text');
 
reader.getText(`path-to-file`).then(function (data) {
  console.log(data);
});

또는 async-await 사용하십시오 :

var reader = require('any-text');
 
const chai = require('chai');
const expect = chai.expect;
 
describe('file reader checks', () => {
  it('check csv file content', async () => {
    expect(
      await reader.getText(`${process.cwd()}/test/files/dummy.csv`)
    ).to.contains('Lorem ipsum');
  });
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.