如何用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=>-1);
my $dt1=$dt+$duration;
my $date=$dt->month.‘-‘.$dt->day.‘-‘.substr($dt->year,2,2);
my $date1=$dt1->month.‘-‘.$dt1->day.‘-‘.substr($dt1->year,2,2);
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( 0, $col );
    next unless $cell;
    $col1=$col if ($cell->value() eq $date1);
    $col2=$col if ($cell->value() eq $date);
}
for my $row (1..$row_max){
    my $cell = $worksheet->get_cell($row,1);
    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}/10000,$str3,$str4;
       $num++;
       last if $num == 11;
}
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=>-1);
my $dt1=$dt+$duration;
my $date=$dt->month.‘-‘.$dt->day.‘-‘.substr($dt->year,2,2);
my $date1=$dt1->month.‘-‘.$dt1->day.‘-‘.substr($dt1->year,2,2);

用于构造今天的日期和昨日的日期,其中$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( 0, $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 (1..$row_max){
    my $cell = $worksheet->get_cell($row,1);
    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}/10000,$str3,$str4;
       $num++;
       last if $num == 11;
}

对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张表相对昨日有所增长。

时间: 2024-11-18 22:01:01

如何用Perl对Excel的数据进行提取并分析的相关文章

运维监控大数据的提取与分析

本文内容整理来自[敏捷运维大讲堂]蒋君伟老师的线上直播分享.分别从以下3个维度来分享:1.云时代监控分析的窘境:2.使用标签标记监控数据的维度:3.监控数据应用场景. 云时代监控分析的窘境 在虚拟化与容器技术广泛应用的情况下,运维对象大规模地增长,监控平台每天存储的指标都以亿计,所以监控数据如今已经成了大数据.传统的监控工具在这种场景下,对于数据的提取分析,已经力不从心,反而成为了运维的负担. 我们用一个典型的互联网档案分析应用举例说明: 这个应用支持容灾与负载均衡,它部署在三个数据中心,并同时

如何用PHP读取Excel文件数据及内容信息

在文章开始介绍前,大家需要了解一下PHPExcel是什么?PHPExcel 就是一个用来操作Office Excel 文档的PHP类库.接下来讲解如何利用PHPExcel类库将Excel表格内的信息内容读取出来,完整代码如下:<?php $fileName = "1.xls"; if (!file_exists($fileName)) { return "文件不存在!"; } // 引入PHPExcel require_once "./PHPExce

perl读取excel

因为工作当中遇到要处理大数据的excel的玩意,最多的有几十万行.用perl的方式试试,看看效果如何. ppm install OLE::Storage_Lite #如果不安装这个,后面两个安装不了 ppm install Spreadsheet::ParseExcel ppm install Spreadsheet::WriteExcel 查看是否安装成功 perldoc Spreadsheet::ParseExcel #如果打印出文档则表示安装成功 为保证编码正确 ppm install U

把Excel的数据导入到数据库

将Excel作为数据源,将数据导入数据库,是SSIS的一个简单的应用,下图是示例Excel,数据列是code和name 第一部分,Excel中的数据类型是数值类型 1,使用SSDT创建一个package,创建Excel data source component,SSDT会在Connection Managers中创建一个Excel的connection 由于示例Excel的首行是列名,所以需要勾选"First row has column names",Excel connectio

由excel经纬度数据生成等值线过程

1.准备数据 2.转换成要素类,名称为xy1 3.定义投影 至此,将excel点数据导入的工作已经完成. 接下来,生成等值线: 1.克里金插值(Kriging) 2.生成等值线 由excel经纬度数据生成等值线过程,布布扣,bubuko.com

技巧一:Delphi XE3 Excel导入数据到StringGrid

procedure TDataEditDrFrm.btn8Click(Sender: TObject);varexcelx,excely:string;ExcelApp:Variant;workBook:OleVariant;excelRowCount,excelColumnCount:longint;i,j,row,row1:integer; begin row1:=1; pb1.Min:=0; dlgOpen1.Filter:='Excel文件|*.xls|*.xlsx'; if dlgOp

Java通过POI技术操作Excel(3)----数据导出

在之前的博客中,总结了Excel模板生成和Excel数据录入,然后剩最后一个模块,数据库中数据读取,在之前的基础上我们来看这一模块,应该已经非常容易了,接下来简单的介绍一下: 这里我们仍然以jsp+servlet为例,对SqlServer2005数据库进行操作,如下都是基本步骤: 1.连接数据库:2.根据sql语句获取数据库中值:3.将值进行导出操作: 首先,我们来记性数据库的连接,这个相信接触过java的人都不会陌生,我就不赘述了 1 public class DataBase { 2 pri

使用Perl读取Excel文件

1. 任务 为了实现一些机械分词算法,准备使用“国家语委语料库”的分词词表,在线下载到得词表文件是一个Excel文件.本文的任务就是使用Perl从该Execl文件中提取所有的词语. 词表文件格式如下: 需要的词语的位置在从第8行开始的,第B列的所有单元格.一共有14629个词语.(PS:语料库的分词词表包含8万多个词语,但是在线下载到是出现次数在50次以上的词语,只有这1万多). 2. 使用什么模块 通过阅读一些博文发现,PERL的Spreadsheet::ParseExcel模块支持Excel

获取Excel部分数据并很据项目要求计算适宜性等级综合指数判断该地区的土壤适宜性

代码运行前请先导入jxl架包,以下代码仅供学习参考: 下图为项目中的Excel: ExcelTest02类代码如下: // 读取Excel的类 import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; public class ExcelTest02 { /* *该代码需要先获得exce