You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							236 lines
						
					
					
						
							5.7 KiB
						
					
					
				
			
		
		
	
	
							236 lines
						
					
					
						
							5.7 KiB
						
					
					
				| 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;
 | |
|   }
 | |
| }
 |