我的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);
    document.write(allText);
    document.write(txtFile);
</script>

当前回答

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中完全有效)。但由于$是一个零长度断言,它不会进展到不匹配并结束循环。

仅供参考,我必须使第二种选择排除引号周围的值;似乎它在我的javascript引擎上的第一个替代方案之前执行,并考虑将引号作为未加引号的值的一部分。我不会问的,我刚弄好了。

其他回答

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

                        }
                      }
                    }

不要用逗号分隔——这对大多数CSV文件都不起作用,而且这个问题的视图太多了,提问者的输入数据不可能适用于所有人。解析CSV有点可怕,因为没有真正的官方标准,而且许多带分隔符的文本编写者不考虑边界情况。

这个问题很老了,但我相信现在有了更好的解决方案Papa Parse。它是我在贡献者的帮助下编写的一个库,用于解析CSV文本或文件。它是我所知道的唯一支持千兆字节大小文件的JS库。它还能优雅地处理畸形输入。

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实现。

实际上,您可以使用称为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');
  });
});

根据公认的答案,

我把这里的1改成了0

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

更改为

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

它将计算一个文件与一个连续的行作为一个allTextLines。长度为1。因此,如果循环从1开始,只要它小于1,它就永远不会运行。因此出现了空白警报框。

不需要自己写……

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

保存在'data'中的输出将是:

[
  { 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:

由于关闭谷歌代码。jquery-csv已经迁移到GitHub