JavaScript将CSV文件加载到数组中

10

我正在开发一个WordPress网页。该网页需要具有包含所有县的组合框。我有一个以CSV格式存储的数据集,其中包含这些县的约10k行数据。 当用户在下拉菜单中选择一个县时,我希望仅在网页中显示所选县的数据。这是我的要求。

在WordPress中,我正在使用以下方法添加JS文件:

<script type="text/javascript" src="http://xxx/wp     content/uploads/2014/05/countyList1.js"></script>

网页下拉菜单的代码为

<select name="county" id="county" onload="setCounties();" onchange="getSelectedCountyData();"></select>

在 countyList1.js 文件中,我有 setCounties() 和 getSelectedCountyData() 函数。

到目前为止,我可以看到县市列表的下拉菜单。但我不知道如何读取 CSV 文件并将所选县市过滤器应用于此列表。

我尝试了 FileReader 对象,我可以在网页上加载 CSV 内容,但我不希望用户选择 CSV。我已经有数据集了。

我正在尝试使用这个 SO 帖子中的 jquery.csv-0.71 库(如何使用 JavaScript 从 *.CSV 文件中读取数据?),但我需要帮助。

以下是当选择一个县市时调用的代码。

function getSelectedCountyData() {
        cntrySel = document.getElementById('county');
        //selCty = countyList[cntrySel.value];
        handleFiles();
}

