用 node-xlsx 将从打卡机中导出的考勤信息处理生成考勤表

Posted webblog-gqs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用 node-xlsx 将从打卡机中导出的考勤信息处理生成考勤表相关的知识,希望对你有一定的参考价值。

导出来的考勤信息表(只是获取打卡信息并处理成报表.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)

技术图片

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

以上是关于用 node-xlsx 将从打卡机中导出的考勤信息处理生成考勤表的主要内容,如果未能解决你的问题,请参考以下文章

c++中导出的def文件要怎么修改

如何用 python 做一个考勤系统

有啥比较好的微信小程序考勤打卡的软件么?

考勤信息(员工打卡)

从钉钉后台对接考勤打卡信息(仅供参考)

从钉钉后台对接考勤打卡信息(仅供参考)