Uncaught TypeError: jszip is not a constructor: How to write inline images to excel with JavaScript within AngularJs

Uncaught TypeError: jszip is not a constructor: How to write inline images to excel with JavaScript within AngularJs

以下方法有效:

https://jsfiddle.net/coolcatDev/Lhzdo2qp/

但是一旦放置在 Angular 环境中,我就会收到以下错误:

http://jsfiddle.net/coolcatDev/ADukg/17027/

我正在使用以下库:

https://code.angularjs.org/angular-1.0.1.js

https://rawgit.com/xSirrioNx/js-xlsx/master/xlsx.js

https://rawgit.com/SheetJS/js-xlsx/master/shim.js

https://rawgit.com/SheetJS/js-xlsx/master/dist/cpexcel.js

https://rawgit.com/xSirrioNx/js-xlsx/master/jszip.js

https://rawgit.com/eligrey/FileSaver.js/master/FileSaver.js

失败代码:控制器:

    var myApp = angular.module('myApp',[]);

    myApp.controller('MyCtrl',  ['$scope',
     function ($scope) {
        $("#exportxlsx").click(exportToExcel);
        function Workbook() {
           if (!(this instanceof Workbook)) return new Workbook();
           this.SheetNames = [];
           this.Sheets = {};
        }
        function imgToDataUrl(img){
          var canvas = document.createElement('canvas');
          canvas.width = img.naturalWidth; // or 'width' if you want a special/scaled size
          canvas.height = img.naturalHeight; // or 'height' if you want a special/scaled size

          canvas.getContext('2d').drawImage(img, 0, 0);
          return canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '');
        }

        function exportToExcel() {
          var wbout = XLSX.write(wb, {bookType:"xlsx", bookSST:true, type: 'binary'});
          var fname = 'test.xlsx';
          try {
            saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), fname);
          } catch(e) { if(typeof console != 'undefined') console.log(e, wbout); }
          return wbout;
        }

        function s2ab(s) {
          if(typeof ArrayBuffer !== 'undefined') {
            var buf = new ArrayBuffer(s.length);

            var view = new Uint8Array(buf);
            for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;

            return buf;
          } else {
            var buf = new Array(s.length);
            for (var i=0; i!=s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
            return buf;
          }
        }
        var images = [];
        var wb = new Workbook();
        var ws_name = "SheetJS";
        wb.SheetNames.push(ws_name);
        var ws = {};
        var rows = $("#table tr");
        var rowsCount = rows.length;
        var colsCount = $(rows[0]).find("td").length;
        var range = {s: {c: 0, r: 0}, e: {c: colsCount - 1, r: rowsCount - 1}};
        ws['!ref'] = XLSX.utils.encode_range(range);

        $.each(rows, function(rowIndex, row){
          var cols = $(row).find("td");
          $.each(cols, function(colIndex, col){
            var cell_ref = XLSX.utils.encode_cell({c: colIndex, r: rowIndex});
            var excelCell = {
              v: $(col).text(),
              t: "s",
              s: {
                fill: {
                  patternType: "none",
                  fgColor: {rgb: "FF000000"},
                  bgColor: {rgb: "FFFFFFFF"}
                },
                font: {
                  name: 'Times New Roman',
                  sz: 16,
                  color: {rgb: "#FF000000"},
                  bold: false,
                  italic: false,
                  underline: false
                },
                border: {
                  top: {style: "thin", color: {auto: 1}},
                  right: {style: "thin", color: {auto: 1}},
                  bottom: {style: "thin", color: {auto: 1}},
                  left: {style: "thin", color: {auto: 1}}
                }
              }
            };

            if(rowIndex == 0){
              excelCell.s.font.bold = true;
              excelCell.s.fill.patternType = "solid";
              excelCell.s.fill.fgColor = {
                rgb: "FFFF0000"
              };
              excelCell.s.fill.bgColor = {
                rgb: "FFFF0000"
              };
            }

            if($(col).find("img").length > 0){
              images.push({
                c: colIndex,
                r: rowIndex,
                element: $(col).find("img")
              })
            }
            ws[cell_ref] = excelCell;
          })
        });
        ws["!images"] = [];
        $.each(images, function(index, image){
          ws["!images"].push({
            name: 'image' + index + '.png',
            data: imgToDataUrl(image.element[0]),
            opts: {base64: true},
            type: "png",
            position: {
              type: 'twoCellAnchor',
              attrs: {editAs: 'oneCell'},
              from: {col: image.c, row: image.r},
              to: {col: image.c + 1, row: image.r + 1}
            }
          });
        });
        wb.Sheets[ws_name] = ws;
    }]);

