首页 » 后端 » PHP » 正文

将指纹打卡考勤机源数据转换为Excel考勤表(含源程序)

发布者:站点默认
2015/08/12 浏览数(7,029) 分类:PHP 将指纹打卡考勤机源数据转换为Excel考勤表(含源程序)已关闭评论

说明:

指纹打卡考勤机每天的打卡记录类似:09:00 12:00 13:19 18:06,这个程序可以判断上午和下午是否正常打卡并生成考勤表。

只支持导入和导出 xls 后缀的 Excel97-2003 的文件,如果需要支持 Excel2007 的 xlsx 文件可以改程序源码中的 Excel5 为 Excel2007。

以实用为主无美感的界面:

zhuanhuankaoqinshuju_interface

下载地址在演示页面左上角。PHP语言,不需要数据库。

考勤机导出的 xls 文件:

中心款考勤机导出的源数据:

kaoqinshuju_20150714

科大款考勤机导出的源数据:

kaoqinshuju_keda_20150714

项目部款考勤机的源数据:

kaoqinshuju_xianmu_20150714

程序生成的最后生成的考勤表:

kaoqinbiao_20150714

一些判断标准:

迟到超过一个小时后半天按未上班,早退超过一个小时半天也不计(不计:按未上班计、不计为上过班)

当天只打了一次卡的不计,只在上班前了N次的不计,只在中午打了N次的不计,只在下班后打了N次的不计

上午正常打卡,中午打了N次,下午和下午下班未打的,不计下午

中午打了N次,下午下班打过,但是上午没打的,不计上午

上午正常打卡,中午打了一次,下午下班打了一次时,中午那次计为上午下班卡、下午未打上班卡

效果:

08:14 12:00 13:19 18:06 // output: √ √
08:06 08:20 // output: 休 休
12:06 12:20 // output: 休 休
18:06 18:20 // output: 休 休
08:06 18:20 // output: 未退 未签
09:00 12:00 13:19 18:06 // output: 迟到 √
09:00 11:00 13:19 18:06 // output: 迟到 未签
11:00 13:19 13:20 18:06 // output: 休 √
08:00 11:19 13:20 18:06 // output: √ 未签
09:00 11:19 14:20 17:06 // output: 迟到早退 迟到早退
09:00 11:00 13:19 18:06 // output: 迟到 未签
13:19 18:06 // output: 休 √
08:19 08:19 08:19 12:02 18:06 18:06 18:06 // output: √ 未签

判断当天的打卡记录是否符合标准的函数代码:

