diff --git a/demos/angular/README.md b/demos/angular/README.md new file mode 100644 index 0000000..fea219f --- /dev/null +++ b/demos/angular/README.md @@ -0,0 +1,32 @@ +# Angular 1 + +The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped +into web pages with script tags e.g. + +```html + +``` + +Strictly speaking, there should be no need for an angular demo! You can proceed +as you would with any other browser-friendly library. To make this meaningful, +we chose to show an integration with a common angular table component. + +This demo uses angular-ui-grid to display a data table. The ui-grid does not +provide any way to hook into the import button, so the demo includes a simple +directive for a HTML File Input control. It also includes a sample service for +export which adds an item to the export menu. + +## Import Directive + +`SheetJSImportDirective` follows the prescription from the README for File input +controls using `readAsBinaryString`, converting to a suitable representation +and updating the scope. + +## Export Service + +`SheetJSExportService` exposes export functions for `XLSB` and `XLSX`. Other +formats are easily supported by changing the `bookType` variable. It grabs +values from the grid, builds an array of arrays, generates a workbook and uses +FileSaver to generate a download. By setting the `filename` and `sheetname` +options in the ui-grid options, the output can be controlled. + diff --git a/demos/angular/SheetJS-angular.js b/demos/angular/SheetJS-angular.js new file mode 100644 index 0000000..d97a780 --- /dev/null +++ b/demos/angular/SheetJS-angular.js @@ -0,0 +1,107 @@ +/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ +function SheetJSExportService(uiGridExporterService) { + + function exportSheetJS(gridApi, wopts) { + var columns = uiGridExporterService.getColumnHeaders(gridApi.grid, 'all'); + var data = uiGridExporterService.getData(gridApi.grid, 'all', 'all'); + + var fileName = gridApi.grid.options.filename || 'SheetJS'; + fileName += wopts.bookType ? "." + wopts.bookType : '.xlsx'; + + var sheetName = gridApi.grid.options.sheetname || 'Sheet1'; + + var wb = XLSX.utils.book_new(), ws = uigrid_to_sheet(data, columns); + XLSX.utils.book_append_sheet(wb, ws, sheetName); + var wbout = XLSX.write(wb, wopts); + saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), fileName); + } + + var service = {}; + service.exportXLSB = function exportXLSB(gridApi) { return exportSheetJS(gridApi, { bookType: 'xlsb', bookSST: true, type: 'binary' }); }; + service.exportXLSX = function exportXLSX(gridApi) { return exportSheetJS(gridApi, { bookType: 'xlsx', bookSST: true, type: 'binary' }); } + + return service; + + /* utilities */ + function uigrid_to_sheet(data, columns) { + var o = [], oo = [], i = 0, j = 0; + + /* column headers */ + for(j = 0; j < columns.length; ++j) oo.push(get_value(columns[j])); + o.push(oo); + + /* table data */ + for(i = 0; i < data.length; ++i) { + oo = []; + for(j = 0; j < data[i].length; ++j) oo.push(get_value(data[i][j])); + o.push(oo); + } + /* aoa_to_sheet converts an array of arrays into a worksheet object */ + return XLSX.utils.aoa_to_sheet(o); + } + + function get_value(col) { + if(!col) return col; + if(col.value) return col.value; + if(col.displayName) return col.displayName; + if(col.name) return col.name; + return null; + } + + 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 SheetJSImportDirective = function() { + return { + scope: { opts: '=' }, + link: function ($scope, $elm, $attrs) { + $elm.on('change', function (changeEvent) { + var reader = new FileReader(); + + reader.onload = function (e) { + /* read workbook */ + var bstr = e.target.result; + var wb = XLSX.read(bstr, {type:'binary'}); + + /* grab first sheet */ + var wsname = wb.SheetNames[0]; + var ws = wb.Sheets[wsname]; + + /* grab first row and generate column headers */ + var aoa = XLSX.utils.sheet_to_json(ws, {header:1, raw:false}); + var cols = []; + for(var i = 0; i < aoa[0].length; ++i) cols[i] = { field: aoa[0][i] }; + + /* generate rest of the data */ + var data = []; + for(var r = 1; r < aoa.length; ++r) { + data[r-1] = {}; + for(i = 0; i < aoa[r].length; ++i) { + if(aoa[r][i] == null) continue; + data[r-1][aoa[0][i]] = aoa[r][i] + } + } + + /* update scope */ + $scope.$apply(function() { + $scope.opts.columnDefs = cols; + $scope.opts.data = data; + }); + }; + + reader.readAsBinaryString(changeEvent.target.files[0]); + }); + } + } +} diff --git a/demos/angular/angular.html b/demos/angular/angular.html deleted file mode 100644 index f0dada7..0000000 --- a/demos/angular/angular.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Angular Js XLS - - -
- -
- - - - - - - - diff --git a/demos/angular/app.js b/demos/angular/app.js new file mode 100644 index 0000000..2beeadd --- /dev/null +++ b/demos/angular/app.js @@ -0,0 +1,43 @@ +/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ +var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.exporter']); + +/* Inject SheetJSExportService */ +app.factory('SheetJSExportService', SheetJSExportService); +SheetJSExportService.inject = ['uiGridExporterService']; + +app.controller('MainCtrl', ['$scope', '$http','SheetJSExportService', function ($scope, $http, SheetJSExportService) { + $scope.gridOptions = { + columnDefs: [ + { field: 'name' }, + { field: 'gender', visible: false}, + { field: 'company' } + ], + enableGridMenu: true, + enableSelectAll: true, + exporterMenuPdf: false, + exporterMenuCsv: false, + showHeader: true, + onRegisterApi: function(gridApi){ + $scope.gridApi = gridApi; + }, + /* SheetJS Service setup */ + filename: "SheetJSAngular", + sheetname: "ng-SheetJS", + gridMenuCustomItems: [ + { + title: 'Export all data as XLSX', + action: function ($event) { SheetJSExportService.exportXLSX($scope.gridApi); }, + order: 200 + }, + { + title: 'Export all data as XLSB', + action: function ($event) { SheetJSExportService.exportXLSB($scope.gridApi); }, + order: 201 + } + ] + }; + + $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json').success(function(data) { $scope.gridOptions.data = data; }); + +}]); +app.directive("importSheetJs", [SheetJSImportDirective]);