本文由乐哥团队公义撰写。
做数据的小伙伴在日常工作中可能会遇到这样的场景,有几十个文件需要保存到Excel中,在Excel里做计算,为每一个文件作图,导出图片。这时候如果你想锻炼自己坚韧的意志力,手动粘贴是不二选择。但大部分人还是排斥这种重复性操作的,重复性的操作应该交给计算机,人应该释放精力去做一些更有创造力的工作。
下面就介绍一下使用Perl的Win32::OLE模块操作Excel。
背景介绍:
Perl的设计者LarryWall为了让在UNIX上进行报表处理的工作变得更方便,决定开发一个通用的脚本语言。可以说Perl就是为报表处理,字符串处理而生。即便在今天Perl被用于图形编程、系统管理、网络编程、金融、生物以及其他许多领域。但最让人喜爱的还是Perl高效的字符处理方式。Perl有一个庞大的代码开源库CPAN,几乎可以找到任何你想要的功能模块。
再简单介绍一些Excel。Excel几乎人人都用,但普通使用者可能很少知道Excel可以抽象为对象模型从而使用OLE(ObjectLinkingandEmbedding)来操作。OLE即“对象链接与嵌入”,这是一种把一个文件的一部分嵌入到另一个文件之中的技术。下图是Excel的对象模型的整个层级结构。
根据这个图,我们打开一个Excel,可以有一种非常直观形象的了解。
一个Excel应用程序就是一个Application;
一个Application可以同时打开很多个工作簿(Workbooks);
一个Workbook可以包含很多个工作表(Worksheets);
一个Workbook还可以包含很多Shapes对象;
图表,标记,注释,控件等统称为shapes,我们接触最多的应该是图表也就是chart对象
通过Win32::OLE模块可以操作这些Excel对象,从而新建文件,新建表,写入数据,作图等等一系列的操作都可以完成。
准备工作:
安装Perl和win32::OLE模块。这里推荐使用strawberryPerl,因为其对CPAN上的模块支持更好。最新的strawberryPerl自带Win32::OLE模块。
下面进入正题,现在有n个文件,格式如下表所示:
date
A
B
C
D
-06-22
21
-06-23
20
.8
…
…
…
…
…
第一列为时间,后面几列都是指标。我们要把这些文件写入Excel中,并为每一个文件作一张图。我们做的简单一些将时间作为X轴,只用指标A作为Y轴画柱状图,其他指标暂时不管。
第一步:根据前面所描述的先建立一个Excel对象;
useWin32::OLE;
my$app_xls=Win32::OLE-new(Excel.Application,sub{$_[0]-Quit})ordieCantinstallExcel01!;
$app_xls-{DisplayAlerts}=False;
第二步:建立workbook,建立worksheet,sheet名为”sheet1”;
####—————————新建一个workbook
my$src_book=$app_xls-WorkBooks-add();
####—————————新建一个worksheet
my$sheet=$src_book-Worksheets(Sheet1);
第三步:读取数据文件,写入Excel,作图;
foreachmy$res(
res){##读入数据文件
my
data;open(FL,$res)ordie$!;
my$label=FL;
while(FL){
chomp;
push
data,[split/\t/,$_];}
closeFL;
##————使用cells对象,写入数据
print$res.\n;
my$ncol=scalar(
{$data[0]});my$nrow=scalar(
data);foreachmy$rn(1..$nrow){
foreachmy$cn(1..$ncol){
$sheet-Cells($rn,$ii+$cn)-{Value}=$data[$rn-1][$cn-1];
}
}
##——————使用range对象,选择数据
my$rang=$sheet-Range($sheet-Cells(1,$ii+1),$sheet-Cells($nrow,$ii+2));
my$label_rang=$sheet-Range($sheet-Cells(1,$ii+1),$sheet-Cells($nrow,$ii+1));
##——————使用chartobject用选中的数据作图
my$chart=$sheet-ChartObjects-Add(0,0,,);
$chart-{ChartType}=xlColumnClustered;
$chart-Chart-ChartWizard(
{
Source=$rang,
Title=$ii+2
});
$chart-{Left}=60*($ii);
$chart-{Top}=;
$ii++;
$ii+=$ncol;
}
用Cells对象写入数据$sheet-Cells(行数,列数)-{Value}=$data,Cells里面的行数列数只能是数字,数字从1开始。Range对象选择数据时一般使用单元格名称:$sheet-Range(A1:D4),这样选择的是A1:D4的矩形区域。单元格名称是字母数字组合,使用起来不太方便。所以也可以使用Cells对象代替单元格名Range($sheet-Cells(1,1),$sheet-Cells(4,4)),同样表示A1:D4的矩形区域。
$chart-{ChartType}可设置作图类型。作图类型可以在Microsoft