myApp.factory('Excel',function($window){
var uri='data:application/vnd.ms-excel;base64,',
template='<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
base64=function(s){return $window.btoa(unescape(encodeURIComponent(s)));},
format=function(s,c){return s.replace(/{(\w+)}/g,function(m,p){return c[p];})};
return {
tableToExcel:function(tableId,worksheetName){
var table=$(tableId),
ctx={worksheet:worksheetName,table:table.html()},
href=uri+base64(format(template,ctx));
return href;
}
};
})
.controller('MyCtrl',function(Excel,$timeout){
$scope.exportToExcel=function(tableId){ // ex: '#my-table'
$scope.exportHref=Excel.tableToExcel(tableId,'sheet name');
$timeout(function(){location.href=$scope.fileData.exportHref;},100); // trigger download
}
});
How to use:
<button class="btn btn-link" ng-click="exportToExcel('#table1')">
<span class="glyphicon glyphicon-share"></span> Export to Excel
</button>
This work in IE, Edge, FF and Chrome. Test on IE11.309.16299.0, Edge 41.16299.248.0, FF 59.2.3, Chrome 65.0.3325.181. Hope this help.
But it doesn't work in chrome when the file exceed 2Mb. It's very easy to hit 2Mb when the html consists of a lot of html.
// factory MyApp.factory('Excel', ["$window", function ($window) { var uri = 'data:application/vnd.ms-excel;base64,', template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>', base64 = function (s) { return $window.btoa(unescape(encodeURIComponent(s))); }, format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }; return { tableToExcel: function (tableId, worksheetName, isBase64) { var table = document.querySelector(tableId); var ctx = { worksheet: worksheetName, table: table.innerHTML }; var href = ""; if (isBase64) { href = uri + base64(format(template, ctx)); } else { href = uri + format(template, ctx); } return href; } }; }]); // controller MyApp.controller('MyController', ["$scope", "$timeout", "Excel", function ($scope, $timeout, Excel) { $scope.exportToExcel = function (tableId) { var browser = window.navigator.appVersion; var useBlobBuilder = false; // IE, Edge if ((browser.indexOf('Trident') !== -1 && browser.indexOf('rv:11') !== -1) || (browser.indexOf('MSIE 10') !== -1) || (document.documentMode || /Edge/.test(browser))) { useBlobBuilder = true; $scope.exportHref = Excel.tableToExcel(tableId, 'sheet name', false); } else { //FF, Chrome useBlobBuilder = false; $scope.exportHref = Excel.tableToExcel(tableId, 'sheet name', true); } $timeout(function () { var fileName = "testing.xls"; if (useBlobBuilder) { // IE, Edge var builder = new window.MSBlobBuilder(); builder.append($scope.exportHref); var blob = builder.getBlob('data:application/vnd.ms-excel'); window.navigator.msSaveOrOpenBlob(blob, fileName); } else { //FF, Chrome var link = document.createElement('a'); link.download = fileName; link.href = $scope.exportHref; if (document.body != null) { document.body.appendChild(link); } link.click(); link.remove(); } }, 100); } }]);