使用FileReader readAsArrayBuffer读取文件时如何设置正确编码?
解决SheetJS读取Windows-1255编码希伯来文CSV文件乱码问题(保留
readAsArrayBuffer方案) 你的核心需求很明确——既要保留SheetJS+readAsArrayBuffer的可靠解析(避免手动拆分逗号导致的单元格错误),又要解决Windows-1255编码希伯来文的乱码问题。其实问题出在CSV文件的编码上:SheetJS默认会把ArrayBuffer形式的CSV按UTF-8解码,而你的文件是Windows-1255编码,所以才会乱码。XLSX文件本身是二进制容器,内部用UTF-8存储,所以不需要额外处理,只需要针对CSV文件做编码转换即可。
下面是修改后的完整代码,我会一步步解释关键改动:
$scope.do_file = function(files) { $scope.fileContent = []; const X = XLSX; let global_wb; const f = files[0]; const reader = new FileReader(); reader.onload = function(e) { const data = e.target.result; let workbook; // 判断文件类型,区分CSV和XLSX const fileExtension = f.name.split('.').pop().toLowerCase(); if (fileExtension === 'csv') { // 针对Windows-1255编码的CSV,先将ArrayBuffer转成对应编码的文本 const decoder = new TextDecoder('windows-1255'); const csvText = decoder.decode(data); // 用SheetJS解析文本形式的CSV,指定type为'string' workbook = X.read(csvText, { type: 'string' }); } else { // XLSX文件直接用原逻辑解析ArrayBuffer workbook = X.read(data, { type: 'array' }); } const result = {}; workbook.SheetNames.forEach(function(sheetName) { const roa = X.utils.sheet_to_json(workbook.Sheets[sheetName], { header: 1 }); if (roa.length) result[sheetName] = roa; }); // 取第一个工作表的数据(兼容你的原逻辑) $scope.fileContent = result[workbook.SheetNames[0]] || []; // 触发AngularJS的脏检查,确保视图更新 $scope.$apply(); }; reader.readAsArrayBuffer(f); };
关键改动说明:
- 文件类型判断:通过文件名后缀区分CSV和XLSX,只对CSV做编码处理,XLSX保持原逻辑不变。
- ArrayBuffer转Windows-1255文本:使用浏览器原生的
TextDecoderAPI,传入'windows-1255'编码参数,把ArrayBuffer解码成正确的希伯来文字符串。 - SheetJS解析文本CSV:把解码后的CSV字符串传给
X.read,指定type: 'string',这样SheetJS会正确解析CSV结构,不会出现手动拆分逗号的错误。 - AngularJS视图更新:添加
$scope.$apply()确保数据更新后视图能同步刷新(原代码可能因为异步操作导致视图不更新)。
兼容性说明:
TextDecoder是ES6+的API,现代浏览器(Chrome、Firefox、Edge等)都支持。如果需要兼容非常旧的浏览器,可以引入第三方编码转换库(如iconv-lite),但需要注意在浏览器环境中使用的话可能需要打包工具处理。
这样修改后,既保留了SheetJS对CSV结构的可靠解析,又解决了Windows-1255编码的乱码问题,完美符合你的需求。
内容的提问来源于stack exchange,提问作者Joel Joseph
相关产品推荐
相关产品推荐

