如何用Perl对Excel的数据进行提取并分析
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了一个表的数据量统计日报,主要是针对数据库中使用较频繁,数据量又较大的31张表。该日报有两个sheet组成,第一个sheet是数据填写,第二个sheet则是基于第一个sheet的数据进行的文字描述和图表展示。
文字描述主要包括两部分:一、呈现该31张表中数据量最大的9张表。呈现结果类似于:emp(约14万),dept(约100万)。。。当然,这个只是举例,为了避免引起不必要的麻烦(主要是企业信息安全方面的考虑),我这里不可能将具体日报的内容贴出来。毕竟,这个会涉及到表名和数据量大小。二、相对于昨日,这31张表中有哪些表的数据量在今日有所增长。
对于这种机械类的工作,每次做起来都比较繁琐,头疼。Perl之父Larry Wall说过,懒惰、急躁、傲慢是程序员的三大美德。于是就着手写了一个perl程序,每次只要把当天的数据量copy到Excel中,执行该程序即可。
程序内容如下:
use strict;
use Spreadsheet::XLSX;
use Unicode::UTF8simple;
use DateTime;
my ($col1,$col2,%hash1,%hash2,@tabname,$num,$num1);
my $dt=DateTime->from_epoch(epoch=>time);
my $duration=DateTime::Duration->new(days=>-);
my $dt1=$dt+$duration;
my $date=$dt->month.'-'.$dt->day.'-'.substr($dt->year,,);
my $date1=$dt1->month.'-'.$dt1->day.'-'.substr($dt1->year,,);
my $uref =new Unicode::UTF8simple;
my $file='C:\Users\Victor\Desktop\需做数据迁移的数据表数据量巡检日报-20150713.xlsx';
$file=$uref->fromUTF8('gb2312',$file);
my $workbook = Spreadsheet::XLSX -> new ($file);
my $worksheet = $workbook->worksheet('数据填写');
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $col ( $col_min .. $col_max ){
my $cell = $worksheet-> get_cell( , $col );
next unless $cell;
$col1=$col if ($cell->value() eq $date1);
$col2=$col if ($cell->value() eq $date);
}
for my $row (..$row_max){
my $cell = $worksheet->get_cell($row,);
my $cell1= $worksheet->get_cell($row,$col1);
my $cell2= $worksheet->get_cell($row,$col2);
$hash1{$cell->value()}=$cell1->value();
$hash2{$cell->value()}=$cell2->value();
push @tabname,$cell->value();
}
print $uref->fromUTF8('gb2312',"(1)需做数据迁移的数据表当前数据量较大的依次为(不计日志表):\n");
my $str2=$uref->fromUTF8('gb2312','约');
my $str3=$uref->fromUTF8('gb2312','万');
my $str4=$uref->fromUTF8('gb2312','、');
foreach my $key(sort {$hash2{$b}<=>$hash2{$a}} keys %hash2){
printf "%s(%s%d%s)%s",$key,$str2,$hash2{$key}/,$str3,$str4;
$num++;
last if $num == ;
}
print "\n";
print $uref->fromUTF8('gb2312',"(2)务开通定单调度关键数据表数据量增长趋势:\n");
foreach(@tabname){
if($hash1{$_} < $hash2{$_}){
print $_.$str4;
$num1++;
}
}
print $uref->fromUTF8('gb2312',"这$num1张表相对昨日有所增长。\n")
说明如下:
1> 在这里,用了三个模块,其中Spreadsheet::XLSX用于读取2007及以上版本的Excel。可惜的是,CPAN中貌似没有一个模块支持对已有Excel进行写操作。具体在本例中,第二个sheet中的文字描述完全可以在第一个sheet中数据基础上生成。但因找不到对既有Excel进行写的模块,所以生成的文字描述无法插入到第二个sheet中。于是只能退而求其次,只生成文字描述,然后再手动粘贴到第二个sheet中。第二个模块是Unicode::UTF8simple,主要用于UTF8和其它字符集的转换,在本例中,即中文字符集gb2312。第三个模块是DateTime,用于构造今天的日期和昨日的日期。
2>
my $dt=DateTime->from_epoch(epoch=>time);
my $duration=DateTime::Duration->new(days=>-);
my $dt1=$dt+$duration;
my $date=$dt->month.'-'.$dt->day.'-'.substr($dt->year,,);
my $date1=$dt1->month.'-'.$dt1->day.'-'.substr($dt1->year,,);
用于构造今天的日期和昨日的日期,其中$date是今天的日期,$date1是昨天的日期。
3>
my $worksheet = $workbook->worksheet('数据填写');
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $col ( $col_min .. $col_max ){
my $cell = $worksheet-> get_cell( , $col );
next unless $cell;
$col1=$col if ($cell->value() eq $date1);
$col2=$col if ($cell->value() eq $date);
}
第一个sheet的名字是“数据填写”,首先获取该sheet行、列的范围。
第一行的内容如下:
所以上面这个for语句用于获取今日日期和昨日日期所在的列。
注意上面for语句中的next unless $cell,它的意思是如果$cell为空,则继续下一个循环。因第一列第一行为空,所以该语句尤为必要。
4>
for my $row (..$row_max){
my $cell = $worksheet->get_cell($row,);
my $cell1= $worksheet->get_cell($row,$col1);
my $cell2= $worksheet->get_cell($row,$col2);
$hash1{$cell->value()}=$cell1->value();
$hash2{$cell->value()}=$cell2->value();
push @tabname,$cell->value();
}
分别构造两个哈希表,键均是第一列的表名,值是对应的数据量大小。其中hash1对应的是昨日的数据量,hash2对应的是今日的数据量。
将表名放到数组中,用于后续今日和昨日数据量的比较。
5>
print $uref->fromUTF8('gb2312',"(1)需做数据迁移的数据表当前数据量较大的依次为(不计日志表):\n");
my $str2=$uref->fromUTF8('gb2312','约');
my $str3=$uref->fromUTF8('gb2312','万');
my $str4=$uref->fromUTF8('gb2312','、');
foreach my $key(sort {$hash2{$b}<=>$hash2{$a}} keys %hash2){
printf "%s(%s%d%s)%s",$key,$str2,$hash2{$key}/,$str3,$str4;
$num++;
last if $num == ;
}
对hash2,即今天的数据量进行排序,打印出31个表中排名前11位的表,输入结果形式如下:
EMP(约1100万)、DEPT(约1000万)、location(约812万)、sales(约123万)...
因“约”、“万”、“、”均是中文字符,所以需要转换。因数据量的单位是万,在这里,我们将$hash2{$key}的值除以10000。
6>
print "\n";
print $uref->fromUTF8('gb2312',"(2)务开通定单调度关键数据表数据量增长趋势:\n");
foreach(@tabname){
if($hash1{$_} < $hash2{$_}){
print $_.$str4;
$num1++;
}
}
print $uref->fromUTF8('gb2312',"这$num1张表相对昨日有所增长。\n")
构造文字描述的第二部分,将今日相对于昨日数据量有所增加的表打印处理。输出结果类似于:
emp、dept、location、sales这4张表相对昨日有所增长。
如何用Perl对Excel的数据进行提取并分析的更多相关文章
- 使用Perl处理Excel之DMA映射
使用Perl处理Excel之DMA映射 功能 通道处理,将各个通道的外设映射到通道上 外设ack信号处理 脚本执行情况 顶层Perl脚本(dma_parse.pl) 将上述两个功能脚本整合,便于调用 ...
- 使用perl读取Excel
使用perl读取Excel 环境 windows 7 ActiveState Perl Win32::OLE[perl package] 基本功能 循环处理多个sheet 读取Excel单元,提取in ...
- NPOI操作EXCEL(三)——反射机制进行excel表格数据的解析
我们先来回忆回忆上篇文章讲到的通过xml配置文件实现excel批量模板解析的整体思路: 1.对每个excel模板制定xml配置规则集,实现xml配置文件的解析服务 2.为每个excel模板制定DTO, ...
- .net实现与excel的数据交互、导入导出
应该说,一套成熟的基于web的管理系统,与用户做好的excel表格进行数据交互是一个不可或缺的功能,毕竟,一切以方便客(jin)户(qian)为宗旨. 本人之前从事PHP的开发工作,熟悉PHP的都应该 ...
- jxl读取Excel表格数据
调用jxl包实现Excel表格数据的读取,代码如下: import java.io.File; import java.io.IOException; import java.util.ArrayLi ...
- Excel的数据导入到PB的DW中
Excel的数据导入到PB的DW中//==================================================================== // Event:cb_ ...
- Visual Basic 2012 借助DataGridView控件将Excel 2010数据导入到SQL server 2012
(注:注释的颜色原本为绿色,在这里变为黑色,有点不便,但不会造成阅读影响.放入Visual Basic2012代码编辑器后会还原成绿色.) 摘 要:DataGridView控件作为数据传输的中介,只 ...
- 向MySql数据库导入excel表数据
最近要开发一个小的答题系统,如果题目人工录入那确实很麻烦.所以想到是不是可以从用一些现有数据格式的文件导入数据.在网上查了一下,看到有关于将excel的数据导入到mysql的方法.所以将题库数据整理成 ...
- 上传读取Excel文件数据
/// <summary> /// 上传读取Excel文件数据 /// 来自http://www.cnblogs.com/cielwater /// </summary> // ...
随机推荐
- web-inf目录和meta-inf目录
/WEB-INF/web.xml Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则. /WEB-INF/classes/ 包含了站点所有用的 class 文件,包括 se ...
- 如何对tableview进行自定义多选
前言: 很多入门不久的程序员或许都会遇到系统自带的tableview多选时cell选择时不能选择自己想要的点击时的颜色或者图片,这让初级开发者们很烦恼.今天,我试着花了几个小时的时间用了自己的想法,去 ...
- 开源一个C#写的Android和IOS都能跑的 打击感强的RPG玩玩。
攒到 250楼再统一发一次代码,各位 给力啊 156楼之前的兄弟 都已经发送代码了!各位查收一下! 156楼之后的兄弟要晚上统一发送 200楼之前的兄弟都已经发送代码了! 各位查收一下!!!顺便 ...
- webform 上传
要使用控件 - FileUpload 1.如何判断是否选中文件? FileUpload.FileName - 选中文件的文件名,如果长度不大于0,那么说明没选中任何文件 js - f.value.le ...
- c/c++头文件_string
string, cstring, string.h 一.string头文件 主要包含一些字符串转换的函数 // sto* NARROW CONVERSIONS// sto* WIDE CONVERSI ...
- [CSS]textarea设置下划线格式
功能要求:1:如何实现在多行文本框textarea里面每一行下面都有一条横线 2:textarea文本框里面有一段不能删掉 实现方法:横线用背景图片来做,不动的文字用浮动层+给textarea增加t ...
- 谢欣伦 - 原创软件 - 工具软件 - 快速关机Shutdown
快速关机Shutdown,含源码. 公司公用的笔记本电脑实在太烂,不知从什么时候开始关机永远都关不了,一直停留在“关闭系统中……”.忍无可忍之下,自己写了一个快速关机程序. 下载: Shutdown_ ...
- Ubuntu安装Gnome3
参考:How To Install GNOME In Ubuntu 14.04 . Ubuntu11.10安装GNOME3,卸载UNITY和UNITY2D操作 和How to install Gnom ...
- 多位数每一位个系数:个位num%10;十位num/10%10.......
请输出满足这样条件的五位数. 个位=万位 十位=千位 个位+十位+千位+万位=百位 思路: 1.定义一个要操作的五位数变量num 2.求出每一位个系数 个:num%10 十:num/10%10 百:n ...
- ASP.NET Core 优雅的在开发环境保存机密(User Secrets)
前言 在应用程序开发的过程中,有的时候需要在代码中保存一些机密的信息,比如加密密钥,字符串,或者是用户名密码等.通常的做法是保存到一个配置文件中,在以前我们会把他保存到web.config中,但是在A ...