var nodeExcel = require('excel-export');
var transform = function(json,config) {
var conf = transform.prepareJson(json,config);
var result = nodeExcel.execute(conf);
return result;
};
//get a xls type based on js type
function getType(obj,type) {
if (type) {
return type;
}
var t = typeof obj;
switch (t) {
case 'string':
case 'number':
return t;
case 'boolean':
return 'bool';
default:
return 'string';
}
}
//get a nested property from a JSON object given its key, i.e 'a.b.c'
function getByString(object, path) {
path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
path = path.replace(/^\./, ''); // strip a leading dot
var a = path.split('.');
while (a.length) {
var n = a.shift();
if (n in object) {
object = (object[n]==undefined)?null:object[n];
} else {
return null;
}
}
return object;
}
//prepare json to be in the correct format for excel-export
transform.prepareJson = function(json,config) {
var res = {};
var conf = config||{};
var jsonArr = [].concat(json);
var fields = conf.fields || Object.keys(jsonArr[0]||{});
var types = [];
if (!(fields instanceof Array)) {
types = Object.keys(fields).map(function(key) {
return fields[key];
});
fields = Object.keys(fields);
}
//cols
res.cols = fields.map(function(key,i) {
return {
caption: key,
type: getType(jsonArr[0][key],types[i]),
beforeCellWrite: function(row, cellData, eOpt){
eOpt.cellType = getType(cellData,types[i]);
return cellData;
}
};
});
//rows
res.rows = jsonArr.map(function(row) {
return fields.map(function(key) {
var value = getByString(row,key);
//stringify objects
if(value && value.constructor == Object) value = JSON.stringify(value);
//replace illegal xml characters with a square
//see http://www.w3.org/TR/xml/#charsets
//#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
if (typeof value === 'string') {
value = value.replace(/[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]/g,'');
}
return value;
});
});
//add style xml if given
if (conf.style) {
res.stylesXmlFile = conf.style;
}
return res;
};
/*
transform.middleware = function(req,res,next) {
res.xls = function(fn,data,config) {
var xls = transform(data,config);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader("Content-Disposition", "attachment; filename=" + fn);
res.end(xls, 'binary');
};
next();
};
*/
module.exports = transform;