copay/js/util/csv.js

96 lines
2.4 KiB
JavaScript

/**
* Small module for exporting data to CSV.
*/
var _ = require('lodash');
var preconditions = require('preconditions').singleton();
var moment = require('moment');
var logger = require('../util/log.js');
var config = require('../../config');
var COL_DELIMITER = ',';
var ROW_DELIMITER = '\r\n';
function getValue(obj, property) {
if (_.isFunction(property)) {
try {
return property(obj);
} catch (err) {
if (_.isString(err)) return err;
return undefined;
}
}
if (!_.isObject(obj)) return undefined;
return obj.hasOwnProperty(property) ? obj[property] : undefined;
};
function formatValue(value, type, format) {
if (_.isUndefined(value) || _.isNull(value)) return '';
var r;
switch (type) {
default:
case 'string':
r = value.toString();
r.replace('"', '\\"');
break;
case 'date':
r = moment(value).format(format);
break;
case 'number':
r = value.toString();
break;
}
// escape when commas in values
if (r.indexOf(',') !== -1) {
r = '"' + r + '"';
}
return r;
};
function getHeader(descriptor) {
return _.map(descriptor.columns, function (col) {
return col.label || (_.isString(col.property) ? col.property : '') || '';
});
};
function processDataRow(data, descriptor) {
return _.map(descriptor.columns, function (col) {
var value = getValue(data, col.property);
var formatted = formatValue(value, col.type, col.format);
return formatted;
});
};
/**
* @desc Convert json object to csv based on a descriptor
*
* @param {array} data - the array of json objects to convert to csv
* @param {object} descriptor - an object that parameterizes the conversion
* @param {function} cb - called with the resulting csv
*/
module.exports.toCsv = function(data, descriptor, cb) {
preconditions.shouldBeArray(data);
preconditions.shouldBeObject(descriptor);
preconditions.shouldBeArray(descriptor.columns);
preconditions.shouldBeFunction(cb);
var colDelimiter = descriptor.colDelimiter || COL_DELIMITER;
var rowDelimiter = descriptor.rowDelimiter || ROW_DELIMITER;
var rows = _.map(data, function (dataRow) {
return processDataRow(dataRow, descriptor);
});
var header = getHeader(descriptor);
rows.unshift(header);
var csv = _.reduce(rows, function (memo, row) {
return memo + row.join(colDelimiter) + rowDelimiter;
}, '');
return cb(null, csv);
};