| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: AngularJS | 
					
						
							|  |  |  | pagination_prev: demos/index | 
					
						
							|  |  |  | pagination_next: demos/grid/index | 
					
						
							|  |  |  | sidebar_position: 7 | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | import current from '/version.js'; | 
					
						
							|  |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | :::warning | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo is for the legacy AngularJS framework (version 1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "Angular" now commonly refers to the new framework starting with version 2. | 
					
						
							|  |  |  | [The "Angular" demo](/docs/demos/frontend/angular) covers the new framework. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-18 20:39:12 +00:00
										 |  |  | [AngularJS](https://angularjs.org/) is a JS library for building user interfaces. | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Demo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo was last run on 2023 April 08 using AngularJS `1.5.0` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [Click here for a live standalone integration demo.](pathname:///angularjs/) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The demo uses an array of objects as its internal state. It fetches and displays | 
					
						
							|  |  |  | data on load. It also includes a button for exporting data to file and a file | 
					
						
							|  |  |  | input element for loading user-submitted files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Installation
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [Standalone scripts](/docs/getting-started/installation/standalone) can be | 
					
						
							|  |  |  | referenced in a `SCRIPT` tag from the HTML entrypoint page. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `$http` service can request binary data using `"arraybuffer"` response type. | 
					
						
							|  |  |  | This maps to the `"array"` input format for `XLSX.read`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | app.controller('sheetjs', function($scope, $http) { | 
					
						
							|  |  |  |   $http({ | 
					
						
							|  |  |  |     method:'GET', url:'https://sheetjs.com/pres.xlsx', | 
					
						
							|  |  |  |     // highlight-next-line | 
					
						
							|  |  |  |     responseType:'arraybuffer' | 
					
						
							|  |  |  |   }).then(function(data) { | 
					
						
							|  |  |  |     // highlight-next-line | 
					
						
							|  |  |  |     var wb = XLSX.read(data.data, {type:"array"}); | 
					
						
							|  |  |  |     /* DO SOMETHING WITH wb HERE */ | 
					
						
							|  |  |  |     $scope.data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |   }, function(err) { console.log(err); }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details><summary><b>Parsing User-Submitted Files</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For file input elements, a general import directive is fairly straightforward: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Add an `INPUT` element with attribute `import-sheet-js=""`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <input type="file" import-sheet-js="" multiple="false"  /> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) Define the `SheetJSImportDirective` directive function: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function SheetJSImportDirective() { return { | 
					
						
							|  |  |  |   scope: false, | 
					
						
							|  |  |  |   link: function ($scope, $elm) { | 
					
						
							|  |  |  |     $elm.on('change', function (changeEvent) { | 
					
						
							|  |  |  |       var reader = new FileReader(); | 
					
						
							|  |  |  |       reader.onload = function (e) { | 
					
						
							|  |  |  |         var wb = XLSX.read(e.target.result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* DO SOMETHING WITH wb HERE */ | 
					
						
							|  |  |  |         $scope.apply(function() { | 
					
						
							|  |  |  |           $scope.data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       reader.readAsArrayBuffer(changeEvent.target.files[0]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Define the `importSheetJs` directive in the app: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | app.directive("importSheetJs", [SheetJSImportDirective]); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Internal State
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The various SheetJS APIs work with various data shapes.  The preferred state | 
					
						
							|  |  |  | depends on the application. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Array of Objects
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Typically, some users will create a spreadsheet with source data that should be | 
					
						
							|  |  |  | loaded into the site.  This sheet will have known columns.  For example, our | 
					
						
							|  |  |  | [presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This naturally maps to an array of typed objects, as in the example below: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | app.controller('sheetjs', function($scope, $http) { | 
					
						
							|  |  |  |   $http({ method:'GET', url:'https://sheetjs.com/pres.xlsx', responseType:'arraybuffer' }).then(function(data) { | 
					
						
							|  |  |  |     var wb = XLSX.read(data.data, {type:"array"}); | 
					
						
							|  |  |  |     // highlight-next-line | 
					
						
							|  |  |  |     $scope.data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |   }, function(err) { console.log(err); }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `data` will be an array of objects: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | [ | 
					
						
							|  |  |  |   { Name: "Bill Clinton", Index: 42 }, | 
					
						
							|  |  |  |   { Name: "GeorgeW Bush", Index: 43 }, | 
					
						
							|  |  |  |   { Name: "Barack Obama", Index: 44 }, | 
					
						
							|  |  |  |   { Name: "Donald Trump", Index: 45 }, | 
					
						
							|  |  |  |   { Name: "Joseph Biden", Index: 46 } | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A component will typically loop over the data using `ng-repeat`. The following | 
					
						
							|  |  |  | template generates a TABLE with a row for each President: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <table id="sjs-table"> | 
					
						
							|  |  |  |   <tr><th>Name</th><th>Index</th></tr> | 
					
						
							|  |  |  |   <tr ng-repeat="row in data track by $index"> | 
					
						
							|  |  |  |     <td>{{row.Name}}</td> | 
					
						
							|  |  |  |     <td>{{row.Index}}</td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							|  |  |  | </table> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `XLSX.utils.json_to_sheet` can generate a worksheet from the data: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* assuming $scope.data is an array of objects */ | 
					
						
							|  |  |  | $scope.exportSheetJS = function() { | 
					
						
							|  |  |  |   /* generate a worksheet */ | 
					
						
							|  |  |  |   var ws = XLSX.utils.json_to_sheet($scope.data); | 
					
						
							|  |  |  |   /* add to workbook */ | 
					
						
							|  |  |  |   var wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |   XLSX.utils.book_append_sheet(wb, ws, "Presidents"); | 
					
						
							|  |  |  |   /* write workbook and force a download */ | 
					
						
							|  |  |  |   XLSX.writeFile(wb, "SheetJSAngularJSAoO.xlsx"); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details><summary><b>Complete Example</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Save the following to `index.html`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | <CodeBlock language="html" title="index.html">{`\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <!DOCTYPE html> | 
					
						
							|  |  |  | <html ng-app="s5s"> | 
					
						
							|  |  |  | <head> | 
					
						
							|  |  |  |   <title>SheetJS + AngularJS</title> | 
					
						
							|  |  |  |   <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  |   <script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js"></script> | 
					
						
							|  |  |  |   <script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script> | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | </head> | 
					
						
							|  |  |  | <body> | 
					
						
							|  |  |  | <h3><a href="https://sheetjs.com">SheetJS + AngularJS demo</a></h3> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <div ng-controller="sheetjs"> | 
					
						
							|  |  |  |   <button ng-click="exportSheetJS()">Export Table</button> | 
					
						
							|  |  |  |   <table id="s5s-table"> | 
					
						
							|  |  |  |     <tr><th>Name</th><th>Index</th></tr> | 
					
						
							|  |  |  |     <tr ng-repeat="row in data track by $index"> | 
					
						
							|  |  |  |       <td>{{row.Name}}</td> | 
					
						
							|  |  |  |       <td>{{row.Index}}</td> | 
					
						
							|  |  |  |     </tr> | 
					
						
							|  |  |  |   </table> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <script> | 
					
						
							|  |  |  | var app = angular.module('s5s', []); | 
					
						
							|  |  |  | app.controller('sheetjs', function($scope, $http) { | 
					
						
							|  |  |  |   $scope.exportSheetJS = function() { | 
					
						
							|  |  |  |     var ws = XLSX.utils.json_to_sheet($scope.data); | 
					
						
							|  |  |  |     var wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(wb, ws, "Presidents"); | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSAngularJSAoO.xlsx"); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   $http({ | 
					
						
							|  |  |  |     method:'GET', | 
					
						
							|  |  |  |     url:'https://sheetjs.com/pres.xlsx', | 
					
						
							|  |  |  |     responseType:'arraybuffer' | 
					
						
							|  |  |  |   }).then(function(data) { | 
					
						
							|  |  |  |     var wb = XLSX.read(data.data, {type:"array"}); | 
					
						
							|  |  |  |     var data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |     $scope.data = data; | 
					
						
							|  |  |  |   }, function(err) { console.log(err); }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | </body> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | </html>`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 2) Start a local web server with `npx http-server .` and access the displayed | 
					
						
							|  |  |  | URL with a web browser (typically `http://localhost:8080`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### HTML
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The main disadvantage of the Array of Objects approach is the specific nature | 
					
						
							|  |  |  | of the columns.  For more general use, passing around an Array of Arrays works. | 
					
						
							|  |  |  | However, this does not handle merge cells well! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `sheet_to_html` function generates HTML that is aware of merges and other | 
					
						
							|  |  |  | worksheet features.  The generated HTML does not contain any `<script>` tags, | 
					
						
							|  |  |  | and should therefore be safe to pass to an `ng-bind-html` binding. This approach | 
					
						
							|  |  |  | requires the `ngSanitize` plugin. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <div ng-controller="sheetjs"> | 
					
						
							|  |  |  |   <!-- highlight-next-line --> | 
					
						
							|  |  |  |   <div ng-bind-html="data" id="tbl"></div> | 
					
						
							|  |  |  | </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script> | 
					
						
							|  |  |  | // highlight-next-line | 
					
						
							|  |  |  | var app = angular.module('s5s', ['ngSanitize']); | 
					
						
							|  |  |  | app.controller('sheetjs', function($scope, $http) { | 
					
						
							|  |  |  |   $http({ method:'GET', url:'https://sheetjs.com/pres.xlsx', responseType:'arraybuffer' }).then(function(data) { | 
					
						
							|  |  |  |     var wb = XLSX.read(data.data, {type:"array"}); | 
					
						
							|  |  |  |     // highlight-next-line | 
					
						
							|  |  |  |     $scope.data = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |   }, function(err) { console.log(err); }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The HTML table can be directly exported with `XLSX.utils.table_to_book`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  |   $scope.exportSheetJS = function() { | 
					
						
							|  |  |  |     /* export table element */ | 
					
						
							|  |  |  |     // highlight-start | 
					
						
							|  |  |  |     var tbl = document.getElementById("tbl").getElementsByTagName("TABLE")[0]; | 
					
						
							|  |  |  |     var wb = XLSX.utils.table_to_book(tbl); | 
					
						
							|  |  |  |     // highlight-end | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSAngularJSHTML.xlsx"); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details><summary><b>Complete Example</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Save the following to `index.html`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | <CodeBlock language="html" title="index.html">{`\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <!DOCTYPE html> | 
					
						
							|  |  |  | <html ng-app="s5s"> | 
					
						
							|  |  |  | <head> | 
					
						
							|  |  |  |   <title>SheetJS + AngularJS</title> | 
					
						
							|  |  |  |   <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> | 
					
						
							|  |  |  |   <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-sanitize.js"></script> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  |   <script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js"></script> | 
					
						
							|  |  |  |   <script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script> | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | </head> | 
					
						
							|  |  |  | <body> | 
					
						
							|  |  |  | <h3><a href="https://sheetjs.com">SheetJS + AngularJS demo</a></h3> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <div ng-controller="sheetjs"> | 
					
						
							|  |  |  |   <button ng-click="exportSheetJS()">Export Table</button> | 
					
						
							|  |  |  |   <div ng-bind-html="data" id="tbl"></div> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | <script> | 
					
						
							|  |  |  | var app = angular.module('s5s', ['ngSanitize']); | 
					
						
							|  |  |  | app.controller('sheetjs', function($scope, $http) { | 
					
						
							|  |  |  |   $scope.exportSheetJS = function() { | 
					
						
							|  |  |  |     var tbl = document.getElementById("tbl").getElementsByTagName("TABLE")[0]; | 
					
						
							|  |  |  |     var wb = XLSX.utils.table_to_book(tbl); | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSAngularJSHTML.xlsx"); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   $http({ | 
					
						
							|  |  |  |     method:'GET', | 
					
						
							|  |  |  |     url:'https://sheetjs.com/pres.xlsx', | 
					
						
							|  |  |  |     responseType:'arraybuffer' | 
					
						
							|  |  |  |   }).then(function(data) { | 
					
						
							|  |  |  |     var wb = XLSX.read(data.data, {type:"array"}); | 
					
						
							|  |  |  |     $scope.data = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |   }, function(err) { console.log(err); }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | </body> | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | </html>`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											2023-04-09 00:20:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 2) Start a local web server with `npx http-server .` and access the displayed | 
					
						
							|  |  |  | URL with a web browser (typically `http://localhost:8080`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> |