function handleFiles() {

    $(document).ready(function () {
        $.ajax({
            type: "GET",
            url: "D:\Docs\Desktop\csvfile.csv",
            dataType: "csv",
            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);
        }
    }
    console.log(lines);
    drawOutput(lines);
}

function drawOutput(lines) {
    //Clear previous data
    document.getElementById("output").innerHTML = "";
    var table = document.createElement("table");
    for (var i = 0; i < lines.length; i++) {
        var row = table.insertRow(-1);
        for (var j = 0; j < lines[i].length; j++) {
            var firstNameCell = row.insertCell(-1);
            firstNameCell.appendChild(document.createTextNode(lines[i][j]));
        }
    }
    document.getElementById("output").appendChild(table);
}

@Teemu 在移除它之后,我得到了一个错误:无法读取未定义的ajax属性。感谢您的帮助。 - Aqua267
5个回答

26
我强烈推荐研究这个插件: http://github.com/evanplaice/jquery-csv/
我在处理大型CSV文件的项目中使用了它,它可以很好地将CSV解析为数组。您还可以使用它来调用您在代码中指定的本地文件,这样您就不必依赖文件上传。
一旦您包含了上面的插件,就可以使用以下方法解析CSV:
$.ajax({
    url: "pathto/filename.csv",
    async: false,
    success: function (csvd) {
        data = $.csv.toArrays(csvd);
    },
    dataType: "text",
    complete: function () {
        // call a function on complete 
    }
});

所有内容都将存在数组data中,供您按需操作。如果您需要,我可以提供更多处理数组数据的示例。

插件页面上有很多很棒的示例可用于执行各种操作。


谢谢提供的链接。我正在尝试像下面这样的东西,但是数据未定义。我以前没有使用过ajax或jquery,所以非常感谢您的帮助。我知道我错过了一些显而易见的东西,但是无法弄清楚: $ .ajax({      url:“https://dl.dropboxusercontent.com/u/25575808/energy/nodes.csv”,      aync:false,      success:function(csvd){          data = $ .csv2Array(csvd);      },      dataType:“text”,      complete:function(){          //完成时调用函数      } }); - Aqua267
明白了,那是个打字错误,应该是async。再次感谢。 - Aqua267
1
我正在尝试这个解决方案,但是出现了“XMLHttpRequest无法加载文件:///Users/adampaciorek/Desktop/names%20Parser/CSV_Database_of_First_Names.csv。跨域请求仅支持协议方案:http,data,chrome,chrome-extension,https,chrome-extension-resource”。有人知道解决方法吗? - Adam P
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - princessjackie
能否使用jquery-csv来处理包含CSV文件的输入元素? - NiallMitch14

4

您不能使用AJAX从用户的计算机中获取文件。这绝对是错误的方法。

请使用FileReader API:

<input type="file" id="file input">

js:

console.log(document.getElementById("file input").files); // list of File objects

var file = document.getElementById("file input").files[0];
var reader = new FileReader();
content = reader.readAsText(file);
console.log(content);

然后将content解析为CSV格式。请注意,您的解析器目前无法处理CSV中的转义值,例如:value1,value2,"value 3","value ""4"""


1
但是用户没有上传CSV文件。我在WordPress中有CSV文件,URL类似于http://xxx/wp-content/uploads/2014/05/csvFile.csv。我如何将此文件传递给FileReader? - Aqua267
只是想澄清一下,我只想在Javascript中完成这个任务。我不熟悉jquery/ajax。 - Aqua267
如果文件已经上传,并且您拥有文件内容,则不再需要FileReaderFileReader是用于在用户计算机上读取文件的包装器。 - Halcyon
1
我有这个文件,但问题是我不知道如何读取它的内容。我是一个新手,如果听起来很蠢请见谅。 - Aqua267

3
如果您不太担心文件的大小,那么您可以将数据存储为JS对象并在另一个文件中导入它,然后在您的HTML文件中同步或异步地使用语法<script src="countries.js" async></script>。这样可以避免您需要导入文件并解析它的麻烦。
然而,我能理解为什么您不想重写10000个条目,因此这里是我编写的基本面向对象的CSV解析器。
function requestCSV(f,c){return new CSVAJAX(f,c);};
function CSVAJAX(filepath,callback)
{
    this.request = new XMLHttpRequest();
    this.request.timeout = 10000;
    this.request.open("GET", filepath, true);
    this.request.parent = this;
    this.callback = callback;
    this.request.onload = function() 
    {
        var d = this.response.split('\n'); /*1st separator*/
        var i = d.length;
        while(i--)
        {
            if(d[i] !== "")
                d[i] = d[i].split(','); /*2nd separator*/
            else
                d.splice(i,1);
        }
        this.parent.response = d;
        if(typeof this.parent.callback !== "undefined")
            this.parent.callback(d);
    };
    this.request.send();
};

这可以像这样使用;

var foo = requestCSV("csvfile.csv",drawlines(lines)); 

第一个参数是文件,相对于此html文件的位置。 第二个参数是可选的回调函数,当文件完全加载时运行。
如果您的文件具有非分隔逗号,则它将无法正常工作,因为它只通过切割换行符和逗号来创建2D数组。 如果需要该功能,您可能需要研究正则表达式。
//THIS works 

"1234","ABCD" \n
"!@£$" \n

//Gives you 
[
 [
  1234,
  'ABCD'
 ],
 [
  '!@£$'
 ]
]

//This DOESN'T!

"12,34","AB,CD" \n
"!@,£$" \n

//Gives you

[
 [
  '"12',
  '34"',
  '"AB',
  'CD'
 ]
 [
  '"!@',
  '£$'
 ]
]

如果您不熟悉面向对象的方法,它们通过“构造函数”创建一个新的对象(如数字、字符串、数组),拥有自己的本地功能和变量。在某些情况下非常方便。该函数可用于同时加载10个具有不同回调的不同文件(取决于您对csv的喜爱程度!)


2

这是我之前用过的一种将csv文件转化为数组的方法。之前尝试了上面的方法没有成功,但是这个方法对我很有效。

$(document).ready(function() {
   "use strict";
    $.ajax({
        type: "GET",
        url: "../files/icd10List.csv",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(icd10Codes) {
    "use strict";
    var input = $.csv.toArrays(icd10Codes);
    $("#test").append(input);
}

使用上面链接的jQuery-CSV插件。

这完美地解决了问题。感谢您分享成功经验。 - Jack

0

原始代码用于读取和分离 csv 文件数据工作正常,但您需要将数据类型从 csv 更改为文本。


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