用Perl读取Excel文件,Spreadsheet::Read.pm库介绍

Posted ExASIC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Perl读取Excel文件,Spreadsheet::Read.pm库介绍相关的知识,希望对你有一定的参考价值。

Excel是IC设计验证中常用的配置文件格式。与yaml、json、xml等专业格式比起来,Excel人人都会用,无需培训。




Spreadsheet::Read介绍


Spreadsheet::Read库支持读取csv、ods、xls、xlsx等文件格式。

1use Spreadsheet::Read;
2my $book  = ReadData ("test.csv"sep => ";");
3my $book  = ReadData ("test.ods");
4my $book  = ReadData ("test.xls");
5my $book  = ReadData ("test.xlsx");


其实Read.pm并没有那么厉害,它只是把Spreadsheet::XLSX和Spreadsheet::ParseExcel包了一层,统一了各种格式的读取数据的接口和数据存储结构。

读取csv或excel文件后,Read.pm把数据按下面的结构存储。$book是一个数组指针,$book[0]是一些整体的信息,如一共有几张sheet,每个sheet的label名等。$book[1]~$book[n]保存着实际sheet里的信息和数据。

 1$book = [
2    # Entry 0 is the overall control hash
3    { sheets  => 2,
4      sheet   => {
5        "Sheet 1"  => 1,
6        "Sheet 2"  => 2,
7        },
8      parsers => [ {
9          type    => "xls",
10          parser  => "Spreadsheet::ParseExcel",
11          version => 0.59,
12          }],
13      error   => undef,
14      },
15    # Entry 1 is the first sheet
16    { parser  => 0,
17      label   => "Sheet 1",
18      maxrow  => 2,
19      maxcol  => 4,
20      cell    => [ undef,
21        [ undef1 ],
22        [ undefundefundefundefundef"Nugget" ],
23        ],
24      attr    => [],
25      merged  => [],
26      active  => 1,
27      A1      => 1,
28      B5      => "Nugget",
29      },
30    # Entry 2 is the second sheet
31    { parser  => 0,
32      label   => "Sheet 2",
33      ...


每个sheet里,具体保存了label名、实际使用的最大行和最大列(即有效数据的最后一行和最后一列)、单元格里的数据等。

其中单元格里的数据是一个二维数组cell[col][row]。为了使用更方便,cell数组的0行0列留空了,没使用。实际数据从1行1列开始。例如:cell[1][1]就是A1里面的值。

注意:列在前、行在后。




SpreadSheet::Read的例子


假设,我们有Excel文件Book1.xlsx,内容如下:



读取Excel的脚本如下:


 1#!/usr/bin/perl -w
2
3use strict;
4use Spreadsheet::Read;
5
6my $excelfilename = "Book1.xlsx";
7my $book_ref = ReadData("$excelfilename");
8my @book = @{$book_ref};
9
10#info
11my %info = %{$book[0]};
12my $pages = $info{sheets};
13print("Total $pages sheets ");
14
15#sheet 1
16my %sheet = %{$book[1]};
17
18my $label = $sheet{'label'};
19print("process $label ... ");
20
21my $maxrow = $sheet{'maxrow'};
22my $maxcol = $sheet{'maxcol'};
23print("max row: $maxrow, max col: $maxcol ");
24
25#get cells
26my $cellref = $sheet{'cell'};
27my @cell = @{$cellref};
28
29
30for(my $r=1; $r<=$maxrow; $r++){
31    for(my $c=1; $c<=$maxcol; $c++){
32        if(defined($cell[$c][$r])){
33            print($cell[$c][$r] . " ");
34        }else{
35            print("undefined ");
36        }
37    }
38    print(" ");    
39}


测试结果如下,共有3页sheet,只读取了第一个sheet,输出内容与Excel原文件相同。


用Perl读取Excel文件,Spreadsheet::Read.pm库介绍


细心的朋友可能注意到上面代码中有个defined(),那么defined($cell[$c][$r])是做什么的?有可能什么情况下会出现undefined?我们实验发现两种情况出输出undefined。


情况一:单元格里没有值


用Perl读取Excel文件,Spreadsheet::Read.pm库介绍


用Perl读取Excel文件,Spreadsheet::Read.pm库介绍


情况二:合并单元格


用Perl读取Excel文件,Spreadsheet::Read.pm库介绍


用Perl读取Excel文件,Spreadsheet::Read.pm库介绍


A3和B3合并后,A3可以读出值,而B3是undefined。考虑更通用的情况,如果多个单元格合并,数值保存在左上角,其余单元格都是undefined。




更多资源


Spreadsheet::Read的作者还基于此库做了一些示例应用:

其中,

ss2tk是在tk中显示excel文件,

ssdiff可以对比两个excel的差异,

xls2cvs可以格式转换,

xlscat显示全部或指定的部分内容,

xlsgrep显示正则匹配到的单元格内容等。


github链接:

https://github.com/Tux/Spreadsheet-Read/tree/master/examples






欢迎关注ExASIC


分享数字集成电路设计中的经验和方法

分享让工作更轻松

以上是关于用Perl读取Excel文件,Spreadsheet::Read.pm库介绍的主要内容,如果未能解决你的问题,请参考以下文章

如何通过工作表名称在 Perl 中读取 Excel 文件

Perl学习15之perl读excel表格

perl tk将界面输入的汉字不能输出到读取的EXCEL表格

java中如何读取excel表格中的日期

用Perl将Tab-delimited文本文件转换成Excel表格

用 CGI 在 perl 中读取文件?