function getSignRs($str=''){
	global $amStart,$amEnd,$pmStart,$pmEnd;
	$maxLateTime = 3600; // 最大迟到和早退时间:秒
	$rs = array('AM'=>'','PM'=>'');
	$str = trim($str);
	$str = preg_replace('/\s+/', '#',$str);
	$record = explode('#', $str);
	// $record = array_unique($record); // 1分钟内多条记录合为1条(不使用该功能的原因是允许中午1分钟内按两次:一次下班,一次上班)
	$totalRecord = count($record);
	if($totalRecord < 2) return $rs; // 只有一条记录时按当天未上班计

	if(!$amStart) $amStart = strtotime('09:00');
	if(!$amEnd  ) $amEnd   = strtotime('12:00');
	if(!$pmStart) $pmStart = strtotime('14:00');
	if(!$pmEnd  ) $pmEnd   = strtotime('18:00');
	$amRecord = $noonRecord = $pmRecord = array();
	$beforeAm = $noon = $afterPm = 0; // 早上、中午、晚上的打卡次数

	// 筛选记录到 上午 中午 下午
	foreach ($record as $r) {
		$ts = strtotime($r);
		if($ts < $amEnd) {
			if($ts <= $amStart){ // 只记录一个上班前的记录
				if(0 == $beforeAm){
					$amRecord[] = $r;
				}
				$beforeAm++;
			}else{
				$amRecord[] = $r;
			}
		}
		if($ts >= $amEnd && $ts <= $pmStart){
			if($noon <= 2) $noonRecord[] = $r; // 只记录2个中午的记录
			$noon++;
		}
		if($ts > $pmStart){
			if($ts >= $pmEnd){ // 只记录一个下班后的记录
				if(0 == $afterPm){
					$pmRecord[] = $r;
				}
				$afterPm++;
			}else{
				$pmRecord[] = $r;
			}
		}
	}

	if($totalRecord == $noon)     return array('AM'=>'休','PM'=>'休'); // 全部是中午打的卡:无视
	if($totalRecord == $beforeAm) return array('AM'=>'休','PM'=>'休'); // 全部是上班前打的卡:无视
	if($totalRecord == $afterPm)  return array('AM'=>'休','PM'=>'休'); // 全部是下班后的卡:无视

	// 将中午的记录分给上午和下午
	if(!empty($noonRecord)){
		$i = 1;
		foreach ($noonRecord as $r) {
			if(1 == $i && !empty($amRecord)) // 第一条分给上午,第2条给下午,其它的扔掉
				$amRecord[] = $r;
			else
				array_unshift($pmRecord,$r);
			$i++;
			if($i > 2) break;
		}
	}
	// t:total s:start e:end
	// 上午的打卡结果
	if($amRecord){
		$t = count($amRecord);
		$s = strtotime($amRecord[0]);
		$e = strtotime($amRecord[$t-1]);
		if(0 == $t){
			$rs['AM'] = '';
		}else if(1 == $t){
			if($s <= $amStart){
				if( count($pmRecord) == 1 && isset($pmRecord[0]) && strtotime($pmRecord[0]) < $pmEnd)
					$rs['AM'] .= '√'; // 上午打一次,下午在下班前打了一次
				else $rs['AM'] .= '未退';
			}
			if($s >  $amStart && $s < $amEnd) $rs['AM'] .= ''; // 迟到未退
			if($s >= $amEnd)   $rs['AM'] .= ''; // 未签 或 中午打了N次,上午没上班
		}else{
			if($s > $amStart && $s <= $amStart + $maxLateTime) $rs['AM'] .= '迟到';
			if($e < $amEnd   && $e >= $amEnd   - $maxLateTime) $rs['AM'] .= '早退';
			if($s > $amStart + $maxLateTime) $rs['AM'] = '休'; // 太晚签到(迟到超过1小时)
			if($e < $amEnd   - $maxLateTime) $rs['AM'] = '休'; // 太早签退(距离下班超过1小时)
			if(empty($rs['AM']))   $rs['AM'] .= '√';
		}
	}
	// 下午的打卡结果
	if($pmRecord){
		$t = count($pmRecord);
		$s = strtotime($pmRecord[0]);
		$e = strtotime($pmRecord[$t-1]);
		if(0 == $t){
			$rs['PM'] = '';
		}else if(1 == $t){
			if($s >  $pmStart && count($noonRecord) >= 2)
				$rs['PM'] = ''; // 迟到未退
			if($s >= $pmEnd)   $rs['PM'] = '未签'; // 不能和上条行换位
			if($s <= $pmStart) $rs['PM'] = ''; // 未退 或 中午多次下午未上班
		}else{
			if($s > $pmStart && $s <= $pmStart + $maxLateTime)    $rs['PM'] .= '迟到';
			if($e < $pmEnd   && $e >= $pmEnd   - $maxLateTime)    $rs['PM'] .= '早退';
			if($s > $pmStart + $maxLateTime) $rs['PM'] = ''; // 太晚签到(迟到超过1小时)
			if($e < $pmEnd   - $maxLateTime) $rs['PM'] = ''; // 太早签退(距离下班超过1小时)
			if(empty($rs['PM'])) $rs['PM'] .= '√';
		}
	}
	if(empty($rs['AM'])) $rs['AM'] = '休';
	if(empty($rs['PM'])) $rs['PM'] = '休';
	return $rs;
}

# 完 #

更新:v2.0版 可以处理多个部门(多个考勤机)。

点击返回顶部
  1. 留言
  2. 联系方式