├── .gitignore ├── README.md ├── json2xlsx.js ├── package.json └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | file.json\r\nfile2.json\r\nfile.xlsx 2 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Json2XLSX 2 | ========= 3 | 4 | Provide or pipe a JSON object to a new Excel XLSX file 5 | 6 | Takes an object with one worksheet (tab) per key, and a 2d array or array of objects. 7 | Updates an existing file if already created. 8 | 9 | ```` 10 | { 11 | "worksheet1": [ 12 | [1,2,3], 13 | [4,5,6] 14 | ], 15 | 16 | "worksheet2": [ 17 | {a: 1, b: 2}, 18 | {a: 3, b: 4} 19 | ] 20 | } 21 | ```` 22 | 23 | ### Write Excel 24 | ```` 25 | require('json2xlsx').write(filename, sheetname, [object]); 26 | ```` 27 | or pipe.. 28 | ```` 29 | $ echo '{"work1": [["TRUE",2,3], [4,5,6]], "work2": [{"a": 1, "b":2},{"a":3, "b": 4}]}'\ 30 | | node -e "require('./json2xlsx.js').write('file.xlsx')" 31 | 32 | # update existing 33 | $ echo '{"work3": [["TRUE",2,3], [4,5,6]], "work4": [{"a": 1, "b":2},{"a":3, "b": 4}]}'\ 34 | | node -e "require('./json2xlsx.js').write('file.xlsx')" 35 | 36 | # show additional info about writing (set env variable) 37 | $ debug=1 ... 38 | ```` 39 | ###Read Excel 40 | ```` 41 | require('json2xlsx').read('file.xlsx'); // JSON written to console/stdout 42 | # or 43 | $ node ./json2xlsx file.xlsx 44 | ```` 45 | 46 | ##Order JSON attributes (to have columns in order in Excel) 47 | ```` 48 | echo "..." | require('json2xlsx').write('name.xlsx', 'sheetname', null, ['first_col_name', 'second_col_name']) 49 | ```` 50 | -------------------------------------------------------------------------------- /json2xlsx.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var xlsx = require('xlsx'), 4 | fs = require('fs'); 5 | 6 | if (process.argv[2]){ 7 | try { 8 | if (fs.existsSync(path)) { 9 | readXLSX(process.argv[2]); 10 | } 11 | } catch(err) { 12 | console.error(`The file "${process.argv[2]}" doesn't exists.`) 13 | } 14 | } 15 | 16 | function readXLSX(filename) { 17 | return require('xlsx').readFile(filename).Sheets; 18 | } 19 | 20 | function writeXLSX(filename, sheetname, obj, order) { 21 | 22 | if (process.env.debug) console.log(arguments); 23 | 24 | if (!obj) { 25 | var indata = ''; 26 | process.stdin.on('readable', function() { 27 | indata += process.stdin.read() || ''; 28 | }) 29 | process.stdin.on('end', processData); 30 | } else { 31 | processData(); 32 | } 33 | 34 | function processData() { 35 | 36 | try { 37 | var t = obj || JSON.parse(indata); 38 | } catch(e){ 39 | return console.log(e); 40 | } 41 | 42 | if (!t || typeof t !== 'object') 43 | throw Error('json2xlsx - not an object'); 44 | 45 | if (order) 46 | t = orderAttr(t, order); 47 | 48 | if(process.env.debug) 49 | console.log(t); 50 | 51 | if (t.push && sheetname) { 52 | var ob = {}; 53 | ob[sheetname] = t; 54 | o = ob; 55 | } else { 56 | o = t; 57 | } 58 | var wb = fs.existsSync(filename) ? xlsx.readFile(filename) : new Workbook(); 59 | 60 | for (ws_name in o) { 61 | var sheetdispname = sheetname || ws_name; 62 | var twodarr = o[ws_name]; 63 | if (!twodarr[0]) continue; 64 | 65 | wb.SheetNames.push(sheetdispname); 66 | if (!twodarr[0].push) 67 | twodarr = convertObjArray(twodarr); 68 | var ws = sheet_from_array_of_arrays(twodarr); 69 | wb.Sheets[sheetdispname] = ws; 70 | if (process.env.debug) 71 | console.log(filename, '/', sheetdispname); 72 | } 73 | xlsx.writeFile(wb, filename); 74 | } 75 | 76 | function convertObjArray(objarray) { 77 | try { 78 | var arrarr = [Object.keys(objarray[0])]; 79 | for (var n = 0; n < objarray.length; n++) { 80 | var row = []; 81 | for (var i in objarray[0]) 82 | row.push(objarray[n][i]); 83 | arrarr.push(row); 84 | } 85 | if (process.env.debug) 86 | console.log(arrarr.length + ' records'); 87 | return arrarr; 88 | } catch (e) { 89 | console.log(objarray); 90 | return [ 91 | [] 92 | ]; 93 | } 94 | } 95 | 96 | function datenum(v, date1904) { 97 | if (date1904) v += 1462; 98 | var epoch = Date.parse(v); 99 | return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); 100 | } 101 | 102 | function sheet_from_array_of_arrays(data, opts) { 103 | var ws = {}; 104 | var range = { 105 | s: { 106 | c: 10000000, 107 | r: 10000000 108 | }, 109 | e: { 110 | c: 0, 111 | r: 0 112 | } 113 | }; 114 | for (var R = 0; R != data.length; ++R) { 115 | for (var C = 0; C != data[R].length; ++C) { 116 | if (range.s.r > R) range.s.r = R; 117 | if (range.s.c > C) range.s.c = C; 118 | if (range.e.r < R) range.e.r = R; 119 | if (range.e.c < C) range.e.c = C; 120 | var cell = { 121 | v: data[R][C] 122 | }; 123 | if (cell.v == null) continue; 124 | var cell_ref = xlsx.utils.encode_cell({ 125 | c: C, 126 | r: R 127 | }); 128 | 129 | if (typeof cell.v === 'number') cell.t = 'n'; 130 | else if (typeof cell.v === 'boolean') cell.t = 'b'; 131 | else if (cell.v instanceof Date) { 132 | cell.t = 'n'; 133 | cell.z = xlsx.SSF._table[14]; 134 | cell.v = datenum(cell.v); 135 | } else cell.t = 's'; 136 | 137 | ws[cell_ref] = cell; 138 | } 139 | } 140 | if (range.s.c < 10000000) ws['!ref'] = xlsx.utils.encode_range(range); 141 | return ws; 142 | } 143 | 144 | function orderAttr(obj, order) { 145 | var newobj = []; 146 | for (var i = 0; i < obj.length; i++) { 147 | var oldo = obj[i]; 148 | var newo = {}; 149 | order.forEach(function(field) { 150 | if (oldo[field]) { 151 | newo[field] = oldo[field]; 152 | delete oldo[field]; 153 | } 154 | }) 155 | for (j in oldo) 156 | newo[j] = oldo[j]; 157 | newobj[i] = newo; 158 | } 159 | return newobj; 160 | } 161 | 162 | function Workbook() { 163 | if (!(this instanceof Workbook)) return new Workbook(); 164 | this.SheetNames = []; 165 | this.Sheets = {}; 166 | } 167 | 168 | } 169 | 170 | if (module && module.exports) { 171 | module.exports = { 172 | write: writeXLSX, 173 | read: readXLSX 174 | }; 175 | } 176 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json2xlsx", 3 | "description": "Pipe JSON to Excel spreadsheet", 4 | "url": "http://github.com/dpweb/json2xlsx/", 5 | "keywords": [ 6 | "util", 7 | "nodejs" 8 | ], 9 | "author": { 10 | "name": "C Borkert", 11 | "email": "ILIKECHEESE@dpsw.info" 12 | }, 13 | "dependencies": { 14 | "xlsx": "" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git://github.com/dpweb/json2xlsx.git" 19 | }, 20 | "main": "json2xlsx.js", 21 | "bin": { 22 | "json2xlsx": "json2xlsx.js" 23 | }, 24 | "version": "0.1.5" 25 | } 26 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | # write an Excel file 2 | echo '{"work1": [["TRUE",2,3], [4,5,6]], "work2": [{"a": 1, "b":2},{"a":3, "b": 4}]}'\ 3 | | node -e "require('./json2xlsx.js').write('file.xlsx')" 4 | 5 | # update existing 6 | echo '{"work3": [["TRUE",2,3], [4,5,6]], "work4": [{"a": 1, "b":2},{"a":3, "b": 4}]}'\ 7 | | node -e "require('./json2xlsx.js').write('file.xlsx')" 8 | 9 | # Read an Excel file 10 | node -e "require('./json2xlsx.js').read('file.xlsx')" 11 | 12 | # use node 13 | node ./json2xlsx.js file.xlsx 14 | 15 | # global (read xlsx) 16 | json2xlsx file.xlsx 17 | --------------------------------------------------------------------------------