導出來的考勤信息表(只是獲取打卡信息並處理成報表.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