有一天在钉钉突然收到我闺蜜的信息,跟我咨询有木有什么公式之类的,在excel表格中检查“序列”两两之间,前六位相同位置,字母相同的个数不超过3个。超过则标黄。我当时一听,就觉得你给我程序,有这需求,我还能拿循环去做,你这excel表不是为难我嘛~ 然后我说没啥公式,你有不重要的样表吗?直接过我吧,我有空看看。
然后我就在网络上找了各种前端读取excel表格数据的插件,(因为是做前端的,对前端语言比较熟)。最后选定了xlsx.full.min.js (无意间在我的项目中看到曾经用过这个做excel表格导出)官网地址https://github.com/SheetJS/js-xlsx。
function readWorkbookFromLocalFile(file, callback) { var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; var workbook = XLSX.read(data, {type: 'binary'}); if(callback) callback(workbook); }; reader.readAsBinaryString(file); }
代码中可以看到,其中还有一个知识点 FileReader,FileReader
对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
或 Blob
对象指定要读取的文件或数据。官网知识点 https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader 。
FileReader.readAsBinaryString()
开始读取指定的Blob
中的内容。一旦完成,result
属性中将包含所读取文件的原始二进制数据。
看function还能发现第一个参数是file,也就是从本地读取的文件对象。刚开始一直以为是inputfilename 这个input的value值,后来发现value值是指读取文件的本地路径("C:fakepathxlsx.full.min.js")。后来查到document.getElementById('inputfilename').files[0]; 这样拿到的数据才是file对象,才能用作readWorkbookFromLocalFile函数的第一个参数。
<input type="file" id='inputfilename'> <button onclick="doclick();">读取</button>
到了此处,已经能拿到excel的数据了。只需要按需获取到序列那一列的数据,然后循环对比,把需要“标黄”处理的位置(如D2,D16)记录下来。我采用的是最笨的方案,把所有序列放进一个数组,拿每个数据与其他数据对比,一旦出现标黄的情况,则结束该数据的对比,拿下一个数据再来比较,如此循环。
function showdata(data){ //console.log(data); //拿到数据了 var sheets= data.sheets; var diffArrAdress = new Array(); var sheetname; if(data.SheetNames.length>0){ for(var p=0;p<data.SheetNames.length;p++){ diffArrAdress.length=0; sheetname = data.SheetNames[p]; var sheetobj = data.Sheets[sheetname]; var xlarr = new Array(); var lag=''; for(var k in sheetobj){ /*if(k.indexOf('D') != -1){ if(xl != '序列'){ xlarr.push({'k':k,'v':sheetobj[k]['v'].slice(0,6)}); } }*/ var xl = sheetobj[k]['v']; if(sheetobj[k]['v'] == '序列'){ lag = k.slice(0,1); } if(lag != '' && k.indexOf(lag) != -1){ if(xl != '序列'){ xlarr.push({'k':k,'v':sheetobj[k]['v'].slice(0,6)}); } } } if(xlarr.length>0){ var temp =''; for(var i=0;i<xlarr.length;i++){ var xlitem = xlarr[i]['v']; for(var j=0;j<xlarr.length;j++){ if(i != j){ if(duibi(xlitem,xlarr[j]['v'])){ var adress1 = xlarr[i]['k']; var adress2 = xlarr[j]['k']; //返回true 则表示对比时相同位置字母相同超过了3个 console.log(sheetname + "标黄位置: " + adress1 + ". 检测数据 分别是 " + adress1 + "("+ sheetobj[adress1]['v'] +"), "+ adress2 +" ("+ sheetobj[adress2]['v'] +")."); var len = diffArrAdress.length; if(len>0){ if(diffArrAdress[len-1] != adress1){ diffArrAdress.push(adress1); } }else{ diffArrAdress.push(adress1); } break; } } } } } $("#diffdiv").append("<p>"+sheetname + " : 标黄位置:" +diffArrAdress.join(',')+"</p>"); } } } //检查序列是否两个 function duibi(xl1,xl2){ if(xl1 && xl2 && xl1.length == xl2.length){ var eqcount = 0; var xl1arr = xl1.split(''); var xl2arr = xl2.split(''); for(var j=0;j<xl1arr.length;j++){ if(xl1arr[j] == xl2arr[j]){ eqcount++; } } if(eqcount>3){ return true; }else{ return false; } }else{ return false; } }
结果就是功能ok,页面会把每个sheet里面需要标黄的位置展示在页面。F12查看浏览器的console栏可以查看每个被标记位置是对比的哪个位置的什么数据,以此来检查是否正确。
总之,很有成就感。毕竟实际帮助了闺蜜她 (她夸我拯救了她的眼睛),还练了手,虽然代码很糙~