导出来的考勤信息表(只是获取打卡信息并处理成报表.xlsx , 初始的表格没了) 下图是 “报表.xlsx”
看起来乱糟糟的,虽然能看但是需要花费大量的精力去处理才能成标准表格,下面我直接上代码(代码里已有注释)
const xlsx = require('node-xlsx');const fs = require('fs');// 获取 xlsx 表格中的数据let arr = xlsx.parse('./报表.xlsx')[0].data;// 工号信息集合let jobArr = [];// 打卡时间集合let timeArr = [];// 打卡日期集合let dateArr = [];// xlsx 留出日期字段作为第一列,方便提取出日期arr[0].forEach(val => {if ('日期' !== val) {dateArr.push(val);}})for (let item of arr.slice(1)) {// 有数据if (item.length) {// 工号和姓名信息let numArr1 = [];// 打卡时间let numArr2 = [];if ('工 号:' === item[1]) {for (let v = 0; v < item.length; v++) {if ('工 号:' === item[v]) {numArr1.push('number');} else if ('姓 名:' === item[v]) {numArr1.push('name');} else if (null !== item[v]) {numArr1.push(item[v]);}}jobArr.push(numArr1);} else {for (let it = 1; it < item.length; it++) {if (item[it]) {numArr2.push(item[it]);} else {numArr2.push(' ');}}timeArr.push(numArr2);}} else {// 打卡时间无打卡时间记录给此行赋值空数组 timeArr.push([[]]);}}// 工号信息进一步处理成 json 格式,方便后面使用let arr1 = [];for (let attr of jobArr) {let obj = {};for (let t = 0; t < attr.length; t++) {if ('number' === attr[t]) {obj['number'] = attr[t + 2];} else if ('name' === attr[t]) {obj['name'] = attr[t + 2];}}arr1.push(obj);}// 将上面的工号信息复制一份来与打卡时间处理成一个新的打卡集合let tempArr = [...arr1];timeArr.forEach((t, idx) => {let startTime = [];let endTime = [];t.forEach(k => {if (5 === k.length) {// 打卡时间只有一个,归为下班忘记打卡 -> 这部分人事在检查生成 xlsx 进行核对startTime.push(k);endTime.push(' ');} else if (10 === k.length) {// 有上下班打卡记录startTime.push(k.substr(0, 5));endTime.push(k.substr(5, 5));} else if (10 < k.length) {// 多次打卡记录,下班打卡按最后一次打卡为准startTime.push(k.substr(0, 5));endTime.push(k.substr(k.length - 5, 5));} else {// 无打卡记录startTime.push(' ');endTime.push(' ');}})tempArr[idx]['startTime'] = startTime;tempArr[idx]['endTime'] = endTime;})let array1 = [];tempArr.forEach((val, index) => {let arrlen = [];// 将日期与每个人的打卡信息对应起来for (let a = 0; a < dateArr.length; a++) {let obj11 = {date: dateArr[a],number: val.number,name: val.name,start: val.startTime[a] || '',end: val.endTime[a] || '',}arrlen.push(obj11);}array1.push(arrlen);})let zs = [];for (let a = 0; a < dateArr.length; a++) {let tt = [];for (let b = 0; b < array1.length; b++) {array1[b].forEach((v, i) => {if (a === i) { // 同一日期下的不同工号打卡时间存到 tt 数组 tt.push(v);}})}// 将同一日期打卡按照时间前后存放到 zs zs.push(tt);}// xls 表格格式var temp2 = [];// 表头temp2.push(['日期','姓名','上班时间','下班时间','备注',])// 表格的格式是多维数组需要在之前的格式进行处理zs.forEach((v1) => {v1.forEach(v2 => {let temp1 = []temp1.push(v2.date)temp1.push(v2.name)let start = '';let end = '';if (v2.start) {start = v2.start;}if (v2.end) {end = v2.end;}temp1.push(start)temp1.push(end)temp1.push('')temp2.push(temp1)})})// 单元格的名称var data = [{name: '打卡考勤',}]data[0]['data'] = temp2;var buffer = xlsx.build(data);fs.writeFile('./考勤.xls', buffer, function (err) {if (err)throw err;});
这里有几个点需要说明一下, 那张导出的考勤表需要处理一下成上面第一张图一样的格式,即第一列写上日期,然后第一列开始放置考勤表里的数据 -> 报表.xlsx
可以直接 node xls.js
这里我是 windows 系统,所以写了一个 bat (由于我把代码放在 D 盘的 excel 目录下)
D:D:\excelnode xls.js
这里附上处理好的图 (注:上班时间 10:00-12:30,14:00-19:00)
如果有大牛路过发现代码错误,希望能指出好让小弟学习,要是有更好的处理方式能够告诉小弟,不胜感激。
如果觉得《用 node-xlsx 将从打卡机中导出的考勤信息处理生成考勤表》对你有帮助,请点赞、收藏,并留下你的观点哦!