236 lines
5.7 KiB
Plaintext
236 lines
5.7 KiB
Plaintext
var parserMgr = require("./parserMgr.js");
|
|
var CSVError = require("./CSVError");
|
|
var numReg = /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/;
|
|
/**
|
|
* Convert lines of csv array into json
|
|
* @param {[type]} lines [[col1,col2,col3]]
|
|
* @param {[type]} params Converter params with _headers field populated
|
|
* @param {[type]} idx start pos of the lines
|
|
* @return {[type]} [{err:null,json:obj,index:line,row:[csv row]}]
|
|
*/
|
|
module.exports = function (lines, params, idx) {
|
|
if (params._needParseJson) {
|
|
if (!params._headers || !Array.isArray(params._headers)) {
|
|
params._headers = [];
|
|
}
|
|
if (!params.parseRules) {
|
|
var row = params._headers;
|
|
params.parseRules = parserMgr.initParsers(row, params);
|
|
}
|
|
return processRows(lines, params, idx);
|
|
} else {
|
|
return justReturnRows(lines, params, idx);
|
|
}
|
|
};
|
|
|
|
function justReturnRows(lines, params, idx) {
|
|
var rtn = [];
|
|
for (var i = 0, len = lines.length; i < len; i++) {
|
|
rtn.push({
|
|
err: null,
|
|
json: {},
|
|
index: idx++,
|
|
row: lines[i]
|
|
});
|
|
}
|
|
return rtn;
|
|
}
|
|
|
|
function processRows(csvRows, params, startIndex) {
|
|
var res = [];
|
|
for (var i = 0, len = csvRows.length; i < len; i++) {
|
|
var r = processRow(csvRows[i], params, startIndex++);
|
|
if (r) {
|
|
res.push(r);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function processRow(row, param, index) {
|
|
var parseRules = param.parseRules;
|
|
if (param.checkColumn && row.length !== parseRules.length) {
|
|
return {
|
|
err: CSVError.column_mismatched(index)
|
|
};
|
|
}
|
|
|
|
var headRow = param._headers;
|
|
var resultRow = convertRowToJson(row, headRow, param);
|
|
if (resultRow) {
|
|
return {
|
|
json: resultRow,
|
|
index: index,
|
|
row: row
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function convertRowToJson(row, headRow, param) {
|
|
var hasValue = false;
|
|
var resultRow = {};
|
|
|
|
for (var i = 0, len = row.length; i < len; i++) {
|
|
var convertFunc, head, item;
|
|
item = row[i];
|
|
|
|
if (param.ignoreEmpty && item === '') {
|
|
continue;
|
|
}
|
|
hasValue = true;
|
|
|
|
head = headRow[i];
|
|
if (!head || head === "") {
|
|
head = headRow[i] = "field" + (i + 1);
|
|
}
|
|
var convFunc = getConvFunc(head, i, param);
|
|
if (convFunc) {
|
|
var convRes = convFunc(item, head, resultRow,row,i);
|
|
if (convRes !== undefined) {
|
|
setPath(resultRow, head, convRes);
|
|
}
|
|
} else {
|
|
var flag = getFlag(head, i, param);
|
|
if (flag === 'omit') {
|
|
continue;
|
|
}
|
|
if (param.checkType) {
|
|
convertFunc = checkType(item, head, i, param);
|
|
item = convertFunc(item);
|
|
}
|
|
var title = getTitle(head, i, param);
|
|
if (flag === 'flat' || param.flatKeys) {
|
|
resultRow[title] = item;
|
|
} else {
|
|
setPath(resultRow, title, item);
|
|
}
|
|
}
|
|
}
|
|
if (hasValue) {
|
|
return resultRow;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var builtInConv={
|
|
"string":stringType,
|
|
"number":numberType,
|
|
"omit":function(){}
|
|
}
|
|
function getConvFunc(head,i,param){
|
|
if (param._columnConv[i] !== undefined){
|
|
return param._columnConv[i];
|
|
}else{
|
|
var flag=param.colParser[head];
|
|
if (flag === undefined){
|
|
return param._columnConv[i]=false;
|
|
}
|
|
if (typeof flag ==="string"){
|
|
flag=flag.trim().toLowerCase();
|
|
var builtInFunc=builtInConv[flag];
|
|
if (builtInFunc){
|
|
return param._columnConv[i]=builtInFunc;
|
|
}else{
|
|
return param._columnConv[i]=false;
|
|
}
|
|
}else if (typeof flag ==="function"){
|
|
return param._columnConv[i]=flag;
|
|
}else{
|
|
return param._columnConv[i]=false;
|
|
}
|
|
}
|
|
}
|
|
function setPath(json, path, value) {
|
|
var _set = require('lodash/set');
|
|
var pathArr = path.split('.');
|
|
if (pathArr.length === 1) {
|
|
json[path] = value;
|
|
} else {
|
|
_set(json, path, value);
|
|
}
|
|
}
|
|
|
|
function getFlag(head, i, param) {
|
|
if (typeof param._headerFlag[i] === "string") {
|
|
return param._headerFlag[i];
|
|
} else if (head.indexOf('*omit*') > -1) {
|
|
return param._headerFlag[i] = 'omit';
|
|
} else if (head.indexOf('*flat*') > -1) {
|
|
return param._headerFlag[i] = 'flat';
|
|
} else {
|
|
return param._headerFlag[i] = '';
|
|
}
|
|
}
|
|
|
|
function getTitle(head, i, param) {
|
|
if (param._headerTitle[i]) {
|
|
return param._headerTitle[i];
|
|
}
|
|
|
|
var flag = getFlag(head, i, param);
|
|
var str = head.replace('*flat*', '').replace('string#!', '').replace('number#!', '');
|
|
return param._headerTitle[i] = str;
|
|
}
|
|
|
|
function checkType(item, head, headIdx, param) {
|
|
if (param._headerType[headIdx]) {
|
|
return param._headerType[headIdx];
|
|
} else if (head.indexOf('number#!') > -1) {
|
|
return param._headerType[headIdx] = numberType;
|
|
} else if (head.indexOf('string#!') > -1) {
|
|
return param._headerType[headIdx] = stringType;
|
|
} else if (param.checkType) {
|
|
return param._headerType[headIdx] = dynamicType;
|
|
} else {
|
|
return param._headerType[headIdx] = stringType;
|
|
}
|
|
}
|
|
|
|
function numberType(item) {
|
|
var rtn = parseFloat(item);
|
|
if (isNaN(rtn)) {
|
|
return item;
|
|
}
|
|
return rtn;
|
|
}
|
|
|
|
function stringType(item) {
|
|
return item.toString();
|
|
}
|
|
|
|
function dynamicType(item) {
|
|
var trimed = item.trim();
|
|
if (trimed === "") {
|
|
return stringType(item);
|
|
}
|
|
if (numReg.test(trimed)) {
|
|
return numberType(item);
|
|
} else if (trimed.length === 5 && trimed.toLowerCase() === "false" || trimed.length === 4 && trimed.toLowerCase() === "true") {
|
|
return booleanType(item);
|
|
} else if (trimed[0] === "{" && trimed[trimed.length - 1] === "}" || trimed[0] === "[" && trimed[trimed.length - 1] === "]") {
|
|
return jsonType(item);
|
|
} else {
|
|
return stringType(item);
|
|
}
|
|
}
|
|
|
|
function booleanType(item) {
|
|
var trimed = item.trim();
|
|
if (trimed.length === 5 && trimed.toLowerCase() === "false") {
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function jsonType(item) {
|
|
try {
|
|
return JSON.parse(item);
|
|
} catch (e) {
|
|
return item;
|
|
}
|
|
}
|