javascript - Filereader 在读取为 readAsArrayBuffer 时使用正确的编码读取文件

标签 javascript angularjs csv encoding sheetjs

我正在读取使用 javaScript 上传的 .csv/xlsx 文件,并以包含每一行的 array 形式获取结果。我能够使用 FileReaderSheetJs 读取文件并获取数据。使用以下代码。

// code for the new excel reader
$scope.do_file =  function(files)
{
    $scope.fileContent  = [];
    var X = XLSX;
    var global_wb;
    var f = files[0];
    var reader = new FileReader();
    reader.onload = function(e)
    {
        var data = e.target.result;console.log(data);
        global_wb = X.read(data, {type: 'array'});
        var output = "";
        var result = {};
        global_wb.SheetNames.forEach(function(sheetName) {
            var roa = X.utils.sheet_to_json(global_wb.Sheets[sheetName], {header:1});
            if(roa.length) result[sheetName] = roa;
        });
        $scope.fileContent =  result["Sheet1"];
        if(!result["Sheet1"])
        {
            $scope.fileContent =  result["contacts"].filter(function(el) { return typeof el != "object" || Array.isArray(el) || Object.keys(el).length > 0; });
        }
    };
    reader.readAsArrayBuffer(f);
};

对于读取大多数文件,代码可以工作,但是当文件包含使用 Windows-1255 编码的希伯来语文本时,我会得到乱码数据。

enter image description here

寻找更多选项,我尝试使用 reader.readAsText 将文件读取为文本,并根据需要更改编码,请检查以下代码:

function is_Hebrew(data)
{
    var position = data.search(/[\u0590-\u05FF]/);
    return position >= 0;
}

 $scope.do_file =  function(files)
 {
    var fullResult = [];
    var file =files[0];
      var reader = new FileReader();
        reader.onload = function(e){
            var data = e.target.result;
                if(!is_Hebrew(data.toString()))
                {
                  reader.readAsText(file,'ISO-8859-8');   
                }
            };
        reader.readAsText(file);
        reader.onloadend = function(){
            var lines = reader.result.split('\r\n');
            console.log(lines);
            lines.forEach(element => {
                var cell = element.split(',');
                fullResult.push(cell);
            });

             console.log(reader);
        };
    };

但是上面的代码不合适,因为它不会读取文件作为标识每个单元格的每一行。如果任何一个单元格包含带有逗号分隔值的字符串(例如,如果一个单元格包含诸如“25,28,29”之类的字符串值),则数组输出会给出错误的数据,因为它将每个值视为每个单元格。

所以我决定坚持使用第一种方法,但我无法更改编码。有没有可能的方法来更改我使用 readAsArrayBuffer 读取文件的第一个代码中的编码数据?

最佳答案

在经历了很多可能的解决方案之后,我发现上述问题的答案是将上述两种方法结合起来。第一种方法用于读取 xlsx 文件,第二种方法用于读取 csv 文件。我还使用了一个名为 papaparse 的附加 javaScript 库。第二种方法中解决读取每个cell中数据的问题

$scope.is_Hebrew = function($data){
var position = $data.search(/[\u0590-\u05FF]/);
return position >= 0;
}

// code for the new excel reader
$scope.do_file =  function(files)
{
    var config = {
    delimiter: "",  // auto-detect
    newline: "",    // auto-detect
    quoteChar: '"',
    escapeChar: '"',
    header: false,
    trimHeader: false,
    dynamicTyping: false,
    preview: 0,
    encoding: "",
    worker: false,
    comments: false,
    step: undefined,
    complete: undefined,
    error: undefined,
    download: false,
    skipEmptyLines: false,
    chunk: undefined,
    fastMode: undefined,
    beforeFirstChunk: undefined,
    withCredentials: undefined
    };

    $scope.fileContent  = [];
    var f = files[0];
    var fileExtension = f.name.replace(/^.*\./, '');
    if(fileExtension == 'xlsx')
    {
        var X = XLSX;
        var global_wb;
        var reader = new FileReader();
        reader.onload = function(e)
        {
            var data = e.target.result;
            global_wb = X.read(data, {type: 'array'});
            var result = {};
            global_wb.SheetNames.forEach(function(sheetName) {
               var roa = X.utils.sheet_to_json(global_wb.Sheets[sheetName], {header:1});
               if(roa.length) result[sheetName] = roa;
            });
            $scope.fileContent =  result["Sheet1"];
            if(!result["Sheet1"])
            {
               $scope.fileContent =  result["contacts"].filter(function(el) { return typeof el != "object" || Array.isArray(el) || Object.keys(el).length > 0; });
            }

        };
        reader.readAsArrayBuffer(f);

    }
    else if(fileExtension == 'csv')
    {
    var reader = new FileReader();
    reader.onload = function(e)
    {
        var data = e.target.result;
        console.log(f);
        console.log($scope.is_Hebrew(data.toString()));
        if(!$scope.is_Hebrew(data.toString()))
        {
           reader.readAsText(f,'ISO-8859-8');   
        }
    };

    reader.readAsText(f);
    reader.onloadend = function(e){
        var c =  Papa.parse(reader.result,[ config])
        console.log(c);
        $scope.fileContent =  c["data"].filter(function(el) { return typeof el != "object" || Array.isArray(el) || Object.keys(el).length > 0; });

    };

    }
    else
    {
       alert("File Not supported!");
    }

$scope.fileContent.push([]);
};

关于javascript - Filereader 在读取为 readAsArrayBuffer 时使用正确的编码读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50385028/

相关文章:

java - Selenium 网络驱动程序 : JavascriptExecutor to push play on video

javascript - Contenteditable 在子节点上设置插入符号

angularjs - 如何将 ng-animate 与 ui-view 而不是 ng-view 一起使用?

python - 过滤具有整数列表的python输出

javascript - 荷兰语 ok 中的表单 Submit.button 出现奇怪的错误,但英语不起作用

javascript - 从javascript中的匿名函数访问类成员

javascript - AngularJS 将变量传递到循环异步回调中

javascript - 单击时 ionic 显示全屏图像

python - CSV 到嵌套(分层)JSON - 使用 Python 标记父项

python - 如何从嵌套的 csv 文件中删除子列?