利用perl計算考勤表而且輸出excel表格

 須要處理的excel的格式以下sql

 

轉換器代碼以下(防止中文亂碼)(做者爲:flw):less

 

  
  
  
  
  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. sub TextFmt( $;$ ) { 
  10.     my $this = shift; 
  11.     my ($value, $code) = @_; 
  12.     if ( defined $code and $code eq 'ucs2' ){ 
  13.         from_to( $value, 'ucs2''gb2312' ); 
  14.     } 
  15.     return $value; 
  16. 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. my (%hash,%mon); 
  15. my $fmt = new MyExcelFormatter(); 
  16. my $file = 'kaoqin.xls'
  17. my $xls = Spreadsheet::ParseExcel::Workbook->Parse( $file, $fmt ); 
  18. my @workSheet = @{ $xls->{Worksheet} }; 
  19. open  FH,">douzi.txt" or die "$!"
  20. foreach my $sheet ( @workSheet ){ 
  21.     my $sheetName = $sheet->get_name(); 
  22.     my ( $minRow, $maxRow ) = $sheet->row_range();  #索引全部的行 
  23.     my ( $minCol, $maxCol ) = $sheet->col_range();   #索引全部的列 
  24.     foreach my $row ( 1 .. $maxRow ){           #此處的行 從第二行開始 
  25.         my $tmp; 
  26.         foreach my $col ( $minCol .. $maxCol ){ 
  27.             my $cell = $sheet->get_cell( $row, $col ); 
  28.             next unless $cell; 
  29.                 $tmp .= $cell->value." "
  30.         }        
  31.         my($name,$date,$time) = (split/\s+/,$tmp)[1,3,4];   #提取姓名,日期,時間 
  32.        "$date $time" =~ /(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)/;     
  33.     my $time_unix = timelocal($6,$5,$4,$3,$2-1,$1); 
  34.     my $time_9clock = timelocal(0,30,9,$3,$2-1,$1); 
  35.     push @{$hash{$name}{$date}},$time_unix,$time_9clock; 
  36.     $mon{$date}++;   #此處能夠本身定義上班的時間%mon;我這裏直接讀取了一個月全部的時間。 
  37. my $workbook = Excel::Writer::XLSX->new('test.xlsx');  #準備寫入excel 
  38. map{ my $name=$_;my $num=1; 
  39.    my  $worksheet = $workbook->add_worksheet(H($name));  #以每一個人做爲一個工做簿 
  40.    $worksheet->write_row("B1",[H('上班時間'),H('下班時間'),H('工做時間')]); 
  41.     for (map{$_->[0]}sort{$a->[2] <=> $b->[2]||$a->[3] <=>$b->[3]}map{[$_,split/-/]}keys %mon){ 
  42.         #按照日期時間排序 
  43.         my @arr; 
  44.         $num++;  #定義行號 
  45.         push @arr,$_; 
  46.          if (defined($hash{$name}{$_}->[0])){ 
  47.         if($hash{$name}{$_}->[0] >= $hash{$name}{$_}->[-1]){  #定義早晨打卡時間,若是大於則記爲遲到 
  48.             push @arr,H("遲到"); 
  49.         }else
  50.             push @arr,strftime("%Y-%m-%d %H:%M:%S\t",localtime($hash{$name}{$_}->[0]));  
  51.         } 
  52.         my  $work_night = strftime("%Y-%m-%d %H:%M:%S\t",localtime($hash{$name}{$_}->[-2])); #定義下班時間 
  53.         my $work_time = $hash{$name}{$_}->[-2]-$hash{$name}{$_}->[0];#時間戳計算 
  54.         my $work_hours =  $work_time/3600;   #工做時間長度 
  55.         if($work_time<32400 and $work_time>0){  #若是少於工做的時間則爲早退 
  56.             push @arr,$work_night; 
  57.               push @arr,H(sprintf("早退,實際工做時間:%2.1f\n",$work_hours)); 
  58.         }elsif($work_time == 0 and $hash{$name}{$_}->[-2]<($hash{$name}{$_}->[-1]+10800) ){  
  59.            #若是一天只打了一次卡,且在早晨12點以前打過卡,則定義爲下班未打卡 
  60.             push @arr ,H('下班未打卡'); 
  61.         } 
  62.         else
  63.             push @arr,$work_night; 
  64.             push @arr,H(sprintf("%2.1f\n",$work_hours)); 
  65.         } 
  66.          }else
  67.             push @arr,H('缺勤');  #沒有打過一次卡的記爲缺勤 
  68.          } 
  69.          $worksheet->write_row("A$num",\@arr); 
  70.     } 
  71.     }keys %hash; 
  72. close FH; 

輸出excelide

 

相關文章
相關標籤/搜索