`
deepfuture
  • 浏览: 4429074 次
  • 性别: Icon_minigender_1
  • 来自: 湛江
博客专栏
073ec2a9-85b7-3ebf-a3bb-c6361e6c6f64
SQLite源码剖析
浏览量:80295
1591c4b8-62f1-3d3e-9551-25c77465da96
WIN32汇编语言学习应用...
浏览量:70786
F5390db6-59dd-338f-ba18-4e93943ff06a
神奇的perl
浏览量:103949
Dac44363-8a80-3836-99aa-f7b7780fa6e2
lucene等搜索引擎解析...
浏览量:287426
Ec49a563-4109-3c69-9c83-8f6d068ba113
深入lucene3.5源码...
浏览量:15120
9b99bfc2-19c2-3346-9100-7f8879c731ce
VB.NET并行与分布式编...
浏览量:68282
B1db2af3-06b3-35bb-ac08-59ff2d1324b4
silverlight 5...
浏览量:32529
4a56b548-ab3d-35af-a984-e0781d142c23
算法下午茶系列
浏览量:46246
社区版块
存档分类
最新评论

perl解析excel

阅读更多

解析 Excel 文件提出了一个无论怎样看都很困难的难题。直到去年,UNIX 模块还完全不可用,并且只能用 Win32::OLE 模块来检索来自 Windows Excel 文件的数据。但由于两位 Perl 高手和许多志愿者的帮助和奉献,情况最终得以改变!

Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel

在 2000 年,Takanori Kawai 和 John McNamara 编写出了 Spreadsheet::WriteExcelSpreadsheet::ParseExcel 模块并将它们张贴在 CPAN 上,这两个模块使得在任何平台上从 Excel 文件抽取数据成为可能(尽管不容易)。

正如我们在稍后将看到的,如果您正在使用 Windows, Win32::OLE 仍提供一个更简单、更可靠的解决方案,并且 Spreadsheet::WriteExcel 模块建议使用 Win32::OLE 来进行更强大的数据和工作表操纵。 Win32::OLE 带有 ActiveState Perl 工具箱,可以用来通过 OLE 驱动许多其它 Windows 应用程序。请注意,要使用此模块,您仍需要在机器上安装和注册一个 Excel 引擎(通常随 Excel 本身安装)。

需要解析 Excel 数据的应用程序数以千计,但是这里有几个示例:将 Excel 导出到 CSV、与存储在共享驱动器上的电子表格交互、将金融数据移至数据库以便形成报告以及在不提供任何其他格式的情况下分析数据。

要演示这里给出的示例,必须在您的系统上安装 Perl 5.6.0。您的系统最好是最近(2000 年或以后)的主流 UNIX 安装(Linux、Solaris 和 BSD)。虽然这些示例在以前版本的 Perl 和 UNXI 以及其他操作系统中也可以使用,但是您应该考虑到您将面对那些它们无法作为练习发挥作用的情况。


Windows 示例:解析

本节仅适用于 Windows 机器。所有其它各节适用于 Linux。

在进行之前,请安装 ActiveState Perl(这里使用版本 628)或 ActiveState Komodo IDE 以编辑和调试 Perl。Komodo 为家庭用户提供一个免费许可证,您大概在几分钟之内就可以得到它。(有关下载站点,请参阅本文后面的 参考资料。)

使用 ActiveState PPM 软件包管理器安装 Spreadsheet::ParseExcelSpreadsheet::WriteExcel 模块是困难的。PPM 没有历史记录,难以设置选项,帮助会滚出屏幕并且缺省方式是忽略相关性而安装。您可以从命令行输入“ppm”然后发出以下命令来调用 PPM:


清单 1:安装 Excel 模块的 PPM 命令

ppm> install OLE::Storage_Lite
ppm> install Spreadsheet::ParseExcel
ppm> install Spreadsheet::WriteExcel

 

在这种情况下,该模块的安装将失败,因为 IO::Scalar 还不可用,因此,您可能想放弃 PPM 问题的查找,而转向内置的 Win32::OLE 模块。然而,在您阅读本文时,ActiveState 可能已经发布了该问题的修正。

有了 ActiveState 的 Win32::OLE ,您可以使用下面所列的代码逐个单元地转储工作表:

下载 win32excel.pl


清单 2:win32excel.pl

#!/usr/bin/perl -w
use strict;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
$Win32::OLE::Warn = 3;                                # die on errors...
# get already active Excel application or open new
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
    || Win32::OLE->new('Excel.Application', 'Quit');  
# open Excel file
my $Book = $Excel->Workbooks->Open("c:/komodo projects/test.xls"); 
# You can dynamically obtain the number of worksheets, rows, and columns
# through the Excel OLE interface.  Excel's Visual Basic Editor has more
# information on the Excel OLE interface.  Here we just use the first
# worksheet, rows 1 through 4 and columns 1 through 3.
# select worksheet number 1 (you can also select a worksheet by name)
my $Sheet = $Book->Worksheets(1);
foreach my $row (1..4)
{
 foreach my $col (1..3)
 {
  # skip empty cells
  next unless defined $Sheet->Cells($row,$col)->{'Value'};
 # print out the contents of a cell  
  printf "At ($row, $col) the value is %s and the formula is %s\n",
   $Sheet->Cells($row,$col)->{'Value'},
   $Sheet->Cells($row,$col)->{'Formula'};        
 }
}
# clean up after ourselves
$Book->Close;

 

请注意,您可以用以下方式很轻松地为单元分配值:

$sheet->Cells($row, $col)->{'Value'} = 1;

 


Linux 示例:解析

本节适用于 UNIX,特别适用于 Linux。没有在 Windows 中测试它。

很难给出一个比 Spreadsheet::ParseExcel 模块文档中所提供的示例更好的 Linux 解析示例,因此我将演示那个示例,然后解释其工作原理。

下载 parse-excel.pl


清单 3:parse-excel.pl

#!/usr/bin/perl -w
use strict;
use Spreadsheet::ParseExcel;
my $oExcel = new Spreadsheet::ParseExcel;
die "You must provide a filename to $0 to be parsed as an Excel file" unless @ARGV;
my $oBook = $oExcel->Parse($ARGV[0]);
my($iR, $iC, $oWkS, $oWkC);
print "FILE  :", $oBook->{File} , "\n";
print "COUNT :", $oBook->{SheetCount} , "\n";
print "AUTHOR:", $oBook->{Author} , "\n"
 if defined $oBook->{Author};
for(my $iSheet=0; $iSheet < $oBook->{SheetCount} ; $iSheet++)
{
 $oWkS = $oBook->{Worksheet}[$iSheet];
 print "--------- SHEET:", $oWkS->{Name}, "\n";
 for(my $iR = $oWkS->{MinRow} ;
     defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ;
     $iR++)
 {
  for(my $iC = $oWkS->{MinCol} ;
      defined $oWkS->{MaxCol} && $iC <= $oWkS->{MaxCol} ;
      $iC++)
  {
   $oWkC = $oWkS->{Cells}[$iR][$iC];
   print "( $iR , $iC ) =>", $oWkC->Value, "\n" if($oWkC);
  }
 }
}

 

此示例是用 Excel 97 测试的。如果它不能工作,则试着将它转换成 Excel 97 格式。 Spreadsheet::ParseExcel 的 perldoc 页也声称了 Excel 95 和 2000 兼容性。

电子表格被解析成一个名为 $oBook 的顶级对象。$oBook 具有辅助程序的特性,例如“File”、“SheetCount”和“Author”。 Spreadsheet::ParseExcel 的 perldoc 页的工作簿一节中记载了这些特性。

该工作簿包含几个工作表:通过使用工作簿 SheetCount 特性迭代它们。每个工作表都有一个 MinRow 和 MinCol 以及相应的 MaxRow 和 MaxCol 特性,它们可以用来确定该工作簿可以访问的范围。 Spreadsheet::ParseExcel perldoc 页的工作表一节中记载了这些特性。

可以通过 Cell 特性从工作表获得单元;那就是清单 3 中获得 $oWkC 对象的方式。 Spreadsheet::ParseExcel 的 perldoc 页的 Cell 一节中记载了 Cell 特性。根据文档,似乎没有一种方式能够获得特定单元中列出的公式。


Linux 示例:写入

本节适用于 UNIX,特别适用于 Linux。没有在 Windows 中测试它。

Spreadsheet::WriteExcel 在 Examples 目录中带有许多示例脚本,通常可以在 /usr/lib/perl5/site_perl/5.6.0/Spreadsheet/WriteExcel/examples 下找到这些脚本。它可能被安装在其它各处;如果找不到那个目录,请与您的本地 Perl 管理员联系。

坏消息Spreadsheet::WriteExcel 无法用于写入现有 Excel 文件。必须自己使用 Spreadsheet::ParseExcel 从现有 Excel 文件导入数据。 好消息Spreadsheet::WriteExcel 与 Excel 5 直至 Excel 2000 兼容。

这里有一个程序,它演示如何从一个 Excel 文件抽取、修改(所有数字都乘以 2)数据以及将数据写入新的 Excel 文件。只保留数据,不保留格式和任何特性。公式被丢弃。

下载 excel-x2.pl


清单 4:excel-x2.pl

#!/usr/bin/perl -w
use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use Data::Dumper;
# cobbled together from examples for the Spreadsheet::ParseExcel and
# Spreadsheet::WriteExcel modules
my $sourcename = shift @ARGV;
my $destname = shift @ARGV or 
           die "invocation: $0 <source file> <destination file>";
my $source_excel = new Spreadsheet::ParseExcel;
my $source_book = $source_excel->Parse($sourcename)
 or die "Could not open source Excel file $sourcename: $!";
my $storage_book;
foreach my $source_sheet_number (0 .. $source_book->{SheetCount}-1)
{
 my $source_sheet = $source_book->{Worksheet}[$source_sheet_number];
 print "--------- SHEET:", $source_sheet->{Name}, "\n";
 # sanity checking on the source file: rows and columns should be sensible
 next unless defined $source_sheet->{MaxRow};
 next unless $source_sheet->{MinRow} <= $source_sheet->{MaxRow};
 next unless defined $source_sheet->{MaxCol};
 next unless $source_sheet->{MinCol} <= $source_sheet->{MaxCol};
 foreach my $row_index ($source_sheet->{MinRow} .. 
        $source_sheet->{MaxRow})
 {
  foreach my $col_index ($source_sheet->{MinCol} .. 
        $source_sheet->{MaxCol})
  {
   my $source_cell = $source_sheet->{Cells}[$row_index][$col_index];
   if ($source_cell)
   {
    print "( $row_index , $col_index ) =>", $source_cell->Value, "\n";
    if ($source_cell->{Type} eq 'Numeric')
    {
  $storage_book->{$source_sheet->{Name}}->{$row_index}-
       >{$col_index} = $source_cell->Value*2;
    }
    else
    {
  $storage_book->{$source_sheet->{Name}}->{$row_index}-
          >{$col_index} = $source_cell->Value;
    } # end of if/else
   } # end of source_cell check
  } # foreach col_index
 } # foreach row_index
} # foreach source_sheet_number
print "Perl recognized the following data (sheet/row/column order):\n";
print Dumper $storage_book;
my $dest_book  = Spreadsheet::WriteExcel->new("$destname")
 or die "Could not create a new Excel file in $destname: $!";
print "\n\nSaving recognized data in $destname...";
foreach my $sheet (keys %$storage_book)
{
 my $dest_sheet = $dest_book->addworksheet($sheet);
 foreach my $row (keys %{$storage_book->{$sheet}})
 {
  foreach my $col (keys %{$storage_book->{$sheet}->{$row}})
  {
   $dest_sheet->write($row, $col, $storage_book->{$sheet}->{$row}->{$col});
  } # foreach column
 } # foreach row
} # foreach sheet
$dest_book->close();
print "done!\n";

 

值得注意的是,程序的数据抽取和存储部分必须要分开。它们本来可以同时进行,但是通过将它们分开,可以轻松地进行错误修复和改进。

对于上述问题,一个好得多的解决方案可能是通过 XML::Excel CPAN 模块实现,但是必须编写将 XML 转换回 Excel 的特殊转换器。 如果要以那种方式导入数据,还可以通过 DBD::Excel 模块使用 DBI 接口。最后, Spreadsheet::ParseExcel 带有 Spreadsheet::ParseExcel::SaveParser 模块,它声称可以在两个 Excel 文件之间转换,但是没有文档和示例。我的网站(请参阅 参考资料)演示了一个使用 SaveParser 的示例。事先警告:那是个实验型程序,极易出问题。


结束语

如果您正在使用 Windows 机器,请坚持使用 Win32::OLE 模块,除非您的机器上根本没有 Excel。虽然 Spreadsheet::WriteExcelSpreadsheet::ParseExcel 模块的功能正不断完善,但 Win32::OLE 是目前获得 Excel 数据的最简便方式。

在 UNIX,特别是 Linux 上,请使用 Spreadsheet::WriteExcelSpreadsheet::ParseExcel 模块对 Excel 数据进行编程访问。但是事先警告:它们还是相当不成熟的模块,如果您需要稳定性,则它们可能不适合您。

您还可以考虑象 Gnumeric 和 StarOffice(请参阅 参考资料)这样的软件包,可以免费获得它们,而且它们提供一个完整的 GUI 界面和 Excel 文件的导入/导出能力。如果您不需要对 Excel 数据进行编程访问,则它们很有用。这两个应用程序我都用过,我发现它们对于日常工作很不错。

<!-- CMA ID: 21660 --><!-- Site ID: 10 --><!-- XSLT stylesheet used to transform this file: dw-article-6.0-beta.xsl -->

 

分享到:
评论

相关推荐

    perl解析excel文件

    Perl是一种强大的脚本编程语言,尤其在文本处理和系统管理任务方面表现突出。...总的来说,使用Perl解析Excel文件是一项常见的任务,通过利用Perl的强大功能和丰富的生态系统,可以高效地完成数据提取和处理工作。

    Perl读写excel

    这个模块用于解析现有的Excel文件,提取数据并进行分析。它能够读取Excel文件中的工作簿、工作表和单元格内容。下面是一个简单的例子: ```perl use Spreadsheet::ParseExcel; my $parser = Spreadsheet::...

    perl读取EXCEL文件输出到XML

    该模块提供了对 EXCEL 文件的读取和解析功能,能够读取单元格的值、样式和公式等信息。 知识点三:XML 文件生成 XML 是一种标记语言,用于存储和传输数据。Perl 可以使用 XML::Writer 模块来生成 XML 文件。该模块...

    用Perl操作Excel2007 (xlsx) with Excel-Writer-XLSXL

    ### 使用Perl操作Excel 2007 (xlsx) 文件:详解Excel::Writer::XLSX模块 在IT领域,特别是数据分析、报表制作等场景中,能够高效地读写Excel文件是一项重要的技能。Perl作为一种功能强大的脚本语言,在处理文本和...

    perl Excel操作

    `Spreadsheet::ParseXLSX`模块提供了解析Excel文件的能力。使用这个模块,你可以遍历工作表、获取单元格值、检查公式以及处理样式和日期。以下是一个基本的读取Excel文件的例子: ```perl use Spreadsheet::...

    Perl SpreadSheet_Excel

    Perl SpreadSheet_Excel 是一个基于Perl编程语言的库,用于解析和操作Microsoft Excel电子表格文件。这个库的核心组件是 `Spreadsheet::ParseExcel` 模块,它允许开发者读取Excel文件的内容,包括单元格的数据、公式...

    perl example for read excel

    这段代码首先导入了`Spreadsheet::ParseXLSX`模块,然后创建一个解析器对象并调用`parse()`方法解析Excel文件。如果文件解析成功,它将遍历工作表中的每个单元格,并打印出它们的值。 `auto.pl`可能是一个自动化...

    excel_Perl_源码

    标题中的“excel_Perl_源码”表明我们将讨论如何使用Perl编程语言来处理Excel文件,具体来说是关于从数据文件中提取数据并将其转化为Excel表格的过程。Perl是一种强大的文本处理语言,非常适合处理各种数据格式,...

    perl-site的压缩包

    "perl-site" 指的是 Perl 的模块仓库 Site CPAN ( Comprehensive Perl Archive Network ) 中的模块,这里特指与解析 Excel 文件相关的模块。Site CPAN 是 Perl 社区维护的一个额外的模块存储库,包含了不在标准 CPAN...

    perl Spreadsheet

    - 解析工作簿:通过`Spreadsheet::ParseExcel-&gt;parse()`函数,可以打开并解析Excel文件,返回一个Workbook对象。 - 访问工作表:使用`workheets()`方法获取Workbook中的所有工作表,然后通过`worksheet()`方法选择...

    VB运行perl脚本工具

    这是一个运行Perl脚本的基础,因为它可以解析和执行Perl代码。 2. 引入Perl COM对象:VB可以利用Perl的COM(Component Object Model)支持来创建一个Perl解释器对象,通过这个对象,VB可以直接调用Perl脚本。在VB中...

    可以自动生成Verilog的Testbench的Perl脚本

    Perl脚本通过解析Verilog源代码,可以自动识别模块接口,生成相应的Testbench结构。它会为每个输入信号提供默认值或随机序列,为输出信号设置断言,以确保设计在各种条件下都能正确工作。此外,脚本可能还包含对高级...

    perl SVG包

    结合Perl的其他库,如DBI(数据库接口)或Excel::Writer::XLSX,可以将动态生成的数据可视化,形成直观的报告或分析结果。 `svg_lib`这个文件可能是包含SVG库的一些示例、测试代码或者额外的图形资源。在实际开发中...

    php直接读excel Spreadsheet_Excel_Reader

    然后创建一个`Spreadsheet_Excel_Reader`实例,并调用`read()`方法来解析Excel文件。例如: ```php require_once 'Spreadsheet_Excel_Reader.php'; $reader = new Spreadsheet_Excel_Reader(); $reader-&gt;read('...

    perl操作office

    例如,`Office::ParseXLS`模块用于解析Excel文件,而`Spreadsheet::WriteExcel`模块则可以用来创建新的Excel文件或者写入数据到已有的Excel文件中。对于Word文档,`Win32::OLE`模块允许通过COM接口与Word应用程序...

    perl gui 日志分析工具

    Perl GUI日志分析工具是一款基于Perl编程语言开发的图形用户界面应用,专为解析和分析日志文件设计。它能够帮助用户快速理解日志数据,提取关键信息,从而进行故障排查、性能监控或数据分析。这款工具包含源码,使得...

    华为交换机ARP表采集Perl脚本

    在这个脚本中,Perl的灵活性和强大的文本解析能力使其成为理想的选择,可以方便地与华为交换机进行通信,并解析返回的数据。 `HuaWeiSwitchArpGeter.pl`是主脚本文件,它包含了整个ARP表采集流程的逻辑。通常,它会...

    perl 模(Spreadsheet-ParseExcel)

    Perl 模块 `Spreadsheet::ParseExcel` 是一个用于解析 Excel 文件的库,它允许开发者在 Perl 程序中读取和处理 Excel 工作表的数据,而无需依赖 Microsoft Office 或其他重型软件。这个模块提供了高效且灵活的方式来...

    perl 对文本一些常用操作和常用正则表达式

    在日常开发中,Perl被用来执行各种各样的任务,包括但不限于文本解析、数据提取以及报告生成等。下面我们将详细介绍Perl中常用的文本处理方法以及一些常用的正则表达式。 #### 一、Perl文本操作 ##### 1. 字符串...

Global site tag (gtag.js) - Google Analytics