使用Perl轻松解析Excel

在商业世界中,Excel电子表格似乎无处不在。最近我不得不在一个紧张的截止日期内为客户解析了几百个电子表格。更糟糕的是,电子表格包含了Excel 2003(xls)和2007(xlsx)格式的混合。幸运的是,我了解Perl,并且使用Spreadsheet::Read模块,这很容易。本文将向您展示如何使用Spreadsheet::Read来解析Excel电子表格。

要求

您需要安装Spreadsheet::Read和一些接口模块。 Spreadsheet::ParseExcel是Excel 2003电子表格的接口,而Spreadsheet::XLSX是用于读取现代Excel格式的。您可以使用cpan从终端安装所有三个模块。

$ cpan Spreadsheet::ParseExcel Spreadsheet::XLSX Spreadsheet::Read

使用Spreadsheet::Read

让我们解析封面图像中显示的电子表格,它包含一份利润表。Spreadsheet::Read提供了一个简单、统一的接口来读取电子表格。它导出ReadData函数,该函数需要一个电子表格的文件路径。

use Spreadsheet::Read;

my $workbook = ReadData('income_statement.xlsx');

现在$workbook包含表示电子表格的数据结构。我们可以通过使用Data::Printer打印它来检查此结构。

\ [
    [0] {
        error     undef,
        parser    "Spreadsheet::XLSX",
        sheet     {
            Sheet1   1
        },
        sheets    1,
        type      "xlsx",
        version   0.13
    },
    [1] {
        attr     [],
        B1       "Income Statement 2014",
        B2       "Revenue",
        B3       "Cost of goods sold",
        B4       "Gross profit",
        B5       "Financing costs",
        B6       "Tax",
        B7       "Net profit",
        cell     [
            [0] [],
            [1] [],
            [2] [
                [0] undef,
                [1] "Income Statement 2014",
                [2] "Revenue",
                [3] "Cost of goods sold",
                [4] "Gross profit",
                [5] "Financing costs",
                [6] "Tax",
                [7] "Net profit"
            ],
            [3] [
                [0] undef,
                [1] undef,
                [2] 50000,
                [3] 2500,
                [4] 47500,
                [5] 7150,
                [6] 10087.5,
                [7] 30262.5
            ]
        ],
        C2       " $ 50,000.00 ",
        C3       " $ 2,500.00 ",
        C4       " $ 47,500.00 ",
        C5       " $ 7,150.00 ",
        C6       " $ 10,087.50 ",
        C7       " $ 30,262.50 ",
        label    "Sheet1",
        maxcol   3,
        maxrow   7
    }
]

这表明$workbook是一个数组引用,其第一个元素描述了文件,后续元素表示单个工作表。在label键对中包含工作表名称,可以像这样访问它

$workbook->[1]{label}; #Sheet1

可以使用Excel的网格表示法(“A3”)或通过标准Perl数组访问来引用单元格。这两种方法之间的区别是格式

$workbook->[1]{C2}; #$ 50,000.00

$workbook->[1]{cell}[3][2]; #50000

因此,如果您需要对提取的数据进行额外的处理(例如保存到数据库),您可能希望使用{cell}表示法以获取干净的数据。在Spreadsheet::Read中,数组索引从1开始,所以单元格“C2”是[3][2]。

也许您想同时遍历两列并打印它们?没问题

for (2..7) {
    print "$workbook->[1]{cell}[2][$_]: $workbook->[1]{cell}[3][$_]\n"; 
}

Spreadsheet::Read不提供一些数据点:您无法访问单元格的底层公式,并且样式数据也不可用。

结论

Spreadsheet::Read不仅非常适合命令行应用程序,而且有很多用途。与Microsoft .Net互操作库不同,Perl的Excel接口不是单线程的,并且无需安装Excel即可工作。相反,Spreadsheet::Read直接解析Excel文件。这使得并行处理大型计算任务成为可能。另一个可能的用例是在Web应用程序上的电子表格上传界面;Spreadsheet::Read还支持Libre / Open Office格式以及CSV文本文件。


本文最初发布在PerlTricks.com

标签

David Farrell

David是一位专业程序员,经常在Twitter博客上关于代码和编程艺术发表推文。

查看他们的文章

反馈

这篇文章有什么问题吗?通过在GitHub上打开一个问题或拉取请求来帮助我们。