Excel::Writer::XLSX 的应用

use 5.010;
use strict;  
# use warnings;  
use Spreadsheet::XLSX;  
use Excel::Writer::XLSX;
use MyExcelFormatter;
use Encode;
use HTML::TokeParser;
use Data::Dumper;
use Mojo::UserAgent;
use Mojo::UserAgent::CookieJar;
use Mojo::UserAgent::Proxy;
use YAML 'Dump';
use Win32::API;

#获取当天的日期,作为后面 Excel 的行首
sub getTime
{
    my $time = shift || time();
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);

    $year += 1900;
    $mon ++;

    $min  = '0'.$min  if length($min)  < 2;
    $sec  = '0'.$sec  if length($sec)  < 2;
    $mon  = '0'.$mon  if length($mon)  < 2;
    $mday = '0'.$mday if length($mday) < 2;
    $hour = '0'.$hour if length($hour) < 2;
    
    my $weekday = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$wday];

    return { 'second' => $sec,
             'minute' => $min,
             'hour'   => $hour,
             'day'    => $mday,
             'month'  => $mon,
             'year'   => $year,
             'weekNo' => $wday,
             'wday'   => $weekday,
             'yday'   => $yday,
             'date'   => "$year-$mon-$mday"
          };
}

my $date = getTime();  
my $today = $date->{date};                          # 获取xxxx-xx-xx这样的日期
#my $month = $date->{month};                        # 获取月
#my $day = $date->{day};                            # 获取日
#my $year = $date->{year};                          # 获取年
#my $weekday = $date->{wday};                       # 获取星期
my $yesterday = getTime(time() - 86400)->{date};   # 获取昨天的日期,也可以用 86400*N,获取N天前的日期

sub H{
my $text = shift;
return  decode('utf8',$text);  # 进行转码
}
##################################################
#                 删除旧文件                     #
##################################################

foreach my $file (grep {/客户端运行日志/ or /运维操作平台/} glob "*.xls") { 
say "删除文件:$file";
unlink  "$file";
}

my $client_log_file = "客户端运行日志".$today.".htm.xls";
my $yesterday_file  = 'Finished上传跟进情况'.$yesterday.'.xlsx';
my $yunwei_file     = "运维操作平台".$today.".htm.xls";

##################################################
#                 下载日志文件                    #
##################################################

my $proxy = Mojo::UserAgent::Proxy->new;
$proxy->detect;
say $proxy->http;


# 需要下载 AdvOcr

# 这个版本是可以的,因为有时候要输入验证码,所以有时不行
my $ua   = Mojo::UserAgent->new;
my $http = $proxy->http;
my $ua_proxy      = $proxy->http('http://192.168.1.158:8080');
my $response = $ua->get('https://gskrx.windms.com/commons/image.jsp');

 if ($response->success) {
     # 抓取验证码图片 #
$response->res->content->asset->move_to('verifycode.BMP'); # 不能含中文?


 # # 输入验证码并登录 #
# print "--> enter verifycode:";

# chomp( my $verifycode = <> );
# $verifycode=~ s/\s//g; #删除空白

my $dll={};
my $D='AdvOcr.dll';
$dll->{OcrInit} = Win32::API->new($D, 'OcrInit',[],'N') || die " Can't open the dll file $D $!";

$dll->{OCR_C} = Win32::API->new($D, 'OCR_C',['P','P'],'P');
if($dll->{OcrInit}->Call()){
my $ocr_txt=$dll->{OCR_C}->Call('163_esales','verifycode.BMP');
    print "结果:$ocr_txt\n";
# }

# 163_esales 就是使用哪个字模库
# 作者做了很多现成的字模,只要更换这个参数,就可以识别其他类型的验证码
# 具体参数,看OCRtypedef.ini文件,里面有28种字模

my $login_url  = "https://gskrx.windms.com/login.do";
my $post_form = {
       'rand' => "$ocr_txt",
       'anchor'       =>"",
       'userAccount'  =>'winc_sxw',
       'userPassword' =>'000000',

    };

  
    my $tx = $ua->post( $login_url => form => $post_form );
if ( $tx->success ) {
    if ($tx->res->body !~ /验证码输入错误/) {
    
my $query_form= {
'colIds' => '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,48,43,44,45,46,47',
'reportName' => '../listview/platform/server/dmsRunLogListView',
'tableId'=> 'dmsRunLogListView',
'uploadResult'=>'2',
'loadResult'=>'2',
'uploadDate1'=>"$today",
'uploadDate2'=>"$today",
'dmsRunLogListView_rd'=>'200',
'_RES_ID_'=>'156',
'ec_i'=>'dmsRunLogListView',
'ec_eti'=>'dmsRunLogListView',
'dmsRunLogListView_ev'=>'htm',
'dmsRunLogListView_efn'=>'客户端运行日志.htm.xls',
'dmsRunLogListView_crd'=>'200',
'dmsRunLogListView_p'=>'1',
};

my $yunwei_query_form = {
'_RES_ID_'=>'236',
'colIds'=>'0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,36,37',
'delayDay'=>'2',
'ec_eti'=>'helpDesk',
'ec_i'=>'helpDesk',
'FILE_EXPORT_TOKEN_PARAM_NAME'=>'1393911174875',
'helpDesk_crd'=>'200',
'helpDesk_efn'=>'运维操作平台.htm.xls',
'helpDesk_ev'=>'htm',
'helpDesk_p'=>'1',
'helpDesk_rd'=>'200',
'reportName'=>'helpDesk',
'saleDelayDay'=>'0',
};

# 'FILE_EXPORT_TOKEN_PARAM_NAME'=>'1392799287157'
# URL 要经过解码才能POST
my $client_file='客户端运行日志'.$today.'.htm.xls';

my  $tx=$ua->post('https://gskrx.windms.com/report/listReport.do' => form => $query_form );
$tx->res->content->asset->move_to($client_file); # 不能含中文?

my $yunwei_tx =$ua->post('https://gskrx.windms.com/report/listReport.do' => form => $yunwei_query_form);
$yunwei_tx->res->content->asset->move_to($yunwei_file); #

}
}
}
}
##################################################
#                检测是否下载到                  #
##################################################


