无法在 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'

我尝试了各种堆栈溢出解决方案,例如使用 readAsBinaryArrayreadAsText 而不是使用 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'});
}