Perl如何在一个(多个工作表)中合并两个或多个Excel文件?

我需要将几个excel文件合并成一个,多个工作表。 我不太关心新文件上的表格名称。

我没有计算机上的Excel,我打算运行这个。 所以我不能使用Win32 OLE。 我试图运行这个代码https://sites.google.com/site/mergingxlsfiles/,但它不工作,我得到一个新的空的Excel文件。

我试图运行http://www.perlmonks.org/?node_id=743574但我只获得了新的Excel文件中的一个文件。

我的inputexcel文件有一些法国字符(例如)我相信这些是cp1252。

使用的代码:

#!/usr/bin/perl -w use strict; use Spreadsheet::ParseExcel; use Spreadsheet::WriteExcel; use File::Glob qw(bsd_glob); use Getopt::Long; use POSIX qw(strftime); GetOptions( 'output|o=s' => \my $outfile, 'strftime|t' => \my $do_strftime, ) or die; if ($do_strftime) { $outfile = strftime $outfile, localtime; }; my $output = Spreadsheet::WriteExcel->new($outfile) or die "Couldn't create '$outfile': $!"; for (@ARGV) { my ($filename,$sheetname,$targetname); my @files; if (m!^(.*\.xls):(.*?)(?::([\w ]+))$!) { ($filename,$sheetname,$targetname) = ($1,qr($2),$3); warn $filename; if ($do_strftime) { $filename = strftime $filename, localtime; }; @files = glob $filename; } else { ($filename,$sheetname,$targetname) = ($_,qr(.*),undef); if ($do_strftime) { $filename = strftime $filename, localtime; }; push @files, glob $filename; }; for my $f (@files) { my $excel = Spreadsheet::ParseExcel::Workbook->Parse($f); foreach my $sheet (@{$excel->{Worksheet}}) { if ($sheet->{Name} !~ /$sheetname/) { warn "Skipping '" . $sheet->{Name} . "' (/$sheetname/)"; next; }; $targetname ||= $sheet->{Name}; #warn sprintf "Copying %s to %s\n", $sheet->{Name}, $targetname; my $s = $output->add_worksheet($targetname); $sheet->{MaxRow} ||= $sheet->{MinRow}; foreach my $row ($sheet->{MinRow} .. $sheet->{MaxRow}) { my @rowdata = map { $sheet->{Cells}->[$row]->[$_]->{Val}; } $sheet->{MinCol} .. $sheet->{MaxCol}; $s->write($row,0,\@rowdata); } } }; }; $output->close; 

我有2个excel文件命名为:2.xls(只有一个名为2的表),3.xls(只有一张名为3)

我推出了这个脚本:

 xlsmerge.pl -s -o results-%Y%m%d.xls 2.xls:2 3.xls:3 

结果:结果-20121024.xls什么也没有。

然后我试了一下

 xlsmerge.pl -s -o results-%Y%m%d.xls 2.xls 3.xls 

它的工作。 我不知道为什么添加Sheetname时失败

看起来,脚本的这一行中有一个错误:

 if (m!^(.*\.xls):(.*?)(?::([\w ]+))$!) { ($filename,$sheetname,$targetname) = ($1,qr($2),$3); ... 

在我看来,这条线的目标是允许在forms上的参数

 spreadsheet.xls:source_worksheet 

或以另一种forms允许指定目标工作表的名称:

 spreadsheet.xls:source_worksheet:target_worksheet 

最后一个分组似乎是为了捕获最后的可选参数: (?::([\w ]+)) 。 唯一的问题是,这个分组不是可选的。 因此,如果只指定源表而不指定目标,那么正则expression式将无法匹配,并且会落入备份行为,即将整个参数视为文件名。 但是这也失败了,因为你没有一个名为2.xls:2的文件。

解决办法是介绍一下? 修饰符在正则expression式中的最后一组后,使其成为可选:

 if (m!^(.*\.xls):(.*?)(?::([\w ]+))?$!) { ($filename,$sheetname,$targetname) = ($1,qr($2),$3); ... 

当然,这可能不是唯一的问题。 如果脚本发布错误,则可能还有其他错误。 我目前没有可用的Perl来testing它。