my @files_needed =($client_log_file,$yesterday_file,$yunwei_file);
foreach my $file (@files_needed){
   print "[不存在] -> $file \n" if not -e $file;
}

exit   if not -e "运维操作平台".$today.".htm.xls";
exit   if not -e "客户端运行日志".$today.".htm.xls";
exit   if not -e 'Finished上传跟进情况'.$yesterday.'.xlsx';

my $parser = HTML::TokeParser->new($yunwei_file)
    or die "Can't open $yunwei_file: $!\n";
    
    
my (@table, @row, $inrow);
while (my $token = $parser->get_token( )) {
    my $type = $token->[0];
    if ( $type eq 'T' ) {
        push @row, $token->[1] if $inrow;
    }
    elsif ( $type eq 'S' ) {
        if ( $token->[1] eq 'tr' ) {
            $inrow = 1;
        }
    }
    elsif ( $type eq 'E' ) {
        if ( $token->[1] eq 'tr' ) {
            push @table, [@row]; # 注意这一行不能用 @row
            @row = ();
            $inrow = 0;
        }
    }
}
my @temp;
my %client_code;
foreach my $ele (@table) {
   my $string=join "", $ele->[10],$ele->[12],$ele->[14],"\n";
   $string=~s/\s+$//g;
   # print $ele->[3];
   push @temp, $string if $string;
   $client_code{$ele->[3]} =  $string;
}
delete $client_code{'客户端编码'};
# print Dumper(%client_code);



################################################################################################
# 这里先提取客户端运行日志里的经销商编码,作为 Excel中 Vlookup函数的 table_array
################################################################################################

################################################################################################
# 这里需要准备的文件有3个,昨天的上传跟进情况,今天的客户端运行日志
################################################################################################


open my $fh,"<",$client_log_file or die $!;  #客户端运行日志2014-01-05.htm.xls
my @array;
my %has_seen;
while(<$fh>) {
     $has_seen{$1}=1 if /<td class="tsc" >(\d{7,})<\/td>/;
}

foreach my $key (keys %has_seen) {
        push @array,$key;
}
close $fh;

my $workbook   =  Excel::Writer::XLSX->new( "上传跟进情况".$today.".xlsx" );
my $format     = $workbook->add_format( 
           align      => 'center',
           font       => H('微软雅黑'),
           size       => 9 ,
           num_format => '@' 
           );
           
my $time_format     = $workbook->add_format( align => 'center', num_format => 'h:mm',        font => H('微软雅黑'), size => 9);
my $date_format     = $workbook->add_format( align => 'center', num_format => 'yyyy/mm/dd',  font => H('微软雅黑'), size => 9);
my $filter_format_Y = $workbook->add_format( align => 'center', bg_color   => '#16a951');
my $filter_format_N = $workbook->add_format( align => 'center', bg_color   => 'red', );

# set_column( $first_col, $last_col, $width, $format, $hidden, $level, $collapsed )
   
# 读取一个Excel 的内容到另外一个新建的工作簿中,其实就是复制原来的 Excel 文件     
my $excel          =  Spreadsheet::XLSX -> new ('Finished上传跟进情况'.$yesterday.'.xlsx');

