用 node-xlsx 將從打卡機中導出的考勤信息處理生成考勤表

導出來的考勤信息表(只是獲取打卡信息並處理成報表.xlsx , 初始的表格沒了) 下圖是 「報表.xlsx node

看起來亂糟糟的,雖然能看可是須要花費大量的精力去處理才能成標準表格,下面我直接上代碼(代碼裏已有註釋)json

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;
}
);

這裏有幾個點須要說明一下, 那張導出的考勤表須要處理一下成上面第一張圖同樣的格式,即第一列寫上日期,而後第一列開始放置考勤表裏的數據 -> 報表.xlsxwindows

能夠直接 node xls.js 數組

這裏我是 windows 系統,因此寫了一個 bat (因爲我把代碼放在 D 盤的 excel 目錄下)學習

D:
D:\excel
node xls.js  

這裏附上處理好的圖 (注:上班時間 10:00-12:30,14:00-19:00)ui

若是有大牛路過發現代碼錯誤,但願能指出好讓小弟學習,要是有更好的處理方式可以告訴小弟,不勝感激。spa

相關文章
相關標籤/搜索