导出来的考勤信息表(只是获取打卡信息并处理成报表.xlsx , 初始的表格没了) 下图是 “报表.xlsx 

打卡记录表怎么命名 java_数组

看起来乱糟糟的,虽然能看但是需要花费大量的精力去处理才能成标准表格,下面我直接上代码(代码里已有注释)



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)

打卡记录表怎么命名 java_卡时间_02

如果有大牛路过发现代码错误,希望能指出好让小弟学习,要是有更好的处理方式能够告诉小弟,不胜感激。