无法在 IE11 中使用 SheetJS 在 AngularJS UI 网格中上传 excel
Unable to upload excel in AngularJS UI Grid using SheetJS in IE11
我正在尝试使用 SheetJS 在 AngularJS UI 网格中的客户端上传一个 excel 文件。该代码在 Chrome 和 Firefox 中运行良好,但在 IE 上它给出以下错误 Object doesn't support 属性 or method 'readAsBinaryString'
我尝试了各种堆栈溢出解决方案,例如使用 readAsBinaryArray 或 readAsText 而不是使用 readAsBinaryString,但我无法解决我的问题。
我在下面分享我的代码,它包含 3 个文件:index.html、app.js 和 main.css
index.html的代码如下
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">
<link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/xlsx.full.min.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/ods.js"></script>
<script src="https://github.com/SheetJS/js-xlsx/blob/master/shim.js"></script>
<script src="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.js"></script>
<link rel="stylesheet" href="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.css" />
<link rel="stylesheet" href="css/main.css" type="text/css" />
</head>
<body>
<div ng-controller="MainCtrl as vm">
<div id="grid1" ui-grid="vm.gridOptions" class="grid">
<div class="grid-msg-overlay" ng-show="!vm.gridOptions.data.length">
<div class="msg">
<div class="center">
<span class="muted">Select Excel File</span>
<br />
<input ng-attr-type="{{'file'}}" accept=".xls,.xlsx,.csv" fileread="" opts="vm.gridOptions" multiple="false" />
</div>
</div>
</div>
</div>
<br />
<br />
<button type="button" class="btn btn-success" ng- click="vm.reset()">Reset Grid</button>
<span> </span>
<button type="button" class="btn btn-success" ng-click="">Save</button>
</div>
<script src="js/app.js"></script>
</body>
</html>
app.js的代码如下
(function (angular) {
"use strict";
angular.module('app', ['ui.grid']).controller('MainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.gridOptions = {};
vm.reset = reset;
function reset() {
vm.gridOptions.data = [];
vm.gridOptions.columnDefs = [];
}
}])
.directive("fileread", [function () {
return {
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function () {
var data = evt.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
var headerNames = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]], { header: 1 })[0];
var data = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);
$scope.opts.columnDefs = [];
headerNames.forEach(function (h) {
$scope.opts.columnDefs.push({ field: h });
});
$scope.opts.data = data;
$elm.val(null);
});
};
reader.readAsBinaryString(changeEvent.target.files[0]);
});
}
}
}]);
代码 main.css
body {
padding: 20px;
}
.grid {
width: 100%;
height: 250px;
}
.grid-msg-overlay {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.4);
}
.grid-msg-overlay .msg {
opacity: 1;
position: absolute;
top: 20%;
left: 20%;
width: 60%;
height: 50%;
background-color: #eee;
border-radius: 4px;
border: 1px solid #555;
text-align: center;
font-size: 24px;
display: table;
}
.grid-msg-overlay .msg > .center {
display: table-cell;
vertical-align: middle;
}
.grid input[type="file"] {
font-size: 14px;
display: inline-block;
}
请有人帮助我了解如何解决此问题
IE 没有实现 FileReader 的 readAsBinaryString() 方法。但是,根据 SheetJS 文档,您可以测试支持,然后回退到 readAsArrayBuffer()。
var readAsBinary = "readAsBinaryString" in FileReader;
if (readAsBinary) {
reader.readAsBinaryString(changeEvent.target.files[0]);
} else {
reader.readAsArrayBuffer(changeEvent.target.files[0]);
}
然后在卸载方法中你必须处理结果如下:
var workbook;
if (readAsBinary) {
workbook = XLSX.read(data, {type: 'binary'});
} else {
function fixdata(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
workbook = XLSX.read(btoa(fixdata(data)), {type: 'base64'});
}
我正在尝试使用 SheetJS 在 AngularJS UI 网格中的客户端上传一个 excel 文件。该代码在 Chrome 和 Firefox 中运行良好,但在 IE 上它给出以下错误 Object doesn't support 属性 or method 'readAsBinaryString'
我尝试了各种堆栈溢出解决方案,例如使用 readAsBinaryArray 或 readAsText 而不是使用 readAsBinaryString,但我无法解决我的问题。
我在下面分享我的代码,它包含 3 个文件:index.html、app.js 和 main.css
index.html的代码如下
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">
<link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/xlsx.full.min.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/ods.js"></script>
<script src="https://github.com/SheetJS/js-xlsx/blob/master/shim.js"></script>
<script src="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.js"></script>
<link rel="stylesheet" href="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.css" />
<link rel="stylesheet" href="css/main.css" type="text/css" />
</head>
<body>
<div ng-controller="MainCtrl as vm">
<div id="grid1" ui-grid="vm.gridOptions" class="grid">
<div class="grid-msg-overlay" ng-show="!vm.gridOptions.data.length">
<div class="msg">
<div class="center">
<span class="muted">Select Excel File</span>
<br />
<input ng-attr-type="{{'file'}}" accept=".xls,.xlsx,.csv" fileread="" opts="vm.gridOptions" multiple="false" />
</div>
</div>
</div>
</div>
<br />
<br />
<button type="button" class="btn btn-success" ng- click="vm.reset()">Reset Grid</button>
<span> </span>
<button type="button" class="btn btn-success" ng-click="">Save</button>
</div>
<script src="js/app.js"></script>
</body>
</html>
app.js的代码如下
(function (angular) {
"use strict";
angular.module('app', ['ui.grid']).controller('MainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.gridOptions = {};
vm.reset = reset;
function reset() {
vm.gridOptions.data = [];
vm.gridOptions.columnDefs = [];
}
}])
.directive("fileread", [function () {
return {
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function () {
var data = evt.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
var headerNames = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]], { header: 1 })[0];
var data = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);
$scope.opts.columnDefs = [];
headerNames.forEach(function (h) {
$scope.opts.columnDefs.push({ field: h });
});
$scope.opts.data = data;
$elm.val(null);
});
};
reader.readAsBinaryString(changeEvent.target.files[0]);
});
}
}
}]);
代码 main.css
body {
padding: 20px;
}
.grid {
width: 100%;
height: 250px;
}
.grid-msg-overlay {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.4);
}
.grid-msg-overlay .msg {
opacity: 1;
position: absolute;
top: 20%;
left: 20%;
width: 60%;
height: 50%;
background-color: #eee;
border-radius: 4px;
border: 1px solid #555;
text-align: center;
font-size: 24px;
display: table;
}
.grid-msg-overlay .msg > .center {
display: table-cell;
vertical-align: middle;
}
.grid input[type="file"] {
font-size: 14px;
display: inline-block;
}
请有人帮助我了解如何解决此问题
IE 没有实现 FileReader 的 readAsBinaryString() 方法。但是,根据 SheetJS 文档,您可以测试支持,然后回退到 readAsArrayBuffer()。
var readAsBinary = "readAsBinaryString" in FileReader;
if (readAsBinary) {
reader.readAsBinaryString(changeEvent.target.files[0]);
} else {
reader.readAsArrayBuffer(changeEvent.target.files[0]);
}
然后在卸载方法中你必须处理结果如下:
var workbook;
if (readAsBinary) {
workbook = XLSX.read(data, {type: 'binary'});
} else {
function fixdata(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
workbook = XLSX.read(btoa(fixdata(data)), {type: 'base64'});
}