js解析带有合并单元格的xlsx文件,js高质量代码示范

这是我写的一段代码,谈不上高质量,但汇总了很多语言精粹。
总结一下我写代码的特点:
1、在开头处注明代码属性,作者是谁,日期是啥,功能作甚等
2、沿袭了java代码规范,我还是比较喜欢写main函数,把所有功能封装成普通函数,在main函数写处理逻辑,这样写的代码架构简单明了
3、就是注释啦,注释一定要够,代码第一次写问题难免会有,在闲暇时刻,我比较喜欢看自己先前写的代码,有改进的地方会改进改进,偶尔也会有bug和其他人阅读,这时候注释就很重要呢
3.1、写注释主要是每个函数,要注明参数的作用,函数的功能,接下来就是块级区域,小片段功能代码注释,作用域广的变量注释
4、是命名规范了,命名规范采用驼峰命名法,变量名一定得具有代表意思,英语单词一定要准确,我通常是在单词本里复制过来的
5、了解耗性能的操作,字符串操作比整形运算性能低得多,递归算法耗内存,做循要及时退出循环,不写死循环
6、变量要有赋初值的习惯,方便声明变量是什么类型



const xlsx = require('xlsx') const fpath = './user.xlsx' /** * auth:李金科 * func:解析带有合并单元格的xlsx文件 * date:21-7-29 */ function main(){ // let datas = parseXlsxData(fpath,'通讯录',1) let datas = parseXlsxData(fpath,0,1) // let datas = parseXlsxData(fpath) console.log(datas) } main() // xlsx解析函数,通过路径参数,和表名称(没有名称用Sheet2表示第二张表)参数解析xlsx文件, // 参数3为无效列数,设置无效列会把生成的数组的行数据从后向前删除字段值 function parseXlsxData(fpath,sheetName,colNone=0){ const sourceData = xlsx.readFile(fpath, {}) // 通过xlsx库获取源数据 sheetName = sheetName ? sheetName : Object.keys(sourceData.Sheets).pop() let sheetData = sourceData.Sheets[sheetName] // 获取xlsx表数据,默认获取第一张 if(!sheetData) return '你访问的数据表不存在' // 获取行数col和列数row let ref = sheetData['!ref'] let refParse = ref.match(/[a-z]+|[0-9]+/ig) let col = refParse[3] - refParse[1] + 1 let row = refParse[2].charCodeAt() - refParse[0].charCodeAt() + 1 // 获取单元格合并数据并建立数组索引 let merges = sheetData['!merges'] let mergesParses = xlsxMergeParse(merges) let mergeIndexs = mergeIndex(mergesParses) // 根据表的行数和列数创建一个表,在创建每个单元格时插入数据,数据填充普通单元格直接引用sheetData, //合并单元格通过映射下标计算引用sheetData let datas = [] for(let i = 1;i< col + 1 ;i++){ let row = [] for(let j = refParse[0].charCodeAt();j<refParse[2].charCodeAt()+1-colNone;j++){ let letter = String.fromCharCode(j) let k = j-64 row.push(sheetData[letter+i] ? sheetData[letter+i].w : autoFill([i,k],mergeIndexs,mergesParses,sheetData)) } datas.push(row) } return datas } // 解析单元格合并数据方法 // 解析表格单元格合并数据 把参与合并的单元格全部计算并统计位置信息 function xlsxMergeParse(merges){ let arr = [] merges.map(v=>{ let {s,e} = v let result = [] let addNum = 1 //使数组下标加一,符合Excel单元格下标 if(s.c === e.c){ for(let i = s.r;i<e.r+1;i++){result.push([i+addNum,s.c+addNum])} }else{ for(let i = s.c;i<e.c+1;i++){result.push([s.r+addNum,i+addNum])} } arr.push(result) }) return arr } // 单元格合并数据建立索引 // 单元格合并数据为三维数组,为了提升数据处理效率,添加索引(变为一维数组,序列化位置信息) function mergeIndex(mergesParse){ let datas = [] mergesParse.map((v,i) => { let row = [] v.map((v1,i1) => { row.push(v1.join(',')) row.push([i,i1].join('-')) }) datas.push(row) }) return datas.flat(Infinity) } // 根据单元格下标计算应该填充的值 function autoFill(point,index,mergesParses,sheetData){ // 判断此单元格是否属于合并单元格 let isNeed = index.indexOf(point.join(',')) if(isNeed < 0) return undefined // 通过索引获取映射的合并数据三维数组的下标 let target = index[isNeed+1] let result = target.split('-')[0] result = mergesParses[result][0] // 返回合并单元格左上单元格数据 result = sheetData[String.fromCharCode(result[1]+64)+result[0]].w return result }

  

posted @ 2021-08-05 08:58  中国计算机技术研究员  阅读(1117)  评论(0编辑  收藏  举报