How to read data From *.CSV file using javascript?
我的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 ]....
我已经尝试过此代码,但是没有运气!:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <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(/ | /); }; document.write(allTextLines); document.write(allText); document.write(txtFile); |
不需要自己写...
jQuery-CSV库具有一个称为
注意:该库旨在处理符合RFC 4180的所有CSV数据,包括大多数"简单"解决方案都忽略的所有讨厌的边缘情况。
就像@Blazemonger已经说过的一样,首先您需要添加换行符以使数据有效为CSV。
使用以下数据集:
1 2 3 | 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 |
使用代码:
1 | var data = $.csv.toObjects(csv): |
保存在"数据"中的输出将是:
1 2 3 4 | [ { 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 Code的关闭。 jquery-csv已移至GitHub
注意:在提醒我有效的CSV文件中可能出现的所有"特殊情况"(例如转义引号)之前,我都采用了这种解决方案。我将答案留给那些想要快速又脏的东西的人,但我建议使用Evan的答案以确保准确性。
当您的
data.txt:
1 | heading1,heading2,heading3,heading4,heading5,value1_1,...,value5_2 |
javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | $(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(/ | /); 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:
1 2 3 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | $(document).ready(function() { $.ajax({ type:"GET", url:"data.txt", dataType:"text", success: function(data) {processData(data);} }); }); function processData(allText) { var allTextLines = allText.split(/ | /); 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/
不要用逗号分开-它不适用于大多数CSV文件,并且这个问题对于请求者的输入数据有太多观点,以至于无法应用于所有人。解析CSV有点吓人,因为还没有真正的官方标准,而且许多带分隔符的文本编写者都没有考虑边缘情况。
这个问题很老,但是我相信现在有了Papa Parse会有更好的解决方案。这是我在贡献者的帮助下编写的用于解析CSV文本或文件的库。这是我所知道的唯一一个支持GB大小的文件的JS库。它还可以优雅地处理格式错误的输入。
1分钟内解析出1 GB文件:
(更新:使用Papa Parse 4,同一文件在Firefox中仅花费了大约30秒。PapaParse 4现在是浏览器中已知最快的CSV解析器。)
解析文本非常简单:
1 | var data = Papa.parse(csvString); |
解析文件也很容易:
1 2 3 4 5 | Papa.parse(file, { complete: function(results) { console.log(results); } }); |
流文件类似(这是流远程文件的示例):
1 2 3 4 5 6 7 8 9 | Papa.parse("http://example.com/bigfoo.csv", { download: true, step: function(row) { console.log("Row:", row.data); }, complete: function() { console.log("All done!"); } }); |
如果您的网页在解析过程中被锁定,Papa可以使用Web Worker使您的网站保持被动状态。
如果存在标题行,Papa可以自动检测定界符并与标题列匹配值。它还可以将数值转换为实际的数字类型。它可以适当地分析换行符和引号以及其他奇怪的情况,甚至可以尽可能稳健地处理格式错误的输入。我从现有库中汲取了灵感来制作Papa,因此成为其他JS实现的支撑。
我正在使用d3.js解析csv文件。很好用。
这是文档。
脚步:
- npm install d3-request
使用Es6;
1 2 3 4 5 6 | import { csv } from 'd3-request'; import url from 'path/to/data.csv'; csv(url, function(err, data) { console.log(data); }) |
请参阅文档以了解更多信息。
更新-
d3请求已弃用。您可以使用d3-fetch
您可以使用PapaParse来提供帮助。
https://www.papaparse.com/
这是一个CodePen。
https://codepen.io/sandro-wiggers/pen/VxrxNJ
1 2 3 4 5 6 | Papa.parse(e, { header:true, before: function(file, inputElem){ console.log('Attempting to Parse...')}, error: function(err, file, inputElem, reason){ console.log(err); }, complete: function(results, file){ $.PAYLOAD = results; } }); |
这是一个JavaScript函数,用于解析CSV数据,并计算引号内的逗号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // 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文件的示例:
1 2 3 | "foo, the column",bar 2,3 "4, the value",5 |
分成数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // csv could contain the content read from a csv file var csv = '"foo, the column",bar 2,3 "4, the value",5', // Split the input into lines lines = csv.split(' '), // 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解析器(这是可靠的第三方解决方案):
1 2 3 4 5 6 7 8 9 10 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | function CSVParse(csvFile) { this.rows = []; var fieldRegEx = new RegExp('(?:\s*"((?:""|[^"])*)"\s*|\s*((?:""|[^", ])*(?:""|[^"\s, ]))?\s*)(,|[ ]+|$)',"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中完全有效)。但是由于$是零长度的断言,它不会发展为不匹配并结束循环。
仅供参考,我必须做出第二种选择,排除围绕该值的引号;似乎它在我的javascript引擎上的第一个替代方法之前执行,并将引号视为未引号值的一部分。我不会问-只是让它起作用。
这是将外部CSV读入Javascript(使用jQuery)的另一种方法。
这有点冗长,但是我觉得通过将数据读入数组,您可以完全按照流程进行操作,并且可以轻松地进行故障排除。
可能会帮助别人。
数据文件示例:
1 2 | Time,data1,data2,data2 08/11/2015 07:30:16,602,0.009,321 |
这是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | $(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(/ | /); //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]); } }) |
希望这对以后的人有所帮助!
根据公认的答案,
我通过将1更改为0来使它起作用:
1 | for (var i=1; i<allTextLines.length; i++) { |
变成
1 | for (var i=0; i<allTextLines.length; i++) { |
它会计算一个文件,该文件的allTextLines.length为1,并且连续一行。因此,如果循环从1开始并一直运行,只要循环长度小于1,就永远不会运行。因此,空白警报框。