将csv文件加载到jQuery中?

8
我有一个CSV文件,想将其用作jQuery flot图表的数据源。我应该:
1. 找到一个能够直接加载CSV文件的jQuery插件吗? 2. 将CSV文件转换为JSON并使用它代替? 3. 还是采取完全不同的方法?
我没有找到一个能够处理外部CSV文件的jQuery插件,但也许我漏掉了什么。

看起来将CSV转换为JSON是您在这里的最佳选择。如果还没有服务器端解析器(不太可能),您可以编写一个。 - Bojangles
@JamWaffles 这里完全不需要进行JSON转换和服务器端代码。有关详细信息,请参见我的答案。 - Evan Plaice
2个回答

11
无需服务器...

如果你运用一些巧妙的方法,就可以在不使用服务器的情况下完成。

你需要两个东西:

jquery-csv解析库专门用于解析符合RFC 4180标准的CSV,具有许多超出将CSV数据转换为JavaScript数据的功能。为了演示的目的,我们将使用两个特性:

第一个是toArrays()方法。它将多行CSV字符串转换为2D数组。

第二个是用户定义的解析器钩子,自动将输出(即所有字符串)转换为标量(即整数/浮点数)数据。基本上,通过使用函数回调,可以将额外的处理内联到解析器中。

一旦将CSV数据分配给字符串变量,将其转换为JavaScript数据非常简单。

var csv = "" // this is the string containing the CSV data
var data = $.csv.toArray(csv, {
  onParseValue: $.csv.hooks.castToScalar
});

这就是CSV解析步骤的全部内容。
现在,Flot期望的是一个由2D数组组成的数组,其中每个2D数组包含一个独立的数据集。
为了构建您的数据,请首先创建一个空数组:
var flotData = [];

然后,对于每个使用CSV生成的数据集,您只需将数据集添加到集合中。
var flotData.push(data);

使用HTML5进行文件处理是一个棘手的话题,因为它使用异步回调来加载文件,这意味着没有返回语句。为了保持简单,我将使flot plot成为全局对象。
首先在$(document).ready()中初始化plot:
var data = [];
flot = $.flot($('#plotdiv'), data, options);

注意:添加一个虚拟数据对象以初始化图表。
然后,添加一个文件处理程序:
// handles csv files
function handleFileSelect(evt) {
  var files = evt.target.files; // FileList object

  // reset the flot dataset
  flot.setData([]);
  for(var i=0, len=files.length; i<len; i++) {
    flotFileData(files[i], i);
  }
}

假设这可以加载一个或多个CSV数据文件。在从文件对话框中选择文件后调用此函数。数据被重置为空(即[]),因为我们希望在每次执行文件对话框后重新开始;否则,您将附加到先前的数据集。
这将循环遍历文件,并为在文件对话框中选择的每个文件调用flotFileData()。
以下是处理文件打开回调的代码:
function flotFileData(file, i) {
  var reader = new FileReader();
  reader.readAsText(file);
  reader.onload = function(event){
    var csv = event.target.result;
    var newData = $.csv.toArrays(csv, {
      onParseValue:$.csv.hooks.castToScalar
    });
    var data = flot.getData();
    data[i] = newData;
    flot.setData(data);
    flot.setupGrid();
    flot.draw();
  };
  reader.onerror = function(){ alert('Unable to read ' + file.fileName); };
}

这将以纯文本形式读取文件,并通过event.target.result使内容可用。 CSV解析器将CSV转换为二维数组形式的标量数据。 要堆叠多个数据集,我们需要附加到已经在图表中的数据,因此我们需要先通过flot.getData()存储现有数据。添加新数据,通过flot.setData()设置它,最后重新绘制图表。

注意:如果不需要重新计算图形的范围,则可以跳过flot.setupGrid()调用。

理想情况下,每次文件加载阶段都应该只发生一次重绘,但是这个演示还没有被优化。也就是说,图形将为每个读取的文件重新绘制(绝对不理想)。

如果您想看到它的实际效果,请查看jquery-csv项目提供的“Flot Demonstration”。我建议您尝试同时加载analytics1.csv和analytics2.csv数据集,以便您可以看到两者如何在图表上叠加。

如果您决定走服务器端路线加载CSV文件,则还有一个更基本的示例,演示了如何从文本区域加载CSV。

声明:我是jquery-csv的作者。

更新:

由于Google Code已关闭,jquery-csv已迁移到GitHub


@ChrisG。谢谢,我很感激。只是尽我所能,让JS生态系统变得更好。 - Evan Plaice

5
使用jQuery CSV插件获取数组。根据需要构建/排序数组以适应图表。 jQuery CSV插件 我突然想到你可能正在考虑使用jQuery读取平面CSV文件。那是不可能的。让JavaScript访问文件系统听起来像是一个可怕的主意。但你可以使用$.get()在服务器上加载文件。

$.get() 将为您获取包含 CSV 数据的字符串。将其传递给 CSV 插件将会给您一个数组。然后,您可以根据需要修改该数组,使其以图表脚本接受的格式呈现。大多数图表脚本都可以接受数组格式的数据,因此这一部分不应该难。 - Chris G.
哦,实际上如果我尝试那样做,我会得到一个“text.split不是函数”的JavaScript错误 - 看起来$.csv期望一个字符串,但从$.get()返回的数据是一个对象。我猜我可以尝试这个:https://dev59.com/DG035IYBdhLWcg3wHsSR 但感觉有点混乱... - Richard
我不会称之为混乱,这就是使用Javascript完成这些工作的方式。http://api.jquery.com/jQuery.get/#jqxhr-object - Chris G.
当然...不,我指的是将对象转换为字符串但仅在某些浏览器中支持的部分。 - Richard
你能发一下你的代码吗?我不确定你是否正确地使用了$.get。 - Chris G.
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接