24

我需要阅读用户提供的一些 csv 文件。使用拖放 div 将文件传递到页面/脚本,该 div 处理文件拖放如下:

function handleFileDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files; // FileList object.
    ...
}

我需要使用将其转换为数组的 csv 库来解析每个文件,但我还需要跟踪我当前正在解析的文件名。这是我用来解析每个文件的代码:

for(var x = 0; x < files.length; x++){
    var currFile = files[x];
    var fileName = currFile.name;
    var reader = new FileReader();
    reader.onload = (function(theFile){
        return function(e){
            var csvArr = CSV.csvToArray( e.target.result, ";", true );
            console.log(csvArr); 
        };
    })(currFile);   
    reader.readAsText(currFile);
}

在此之前,一切正常。我还需要将文件名传递给reader.onload事件,例如:

reader.onload = (function(theFile){
    return function(e){

       ***** I need to have fileName value HERE *****

    };
})(currFile); 

有可能吗?我怎样才能做到这一点?提前感谢您的帮助,最好的问候

4

2 回答 2

54

尝试以下操作:

var reader = new FileReader();
reader.onload = (function(theFile){
    var fileName = theFile.name;
    return function(e){
        console.log(fileName);
        console.log(e.target.result);
    };
})(currFile);   
reader.readAsText(currFile);

fileName在这里,每次将文件传递给外部方法时,您都会创建一个新变量。然后,您将创建一个可以访问该变量的函数(由于闭包)并返回它。

于 2013-06-05T10:23:54.750 回答
1

使用 Blob API

使用新的 File / Blob API可以更轻松地完成。

您的第二个代码块 - 也解决了您的问题 - 可以重写为:

for (let file of files){
 (new Blob([file])).text().then(x=>console.log(file.name,x));
}

Blob API 使用 Promises 而不是像 Filereader API 这样的事件,因此闭包的麻烦要少得多。此外,箭头函数 (x=>)for of 的迭代 器使代码更加简洁。

检查支持

使用获取 API

同样使用Fetch API Response Object可以更容易地完成。

for (let file of files){
 (new Response(file)).text().then(x=>console.log(file.name,x));
}

注意构造函数中的缺失Array []

还要检查支持

于 2019-11-25T11:54:49.887 回答