模板代码:

<div ng-controller="MyCtrl">
  <table id="table" border="1">
    <tr>
      <td contenteditable="true">
        <img crossOrigin="Anonymous" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAOkSURBVHjaYvz//z8DNQFAALGAiAhHTnRxkIAuEPsAsSsQa0DFbwDxbiDeAsSXgfg7sqYV+78zAAQQCxZLZIA4V0KEpczekptBQ5WDQU6KjeH/3/8MDx/+tLh+87vFoXPfa1+9/9sFVDcZiJ8gawYIIEaQl6EuZARifSBe4m7Pqx0aLMjAwcHMwMgMkvoPNJCB4d+ffwx/v/1j+Pb+N8PabR8Z9p3/cRUoGQPEF0GKQC4ECCBkF6qysDDuzE8WETM05mFgYgfawMzIwMjICDKPAWQx019GBiagGDfQkghffgZ1GVbt2Vs/bwfaYw/UfwtkCEAAMUEN4wbiijAffjFDE24GZg6QRiYG14BnMH8wMAJVuoU8Z2BmZ2Jg4WJmYOVjZtDX4mDwMeGQAKooBWIukFKAAIIZqC8jzpLo5szHwMQKdBUTI9gQMAClgv8MEAwyG6gDpAZsMDcTg6MxJ4M4H1MKUEoPJA8QQDAD/WzNuRlY2BnhYcYAT03/oYb+R3It0PssQF+wMjGwcjAxmCuDQ84XRAAEEMxAVz1NDnB4MYLjBsmA/wwYfLA6RohrQVhTCmygM4gACCBYpCiJCDGhugSoc886CSQ+A8OeteKoQfAfwuDnAjmCQRFEAAQQEzz5/AFK/fvH4BL0HKEJHob/kQz6D1YHwr45Hxj+/wEK/kNYChBAMAPvv3n1m+Hfb6jEP0xDYK5h+McANuTfr39gpX9//GN49xHMfggiAAIIZuDuS1d/ABPtX4Ydi0QYXEJeIgxlQDL0HyiB/2P49/Mfg1fqe4Y1DZwMf7//Zbj57A/IjL0gAiCAYAZuBGYnhp8ffzP8+fKHYcdCYQaX0FdgzTCDQVkP5IO/P/4yeCS+Y1jXys3w+9Nfhl+f/zKcfvQXZMZmEAEQQLBIufDs3d8Few9/TXC15QJr3jZbkME1/A3WEmVdCzfDL2D2+/3hD8Ph678YXnz5Px+a/RgAAghm4Fcg7lh/9Lu3CA+jKCgHsHAxMWzq54UkcpCPgS4FefXP178MP9/8Arvuyr3fDNtv/X0F0gs1gwEggJDz8i1gnnSbvv3bEoeHv7X9LDgZOIA5gZEFGox/Qd79Dw6z70DDtl38zXD44V9Y4XAbZghAACEbCAr6C0DsceDa79yrj/6UWQJzgKoEM4O0IBPYwCev/zLcfvGX4cSjfwxvvv3HWnwBBBBy8YWtgAVlJzcg1oSKXwfiXdAIwFrAAgQQI7WrAIAAAwC3CoKwmoAzCQAAAABJRU5ErkJggg==">
      </td>
    </tr>
  </table>
  <p id="exportxlsx" class="xport"><input type="submit" value="Export to XLSX!"></p>
</div>

如果我用 https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.11.14/xlsx.core.min.js 替换 https://rawgit.com/xSirrioNx/js-xlsx/master/xlsx.js 没有错误抛出,文件已下载但没有图像:

http://jsfiddle.net/coolcatDev/ADukg/17028/

请注意 console.log(wb) AngularJS 示例中缺少 Sheets->SheetJS->!rels

工作示例: Angular 失败示例:

正在使用来自不同 CDN 的 xlsx.jsshim.js,并且彼此不兼容...

工作解决方案: http://jsfiddle.net/coolcatDev/ADukg/17052/