zoukankan      html  css  js  c++  java
  • 用 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)

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

  • 相关阅读:
    C语言左移和右移
    mmap详谈
    eclipse插件自动生成类图
    async 和 defer 的区别
    SVN里恢复到某一天的版本操作
    解决跨域的jsonp+Java实例
    HTTP请求行、请求头、请求体等
    ajax在什么情况下会走success和error
    记阅读POST与GET的区别
    记一些快捷键
  • 原文地址:https://www.cnblogs.com/webBlog-gqs/p/11177594.html
Copyright © 2011-2022 走看看