JavaScriptを使用して* .CSVファイルからデータを読み取る方法は?


192

私の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 ....

どのようにこのデータを読み取り、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コードは、1つの配列(またはオブジェクト)がどこで停止し、もう1つの配列が開始するかを知ることができません(常に正確に5つの見出しがあることが事前にわかっている場合を除く)。これはカットアンドペーストによる見落としでしたか?
Blazemonger、2011

はい、正確に5つのフィールドがあることを事前に知っています。
Mahesh Thumar、2011

1
次の質問:ソリューションでjQueryは許可されますか?タグを使用しましたが、サンプルコードは純粋なJavaScriptです。
Blazemonger、2011

はい、jQueryは許可されています。そのため、タグに含めます。
Mahesh Thumar、2011

1
の使用file://...は許可されていないと思いますXMLHttpRequest
Noel Llevares

回答:


118

注:エスケープされた引用符など、有効なCSVファイルで発生する可能性のあるすべての「特殊なケース」について思い出される前に、この解決策を考え出しました。私は迅速で汚いものを求めている人のために私の答えを残しますが、正確さのためにエヴァンの答えをお勧めします。


このコードは、data.txtファイルがカンマで区切られたエントリの1つの長い文字列で、改行がない場合に機能します。

data.txt:

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

javascript:

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

次のコードは、各レコードセット間に改行を含む「真の」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

javascript:

$(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/)分割されます。すべてのデータが実際に、改行のないコンマ区切りデータの1つの長い文字列である場合、それは実際のCSVファイルではありません。
Blazemonger、2011

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、2011

7
コードは、有効なIETF標準CSVファイルをすべて処理するわけではなく、コンマ、改行、または二重引用符が埋め込まれた文字列がある場合は失敗する可能性があります。たとえば1, "IETF allows ""quotes"", commas and \nline breaks"、文字列が二重引用符で囲まれ、二重引用符がエスケープされているため、これは許可されます 。
プロトタイプ

1
Macから.csvファイルを読み取ろうとしました。最初の分割をこれに変更したときにのみ、このスクリプトで改行文字を認識できました。var allTextLines = allText.split("\r"); その後、うまくいきました。ありがとう!
Joe

204

自分で書く必要はありません...

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の最初の作者です。

更新:

オペレーションが提供したデータセットを使用するように編集し、データの有効性をテストできるデモへのリンクを含めました。

Update2:

Google Codeのシャッターのため。jquery-csvがGitHubに移動しました


3
IOW、「toObject」は「toJSON」であると考えることができますか?そして、toObjects(csv)への呼び出しに続くコロンはタイプミスですか?IOW、それはセミコロンではないですか?
B.クレイシャノン

11
CSVはファイル名ですか?
バブル

10
素晴らしいライブラリ。参考までに、csv渡されるパラメータはcsv文字列です-csvファイルをテキストとして読み取り、csv文字列を取得します。
callmekatootie 2014年

3
@Evan Plaice csvファイルから読み取るためにこのライブラリを使用する方法?
Richa Sinha

1
@RichaSinha HTML5ファイルAPIまたはAJAXを介してテキストバッファーとしてファイルを読み取ります。次に、文字列バッファをパーサーに渡します。結果として、データの配列を吐き出します。例については、プロジェクトページを参照してください。
Evan Plaice

75

カンマで区切らないでください-ほとんどのCSVファイルでは機能しません。この質問では、質問者の種類の入力データが多すぎるため、ビューが多すぎます。本当に公式な標準がないため、CSVの解析はちょっと怖いです。多くの区切られたテキストライターは、エッジケースを考慮していません。

この質問は古いですが、パパ・パースが今より良い解決策があると思いますが利用可能にます。これは、寄稿者の協力を得て私が作成したライブラリで、CSVテキストまたはファイルを解析します。サイズがギガバイトのファイルをサポートしているのは、私が知っている唯一のJSライブラリです。また、不正な入力を適切に処理します。

1分で解析される1 GBファイル: 1分で1 GBのファイルを解析

更新: Papa Parse 4を使用すると、Firefoxで同じファイルが約30秒しかかかりませんでした。PapaParse 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!");
    }
});

解析中にWebページがハングアップした場合、PapaはWebワーカーを使用してWebサイトの反応を維持できます。

Papaはデリミタを自動検出し、ヘッダー行が存在する場合はヘッダー列と値を一致させます。数値を実際の数値型に変換することもできます。改行や引用符、その他の奇妙な状況を適切に解析し、不正な入力も可能な限り堅牢に処理します。私は既存のライブラリーからインスピレーションを得てPapaを作成しているので、他のJS実装をサポートしています。


パパは使いやすくて速いです!ありがとう!
Technotronic、2015年

+1パパパースでお見事。いつか詳細に調べて、大きなファイルとストリーミングをどのように処理したかを確認したいと思います。他の開発者が、jquery-csvが中断したところから再開する、完全な機能を備えたパーサーを作成しているのを見て、とても嬉しく思います。
Evan Plaice、2015

3
@EvanPlaiceありがとう。:あなたは、私が交流会で昨晩与えたこのプレゼンテーションを好むかもしれないdocs.google.com/presentation/d/...
マット

1
@ Mattそれは
パパパース

1
@ Malky.Kidこれは有効なCSVではありません(区切り文字のない値のスペースは適切ではありません)。MS ExcelのCSV形式の実装はひどい。それでもソースファイルにアクセスできる場合は、引用符区切り文字を有効にするオプションが必要です。これを実行すると、データはcsvパーサーで動作するはずです。
エヴァンプライス

9

csvファイルの解析にd3.jsを使用しています。とても使いやすい。こちらがドキュメントです。

手順:

  • npm install d3-request

Es6の使用;

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

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

詳しくはドキュメントをご覧ください。

更新 -d3-requestは非推奨です。あなたは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が表示されます。
ラザニア猫

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

正規表現にできる限り多くのことをしてもらいたい。この正規表現は、すべてのアイテムを引用符付きまたは引用符なしのいずれかとして扱い、その後に列区切り文字または行区切り文字を続けます。またはテキストの終わり。

これが最後の条件である理由です。パターンがないと長さゼロのフィールド(csvで完全に有効)に一致する可能性があるため、これがないと無限ループになります。しかし、$は長さゼロのアサーションであるため、一致しないものに進んでループを終了することはありません。

そして参考までに、私は2番目の選択肢に値を囲む引用符を除外させなければなりませんでした。それは私のJavaScriptエンジンで最初の選択肢の前に実行されていて、引用符を引用符で囲まれていない値の一部と見なしていたようです。私は尋ねません-うまくいきました。


残念ながら、私はこの関数で無限ループに入りました。
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から始まり、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]);

                        }
                      }
                    }

このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、投票数が増える可能性があります。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。口コミから
ダブルビープ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.