├── .gitignore ├── Gruntfile.js ├── LICENSE.md ├── README.md ├── bower.json ├── dest ├── json-export-excel.js └── json-export-excel.min.js ├── example └── index.html ├── package.json └── src └── json-export-excel.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | .idea 4 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | // * Read command-line switches 3 | // - Read in --browsers CLI option; split it on commas into an array if it's a string, otherwise ignore it 4 | var browsers = typeof grunt.option('browsers') == 'string' ? grunt.option('browsers').split(',') : undefined; 5 | 6 | grunt.initConfig({ 7 | pkg: grunt.file.readJSON('package.json'), 8 | library: grunt.file.readJSON('bower.json'), 9 | concat: { 10 | options: { 11 | separator: '' 12 | }, 13 | library: { 14 | src: [ 15 | 'src/**/*.js' 16 | ], 17 | dest: 'dest/<%= library.name %>.js' 18 | } 19 | }, 20 | uglify: { 21 | options: { 22 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' 23 | }, 24 | jid: { 25 | files: { 26 | 'dest/<%= library.name %>.min.js': ['<%= concat.library.dest %>'] 27 | } 28 | } 29 | }, 30 | jshint: { 31 | beforeConcat: { 32 | src: ['gruntfile.js', '<%= library.name %>/**/*.js'] 33 | }, 34 | afterConcat: { 35 | src: [ 36 | '<%= concat.library.dest %>' 37 | ] 38 | }, 39 | options: { 40 | // options here to override JSHint defaults 41 | globals: { 42 | jQuery: true, 43 | console: true, 44 | module: true, 45 | document: true, 46 | angular: true 47 | }, 48 | globalstrict: false 49 | } 50 | }, 51 | testFiles: { 52 | karmaUnit: 'karma.conf.js' 53 | }, 54 | karma: { 55 | unit: { 56 | options: { 57 | configFile: '<%= testFiles.karmaUnit %>', 58 | autoWatch: false, 59 | singleRun: true, 60 | browsers: browsers || ['Chrome'] 61 | } 62 | } 63 | }, 64 | watch: { 65 | options: { 66 | livereload: true 67 | }, 68 | files: [ 69 | 'Gruntfile.js', 70 | 'src/**/*' 71 | ], 72 | tasks: ['default'] 73 | }, 74 | connect: { 75 | server: { 76 | options: { 77 | hostname: '*' 78 | } 79 | } 80 | } 81 | }); 82 | 83 | // Load grunt-karma task plugin 84 | grunt.loadNpmTasks('grunt-karma'); 85 | 86 | grunt.loadNpmTasks('grunt-contrib-uglify'); 87 | grunt.loadNpmTasks('grunt-contrib-jshint'); 88 | grunt.loadNpmTasks('grunt-contrib-concat'); 89 | grunt.loadNpmTasks('grunt-contrib-watch'); 90 | grunt.loadNpmTasks('grunt-contrib-connect'); 91 | 92 | grunt.registerTask('test', ['jshint', 'karma:unit']); 93 | grunt.registerTask('default', ['jshint:beforeConcat', 'concat', 'jshint:afterConcat', 'uglify']); 94 | grunt.registerTask('livereload', ['default', 'connect:server', 'watch']); 95 | 96 | }; 97 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dtagdev1 (https://github.com/dtagdev1) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ngJsonExportExcel - export excel from json using AngularJS 2 | ======= 3 | 4 | ## How to get it ? 5 | 6 | #### Bower 7 | ``` 8 | bower install ng-json-export-excel --save 9 | ``` 10 | 11 | ## Usage 12 | 13 | 1. Add json-export-excel.js and FileSaver.js to your main file (index.html) 14 | 15 | 16 | 2. Set `ngJsonExportExcel` as a dependency in your module 17 | ```javascript 18 | var myapp = angular.module('myapp', ['ngJsonExportExcel']) 19 | ``` 20 | 21 | 3. Example simple: 22 | ```html 23 | 24 | ``` 25 | Default `filename = 'export-excel'` 26 | 27 | Default `separator = ';'` 28 | 29 | 30 | 4. Please find examples in the directory `example` or You can check out this live example here: http://plnkr.co/6ieuJ1khmKFds9VYHoDv 31 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-export-excel", 3 | "version": "1.0.2", 4 | "main": "src/json-export-excel.js", 5 | "dependencies": { 6 | "angular": ">=1.0.4", 7 | "file-saver": "*" 8 | }, 9 | "devDependencies": { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /dest/json-export-excel.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('ngJsonExportExcel', []) 5 | .directive('ngJsonExportExcel', function () { 6 | return { 7 | restrict: 'AE', 8 | scope: { 9 | data : '=', 10 | filename: '=?', 11 | reportFields: '=', 12 | separator: '@' 13 | }, 14 | link: function (scope, element) { 15 | scope.filename = !!scope.filename ? scope.filename : 'export-excel'; 16 | 17 | var fields = []; 18 | var header = []; 19 | var separator = scope.separator || ';'; 20 | 21 | angular.forEach(scope.reportFields, function(field, key) { 22 | if(!field || !key) { 23 | throw new Error('error json report fields'); 24 | } 25 | 26 | fields.push(key); 27 | header.push(field); 28 | }); 29 | 30 | element.bind('click', function() { 31 | var bodyData = _bodyData(); 32 | var strData = _convertToExcel(bodyData); 33 | 34 | var blob = new Blob([strData], {type: "text/plain;charset=utf-8"}); 35 | 36 | return saveAs(blob, [scope.filename + '.csv']); 37 | }); 38 | 39 | function _bodyData() { 40 | var data = scope.data; 41 | var body = ""; 42 | angular.forEach(data, function(dataItem) { 43 | var rowItems = []; 44 | 45 | angular.forEach(fields, function(field) { 46 | if(field.indexOf('.')) { 47 | field = field.split("."); 48 | var curItem = dataItem; 49 | 50 | // deep access to obect property 51 | angular.forEach(field, function(prop){ 52 | if (curItem !== null && curItem !== undefined) { 53 | curItem = curItem[prop]; 54 | } 55 | }); 56 | 57 | data = curItem; 58 | } 59 | else { 60 | data = dataItem[field]; 61 | } 62 | 63 | var fieldValue = data !== null ? data : ' '; 64 | 65 | if (fieldValue !== undefined && angular.isObject(fieldValue)) { 66 | fieldValue = _objectToString(fieldValue); 67 | } 68 | 69 | if(typeof fieldValue == 'string') { 70 | rowItems.push('"' + fieldValue.replace(/"/g, '""') + '"'); 71 | } else { 72 | rowItems.push(fieldValue); 73 | } 74 | }); 75 | 76 | body += rowItems.join(separator) + '\n'; 77 | }); 78 | 79 | return body; 80 | } 81 | 82 | function _convertToExcel(body) { 83 | return header.join(separator) + '\n' + body; 84 | } 85 | 86 | function _objectToString(object) { 87 | var output = ''; 88 | angular.forEach(object, function(value, key) { 89 | output += key + ':' + value + ' '; 90 | }); 91 | 92 | return '"' + output + '"'; 93 | } 94 | } 95 | }; 96 | }); 97 | })(); -------------------------------------------------------------------------------- /dest/json-export-excel.min.js: -------------------------------------------------------------------------------- 1 | /*! json-export-excel 29-06-2016 */ 2 | !function(){"use strict";angular.module("ngJsonExportExcel",[]).directive("ngJsonExportExcel",function(){return{restrict:"AE",scope:{data:"=",filename:"=?",reportFields:"=",separator:"@"},link:function(a,b){function c(){var b=a.data,c="";return angular.forEach(b,function(a){var d=[];angular.forEach(f,function(c){if(c.indexOf(".")){c=c.split(".");var f=a;angular.forEach(c,function(a){null!==f&&void 0!==f&&(f=f[a])}),b=f}else b=a[c];var g=null!==b?b:" ";void 0!==g&&angular.isObject(g)&&(g=e(g)),"string"==typeof g?d.push('"'+g.replace(/"/g,'""')+'"'):d.push(g)}),c+=d.join(h)+"\n"}),c}function d(a){return g.join(h)+"\n"+a}function e(a){var b="";return angular.forEach(a,function(a,c){b+=c+":"+a+" "}),'"'+b+'"'}a.filename=a.filename?a.filename:"export-excel";var f=[],g=[],h=a.separator||";";angular.forEach(a.reportFields,function(a,b){if(!a||!b)throw new Error("error json report fields");f.push(b),g.push(a)}),b.bind("click",function(){var b=c(),e=d(b),f=new Blob([e],{type:"text/plain;charset=utf-8"});return saveAs(f,[a.filename+".csv"])})}}})}(); -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Demo Export Excel For Json 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |         <button ng-json-export-excel data="dataList" report-fields="{id: 'ID Heder', name: 'Name Header', price: 'Price Head'}"></button>
16 |     
17 |
18 | 19 | 20 |
21 |         <div ng-json-export-excel data="dataList" report-fields="{id: 'ID Heder', name: 'Name Header', price: 'Price Head'}" filename="filename"></div>
22 |     
23 |
24 | 25 | 48 | 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-export-excel", 3 | "version": "1.0.2", 4 | "main": "dest/json-export-excel.min.js", 5 | "filename": "json-export-excel.min.js", 6 | "description": "export excel from json using angularJs", 7 | 8 | "keywords": [ 9 | "angular", 10 | "angularjs", 11 | "export excel", 12 | "excel", 13 | "export", 14 | "json export excel", 15 | "json", 16 | "csv", 17 | "export csv", 18 | "json export csv", 19 | "ng-csv" 20 | ], 21 | "homepage": "https://github.com/dtagdev1/json-export-excel", 22 | "author": { 23 | "name": "Hiếu Trần", 24 | "email": "trantrunghieu0809@gmail.com", 25 | "url": "https://www.facebook.com/trantrunghieu0809" 26 | }, 27 | "dependencies": {}, 28 | "devDependencies": { 29 | "grunt": "~0.4.1", 30 | "grunt-contrib-copy": "~0.4.1", 31 | "grunt-contrib-concat": "~0.3.0", 32 | "grunt-contrib-coffee": "~0.7.0", 33 | "grunt-contrib-uglify": "~0.2.0", 34 | "grunt-contrib-compass": "~0.3.0", 35 | "grunt-contrib-jshint": "~0.6.0", 36 | "grunt-contrib-cssmin": "~0.6.0", 37 | "grunt-contrib-connect": "~0.3.0", 38 | "grunt-contrib-clean": "~0.4.1", 39 | "grunt-contrib-htmlmin": "~0.1.3", 40 | "grunt-contrib-imagemin": "~0.1.4", 41 | "grunt-contrib-watch": "~0.4.0", 42 | "grunt-usemin": "~0.1.11", 43 | "grunt-svgmin": "~0.2.0", 44 | "grunt-rev": "~0.1.0", 45 | "grunt-karma": "~0.4.3", 46 | "grunt-open": "~0.2.0", 47 | "grunt-concurrent": "~0.3.0", 48 | "matchdep": "~0.1.2", 49 | "connect-livereload": "~0.2.0", 50 | "grunt-google-cdn": "~0.2.0", 51 | "grunt-ngmin": "~0.0.2", 52 | "karma": "~0.12.0", 53 | "karma-jasmine": "~0.1.5", 54 | "karma-chrome-launcher": "~0.1.4" 55 | }, 56 | "engines": { 57 | "node": ">=0.8.0" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/json-export-excel.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('ngJsonExportExcel', []) 5 | .directive('ngJsonExportExcel', function () { 6 | return { 7 | restrict: 'AE', 8 | scope: { 9 | data : '=', 10 | filename: '=?', 11 | reportFields: '=', 12 | separator: '@' 13 | }, 14 | link: function (scope, element) { 15 | scope.filename = !!scope.filename ? scope.filename : 'export-excel'; 16 | 17 | var fields = []; 18 | var header = []; 19 | var separator = scope.separator || ';'; 20 | 21 | angular.forEach(scope.reportFields, function(field, key) { 22 | if(!field || !key) { 23 | throw new Error('error json report fields'); 24 | } 25 | 26 | fields.push(key); 27 | header.push(field); 28 | }); 29 | 30 | element.bind('click', function() { 31 | var bodyData = _bodyData(); 32 | var strData = _convertToExcel(bodyData); 33 | 34 | var blob = new Blob([strData], {type: "text/plain;charset=utf-8"}); 35 | 36 | return saveAs(blob, [scope.filename + '.csv']); 37 | }); 38 | 39 | function _bodyData() { 40 | var data = scope.data; 41 | var body = ""; 42 | angular.forEach(data, function(dataItem) { 43 | var rowItems = []; 44 | 45 | angular.forEach(fields, function(field) { 46 | if(field.indexOf('.')) { 47 | field = field.split("."); 48 | var curItem = dataItem; 49 | 50 | // deep access to obect property 51 | angular.forEach(field, function(prop){ 52 | if (curItem !== null && curItem !== undefined) { 53 | curItem = curItem[prop]; 54 | } 55 | }); 56 | 57 | data = curItem; 58 | } 59 | else { 60 | data = dataItem[field]; 61 | } 62 | 63 | var fieldValue = data !== null ? data : ' '; 64 | 65 | if (fieldValue !== undefined && angular.isObject(fieldValue)) { 66 | fieldValue = _objectToString(fieldValue); 67 | } 68 | 69 | if(typeof fieldValue == 'string') { 70 | rowItems.push('"' + fieldValue.replace(/"/g, '""') + '"'); 71 | } else { 72 | rowItems.push(fieldValue); 73 | } 74 | }); 75 | 76 | body += rowItems.join(separator) + '\n'; 77 | }); 78 | 79 | return body; 80 | } 81 | 82 | function _convertToExcel(body) { 83 | return header.join(separator) + '\n' + body; 84 | } 85 | 86 | function _objectToString(object) { 87 | var output = ''; 88 | angular.forEach(object, function(value, key) { 89 | output += key + ':' + value + ' '; 90 | }); 91 | 92 | return '"' + output + '"'; 93 | } 94 | } 95 | }; 96 | }); 97 | })(); --------------------------------------------------------------------------------