导出来的考勤信息表(只是获取打卡信息并处理成报表.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:\excel
node xls.js
这里附上处理好的图 (注:上班时间 10:00-12:30,14:00-19:00)
如果有大牛路过发现代码错误,希望能指出好让小弟学习,要是有更好的处理方式能够告诉小弟,不胜感激。