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
			| 
											3 years ago
										 | 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; | ||
|  |   } | ||
|  | } |