如何使用javascript从*.CSV文件中读取数据?

IT技术 javascript jquery
2021-01-18 09:31:10

我的 csv 数据如下所示:

标题1,标题2,标题3,标题4,标题5,值1_1,值2_1,值3_1,值4_1,值5_1,值1_2,值2_2,值3_2,值4_2,值5_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>
6个回答

不需要自己写...

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:

由于谷歌代码的关闭。jquery-csv 已移至 GitHub

IOW,“toObject”是或可以被认为是“toJSON”,不是吗?并且,调用 toObjects(csv) 后的冒号是否是错字?IOW,不应该是分号吗?
2021-03-22 09:31:10
@RichaSinha 通过 HTML5 文件 API 或 AJAX 将文件作为文本缓冲区读入。然后将字符串缓冲区传递给解析器。结果它会吐出一组数据。有关示例,请参阅项目页面。
2021-03-27 09:31:10
很棒的图书馆。仅供参考,csv传递的参数是一个 csv 字符串 - 将 csv 文件作为文本读取以获取 csv 字符串。
2021-03-28 09:31:10
@Evan Plaice 如何使用这个库读取 csv 文件?
2021-03-29 09:31:10
@GreySage 可以理解,jquery-csv 实际上并不需要 jquery。它只是一组附加实用程序函数,它们附加到 jquery 命名空间以保持一致性。最初的意图是扩展 jquery(伪 monad)对象模型。也许有一天,如果 :: 运算符被添加到 Javascript 中,这将成为现实,现在项目范围被冻结在维护模式。
2021-04-05 09:31:10

注意:在我被提醒所有可能出现在有效 CSV 文件中的“特殊情况”之前,我炮制了这个解决方案,比如转义引号。我将我的答案留给那些想要快速而肮脏的人,但为了准确起见,我推荐Evan 的答案


当您的data.txt文件是一长串以逗号分隔的条目且没有换行符时,此代码将起作用

数据.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 文件:

数据.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/

如果这不是正确的文件(或数据),那么我的文件应该是什么样的??
2021-03-14 09:31:10
顺便说一下,这假设 CSV 文件实际上确实有多行——这就是allText.split(/\r\n|\n/)拆分的原因。如果您的所有数据实际上都是一长串逗号分隔的数据,没有换行符,那么它就不是真正的 CSV 文件。
2021-03-17 09:31:10
嗨,我用过这个代码:但是没有输出。只显示一个空白警报。我的文件看起来像: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 都在同一个文件夹中
2021-03-19 09:31:10
代码可能无法处理所有有效的 IETF 标准 CSV 文件,如果存在嵌入逗号、换行符或双引号的字符串,则代码可能会失败。例如, 1, "IETF allows ""quotes"", commas and \nline breaks"这是允许的,因为字符串被双引号包围,并且双引号被转义。
2021-03-27 09:31:10
我试图从 Mac 读取 .csv 文件。当我将第一个拆分更改为这个时,我只能让这个脚本识别换行符var allTextLines = allText.split("\r"); ,然后它工作得很好!谢谢!
2021-03-30 09:31:10

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

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

1 分钟内解析 1 GB 文件: 1 分钟解析 1 GB 文件

更新:使用 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 可以使用网络工作者来保持您的网站react性。

如果存在标题行,Papa 可以自动检测分隔符并将值与标题列匹配。它还可以将数值转换为实际的数字类型。它适当地解析换行符和引号以及其他奇怪的情况,甚至尽可能稳健地处理格式错误的输入。我从现有库中汲取灵感来制作 Papa,因此支持其他 JS 实现。

@Matt 那是一个很棒的演示文稿,它以更容易理解的方式描述了 papa parse
2021-03-11 09:31:10
@EvanPlace 谢谢。你可能喜欢我昨晚在当地聚会上做的这个演讲:docs.google.com/presentation/d/...
2021-03-17 09:31:10
爸爸易于使用且速度快!谢谢!
2021-03-19 09:31:10
@Malky.Kid 这不是有效的 CSV(即非分隔值中的空格不好)。MS Excel 的 CSV 格式实现很糟糕。如果您仍然可以访问源文件,则应该有一个选项可以启用引号分隔符。一旦你这样做了,你的数据应该可以与任何 csv 解析器一起使用。
2021-03-30 09:31:10
+1 在 Papa Parse 上做得很好。我想有一天详细研究它,看看你是如何处理大文件和流媒体的。我很高兴看到其他开发人员编写功能齐全的解析器,从 jquery-csv 停止的地方开始。
2021-03-31 09:31:10

我正在使用d3.js来解析 csv 文件。非常容易使用。这是文档

脚步:

  • npm 安装 d3 请求

使用 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

这是一个解析 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));

是这段代码工作小提琴

享受!——可