foreach my $old_sheet( @{$excel -> {Worksheet}}[0] ) {  # 只读取前两张工作表,直链安装
        my @columns; 
        my $new_worksheet  =  $workbook->add_worksheet(H($old_sheet->{Name}));  # 将原来的工作表名添加到新的 Excel
        $old_sheet -> {MaxCol} ||= $old_sheet -> {MinCol};  #|| 逻辑或,返回计算结果先为真的值,由左到右计算
        my $temp=$old_sheet -> {MaxCol}+65;  # 今天最大列数是10,今天结束会增加一列,列数变成11,自增1,将数字转换为对应的字母
        my $cell_today=chr($temp+1);

       # 写入新 Excel 文件前,先设置新 Excel 的单元格格式 
       $new_worksheet->set_column( 'A:A', 8.38,$format );
       $new_worksheet->set_column( 'B:B', 10.38,$format);
       $new_worksheet->set_column( 'C:D', 25 ,$format);
       $new_worksheet->set_column( 'F:F', 15, $time_format );
       $new_worksheet->set_column( 'G:G', 25 ,$date_format);
       $new_worksheet->set_column( 'E:E', 15, $format ); 
       $new_worksheet->set_column( "J:$cell_today", 15, $date_format ); 
       
# 读取原 Excel,然后写入 新 Excel        
foreach my $col ($old_sheet -> {MinCol} .. $old_sheet -> {MaxCol}) {
                $old_sheet -> {MaxRow} ||= $old_sheet -> {MinRow}; 
                foreach my $row ($old_sheet -> {MinRow} ..  $old_sheet -> {MaxRow}) {  
                        push @{$columns[$col]},H($old_sheet -> {Cells} [$row] [$col]->{Val});
                        }
                 $new_worksheet->write_row( 'A1', \@columns);
                }


$new_worksheet->write( $cell_today."1",$today,$date_format); # header,为每天的日期

shift  @{$columns[1]}; 
chomp @{$columns[1]};
my @custom=map {s/\s+//g;$_} @{$columns[1]};
shift @{$columns[4]};
my @source_client =map {s/\s+//g;$_} @{$columns[4]};
{no warnings;
foreach my $i ($old_sheet -> {MinRow}+2..$old_sheet -> {MaxRow}+1) {
        $new_worksheet->write( 'F'.$i, $source_client[$i-2] ~~ %client_code ? decode("gb2312",$client_code{$source_client[$i-2]}):"N");
    }

foreach my $i ($old_sheet -> {MinRow}+2..$old_sheet -> {MaxRow}+1) {
        $new_worksheet->write( $cell_today.$i, $custom[$i-2] ~~ @array ? "Y":"N");
    }

my $alpha=$cell_today;
my $b=$alpha.($old_sheet -> {MaxRow}+1);    
$new_worksheet->autofilter( "A1:$b" ); # 对选区数据进行筛选
$new_worksheet->filter_column( 8, 'x == NonBlanks');
# $new_worksheet->filter_column( 5, 'x =~ *小时');
            
my $row = 1;
shift @{$columns[8]};
    
for my $region ( @{$columns[8]} ) {
        if ( not defined $region) {
    
            # Hide row.
            $new_worksheet->set_row( $row, undef, undef, 1 ); # 隐藏不匹配过滤标准的行
        } 
    
        $new_worksheet->write( $row++, 8, $region );
        $new_worksheet->write( $cell_today.$row,$region ~~ @array ? "Y":"N") if defined $region;# 最后的if defined 一定要加上,这是关键
 }
}  
                
    #条件格式 
              $new_worksheet->conditional_formatting( "J:$cell_today",
                {
                    type     => 'text',
                    criteria => 'begins with',
                    value    => 'Y',
                    format   => $filter_format_Y,
                }
            );
            
              $new_worksheet->conditional_formatting( "J:$cell_today",
                {
                    type     => 'text',
                    criteria => 'begins with',
                    value    => 'N',
                    format   => $filter_format_N,
                }
            );
}
print  "---------> [ OK ]";
__END__
QQ截图20160522224329.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 问题描述:制作excel工作簿所有工作表的目录,通过超链接在目录和内容表之间切换。(即:索引) 问题分析:如果一个...
    易水犹寒0711阅读 3,072评论 0 51
  • 时间总是过得很快,美好也好,痛苦也罢,时间很公平,不知不觉就第一周的课程结束,转眼回想,其实也没有那么的痛苦难受,...
    依东望阅读 807评论 1 1
  • 下了一天的雨,晚上停了,风不知东西南北的吹着。泛着水光的大地像一面镜子,跑在上面比平日温柔些。空气也松软,润我的鼻...
    今夕何夕兮007阅读 201评论 0 0
  • 你,是什么人?我是创业人! 今天晚上和硕士班的一个女生吃饭,她告诉我今天她去了创业园区去参观,感触颇深。 “这个社...
    安地TsengWong阅读 576评论 0 1
  • 你说,生活这么累,如果一直跑下去,没有像这样的休息时间,该有多可怕。 休息一下。给生活加点趣味! 画logo 画我...
    素言简说阅读 222评论 1 0