简单的背景介绍不久前,我们接了一份自己做前后端产品的工作,过着敲代码快乐增长知识的苦日子.那是一个平淡无奇的星期一下午。用户小姐姐在群里说,系统对工卡有效期的过滤不太好。(系统:不不不,不是我的错,我看了一下数据库,发现我们原来的有效期格式这么工整,当时数据库里面的数据是这样的,甚至是这样的,看到这个情况,我想一定是输入不正确(年轻...所以我决定从Excel入手。小姐姐们的操作流程是先用我们的系统导出一个Excel,然后导入到修改后的系统。那只要我把这个工作卡栏的格式限定为日期,这样格式就可以统一了,嗯。我们的项目使用js-xlsx来处理表的导入导出。下面是导出Excel的伪代码:import*asXLSXfrom'xlsx';constxlsxMineType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'constdata=data.map((s:any)=>({ID:s.id,工卡有效期:s.card_expired,...}));constsheet=XLSX.utils.json_to_sheet(数据);constwb=XLSX.utils.book_new();XLSX.utils.book_append_sheet(wb,sheet,'员工信息表');constwbbuf=XLSX.write(wb,{type:'base64'});this.success({name:"员工信息表.xlsx",data:wbbuf,type:xlsxMineType});通过json_to_sheet可以得到包含单元格信息的对象{A2:{t:'n',v:3776},B2:{t:'s',v:'2019-04-01'},A3:{t:'n',v:3831},B3:{t:'s',v:'2019-04-01'},A1:{t:'s',v:'ID'},B1:{t:'s',v:'就业证有效期'},'!ref':'A1:B3'}单元格位置作为对象中的key,每个值(v),类型(t)和单元格的其他属性用作值。其中cell类型支持:bBoolean,nNumber,eerror,sString,dDateDate类型好像满足上面的要求,于是试了一下:constsheet=XLSX.utils.json_to_sheet(data);//过滤除标题之外的工作卡列Object.keys(sheet).filter(item=>/^B/.test(item)&&item!=="B1").forEach(key=>{sheet[key].t="d";})但是如果工卡的有效期为空,此时导出,打开Excel会报错,空位会变成NaN。看了各种中英文文档和Issues,导出了一个100多张员工信息表后,发现Excel真的很牛逼,也许导入的数据应该在js上格式化,而不是限制单元格的类型。如果不控制单元格类型,那么当管理员输入日期时,单元格可能是:文本、常规、日期、自定义类型,所以只要保证程序无论格式如何都能得到正确的值cell的数据就好了。当管理员使用的工作卡有效期的cell类型为text或regular时,比较简单。程序可以按照预期解析出一个对应的字符串,使用moment解析得到想要格式的数据。.那么当有效期单元格的类型为date和custom时,我们得到的数据如下图。这就是之前数据库中奇怪号码的由来。这个数字的含义其实就是当前日期距离1900年1月0日的天数。另外需要注意的是,Excel中有个bug:它认为1900年是闰年,所以数days得到的会多一天,因为转换前要减去一天...item.Employmentcardvalidityperiod=newDate(1900,0,expried-1)那么后面就可以得到正确的日期了。古迹。
