├── .gitignore
├── bower.json
├── README.md
├── dest
├── json-export-excel.min.js
└── json-export-excel.js
├── LICENSE.md
├── package.json
├── example
└── index.html
├── Gruntfile.js
└── src
└── json-export-excel.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 | .idea
4 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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"])})}}})}();
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | })();
--------------------------------------------------------------------------------
/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 | })();
--------------------------------------------------------------------------------