加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

利用perl计算考勤表并且输出excel表格

发布时间:2020-12-16 00:18:17 所属栏目:大数据 来源:网络整理
导读:? 需要处理的excel的格式如下 ? 转换器代码如下(防止中文乱码)(作者为:flw): ? package?MyExcelFormatter;? use?strict;? use?warnings;? use?base?qw(Spreadsheet::ParseExcel::FmtDefault);? use?Encode::CN;? use?Encode?qw(from_to);? sub?new()?{? ?

?需要处理的excel的格式如下

?

转换器代码如下(防止中文乱码)(作者为:flw):

?

 
 
  1. package?MyExcelFormatter;?
  2. use?strict;?
  3. use?warnings;?
  4. use?base?qw(Spreadsheet::ParseExcel::FmtDefault);?
  5. use?Encode::CN;?
  6. use?Encode?qw(from_to);?
  7. sub?new()?{?
  8. ????return?bless?{};?
  9. }?
  10. sub?TextFmt(?$;$?)?{?
  11. ????my?$this?=?shift;?
  12. ????my?($value,?$code)?=?@_;?
  13. ????if?(?defined?$code?and?$code?eq?'ucs2'?){?
  14. ????????from_to(?$value,?'ucs2',?'gb2312'?);?
  15. ????}?
  16. ????return?$value;?
  17. }?
  18. 1;?

将上面的代码复制到你的perl ?lib库下 命名为MyExcelFormatter.pm
还需要安装的模块有:
Spreadsheet::ParseExcel(读取execl模块)
Excel::Writer::XLSX(导出excel所用,支持2007)
安装方法:
win下:
ppm install 模块名
?
主程序:
?
 
 
  1. #!/usr/bin/perl?
  2. use?strict;?
  3. use?warnings;?
  4. use?Spreadsheet::ParseExcel;?
  5. use?MyExcelFormatter;??#flw大神写的中文转化模块。?
  6. use?Data::Dumper;?
  7. use?Time::Local;?
  8. use?POSIX?qw{strftime};?
  9. use?Excel::Writer::XLSX;?
  10. use?Encode?;?
  11. sub?H{?
  12. ????my?$text?=?shift;?
  13. ????return??decode('gb2312',$text);??#?进行转码?
  14. }?
  15. my?(%hash,%mon);?
  16. my?$fmt?=?new?MyExcelFormatter();?
  17. my?$file?=?'kaoqin.xls';?
  18. my?$xls?=?Spreadsheet::ParseExcel::Workbook->Parse(?$file,?$fmt?);?
  19. my?@workSheet?=?@{?$xls->{Worksheet}?};?
  20. open??FH,">douzi.txt"?or?die?"$!";?
  21. foreach?my?$sheet?(?@workSheet?){?
  22. ????my?$sheetName?=?$sheet->get_name();?
  23. ????my?(?$minRow,?$maxRow?)?=?$sheet->row_range();??#索引所有的行?
  24. ????my?(?$minCol,?$maxCol?)?=?$sheet->col_range();???#索引所有的列?
  25. ????foreach?my?$row?(?1?..?$maxRow?){???????????#此处的行?从第二行开始?
  26. ????????my?$tmp;?
  27. ????????foreach?my?$col?(?$minCol?..?$maxCol?){?
  28. ????????????my?$cell?=?$sheet->get_cell(?$row,?$col?);?
  29. ????????????next?unless?$cell;?
  30. ????????????????$tmp?.=?$cell->value."?";?
  31. ????????}????????
  32. ????????my($name,$date,$time)?=?(split/s+/,$tmp)[1,3,4];???#提取姓名,日期,时间?
  33. ???????"$date?$time"?=~?/(d+)-(d+)-(d+)s+(d+):(d+):(d+)/;?????
  34. ????my?$time_unix?=?timelocal($6,$5,$4,$3,$2-1,$1);?
  35. ????my?$time_9clock?=?timelocal(0,30,9,$1);?
  36. ????push?@{$hash{$name}{$date}},$time_unix,$time_9clock;?
  37. ????$mon{$date}++;???#此处可以自己定义上班的时间%mon;我这里直接读取了一个月所有的时间。?
  38. }?
  39. }?
  40. my?$workbook?=?Excel::Writer::XLSX->new('test.xlsx');??#准备写入excel?
  41. map{?my?$name=$_;my?$num=1;?
  42. ???my??$worksheet?=?$workbook->add_worksheet(H($name));??#以每个人作为一个工作簿?
  43. ???$worksheet->write_row("B1",[H('上班时间'),H('下班时间'),H('工作时间')]);?
  44. ????for?(map{$_->[0]}sort{$a->[2]?<=>?$b->[2]||$a->[3]?<=>$b->[3]}map{[$_,split/-/]}keys?%mon){?
  45. ????????#按照日期时间排序?
  46. ????????my?@arr;?
  47. ????????$num++;??#定义行号?
  48. ????????push?@arr,$_;?
  49. ?????????if?(defined($hash{$name}{$_}->[0])){?
  50. ????????if($hash{$name}{$_}->[0]?>=?$hash{$name}{$_}->[-1]){??#定义早晨打卡时间,如果大于则记为迟到?
  51. ????????????push?@arr,H("迟到");?
  52. ????????}else{?
  53. ????????????push?@arr,strftime("%Y-%m-%d?%H:%M:%St",localtime($hash{$name}{$_}->[0]));??
  54. ????????}?
  55. ????????my??$work_night?=?strftime("%Y-%m-%d?%H:%M:%St",localtime($hash{$name}{$_}->[-2]));?#定义下班时间?
  56. ????????my?$work_time?=?$hash{$name}{$_}->[-2]-$hash{$name}{$_}->[0];#时间戳计算?
  57. ????????my?$work_hours?=??$work_time/3600;???#工作时间长度?
  58. ????????if($work_time<32400?and?$work_time>0){??#如果少于工作的时间则为早退?
  59. ????????????push?@arr,$work_night;?
  60. ??????????????push?@arr,H(sprintf("早退,实际工作时间:%2.1fn",$work_hours));?
  61. ????????}elsif($work_time?==?0?and?$hash{$name}{$_}->[-2]<($hash{$name}{$_}->[-1]+10800)?){??
  62. ???????????#如果一天只打了一次卡,且在早晨12点之前打过卡,则定义为下班未打卡?
  63. ????????????push?@arr?,H('下班未打卡');?
  64. ????????}?
  65. ????????else{?
  66. ????????????push?@arr,$work_night;?
  67. ????????????push?@arr,H(sprintf("%2.1fn",$work_hours));?
  68. ????????}?
  69. ?????????}else{?
  70. ????????????push?@arr,H('缺勤');??#没有打过一次卡的记为缺勤?
  71. ?????????}?
  72. ?????????$worksheet->write_row("A$num",@arr);?
  73. ????}?
  74. ????}keys?%hash;?
  75. close?FH;?

输出excel

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读