如何使用 Perl 删除 Excel 工作表中的整列并在新的 Excel 文件中写入更新的数据?
Posted
技术标签:
【中文标题】如何使用 Perl 删除 Excel 工作表中的整列并在新的 Excel 文件中写入更新的数据?【英文标题】:How to delete entire column in Excel sheet and write updated data in new excel file using Perl? 【发布时间】:2016-10-04 04:41:35 【问题描述】:我是 Perl 的新手。我有 excel 文件说“sample.xls”,如下所示。 Sample.xls
大约有 1000 行这样的数据。我想解析这个文件并将其写入另一个文件,比如“output.xls”,输出格式如下。
output.xls 我已经用 perl 编写了一个脚本,但是它并没有按照我想要的方式给我准确的输出。另外,看起来脚本效率不高。谁能指导我如何改进我的脚本以及让我的输出如“output.xls”所示??
这是脚本:
#!/usr/bin/perl –w
use strict;
use warnings;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use Spreadsheet::WriteExcel::Chart;
# Read the input and output filenames.
my $inputfile = "path/sample.xls";
my $outputfile = "path/output.xls";
if ( !$inputfile || !$outputfile )
die( "Couldn't find file\n" );
my $parser = Spreadsheet::ParseExcel->new();
my $inwb = $parser->parse( $inputfile );
if ( !defined $inwb )
die "Parsing error: ", $parser->error(), ".\n";
my $outwb = Spreadsheet::WriteExcel->new( $outputfile );
my $inws = $inwb->worksheet( "Sheet1" );
my $outws = $outwb->add_worksheet("Sheet1");
my $out_row = 0;
my ( $row_min, $row_max ) = $inws->row_range();
my ( $col_min, $col_max ) = $inws->col_range();
my $format = $outwb->add_format(
center_across => 1,
bold => 1,
size => 10,
border => 4,
color => 'black',
border_color => 'black',
align => 'vcenter',
);
$outws->write(0,0, "Item Name", $format);
$outws->write(0,1, "Spec", $format);
$outws->write(0,2, "First name", $format);
$outws->write(0,3, "Middle Name", $format);
$outws->write(0,4, "Last Name", $format);
$outws->write(0,5, "Customer Number", $format);
$outws->write(0,6, "Age", $format);
$outws->write(0,7, "Units", $format);
my $col_count = 1;
#$row_min = 1;
for my $inws ( $inwb->worksheets() )
my ( $row_min, $row_max ) = $inws->row_range();
my ( $col_min, $col_max ) = $inws->col_range();
for my $in_row ( 2 .. $row_max )
for my $col ( 0 .. 0 )
my $cell = $inws->get_cell( $in_row, $col);
my @fields = split /_/, $cell->value();
next unless $cell;
$outws->write($in_row,$col, $cell->value());
$outws->write($in_row,$col+1, $fields[1]);
for my $in_row ( 2 .. $row_max )
for my $col ( 1 .. 1 )
my $cell = $inws->get_cell( $in_row, $col);
my @fields = split /_/, $cell->value();
next unless $cell;
#$outws->write($in_row,$col+1, $cell->value());
$outws->write($in_row,$col+1, $fields[0]);
$outws->write($in_row,$col+2, $fields[1]);
$outws->write($in_row,$col+3, $fields[2]);
$outws->write($in_row,$col+4, $fields[3]);
for my $in_row ( 2 .. $row_max )
for my $col ( 2 .. 2 )
my $cell = $inws->get_cell( $in_row, $col);
my @fields = split /_/, $cell->value();
next unless $cell;
$outws->write($in_row,6, $cell->value());
for my $in_row ( 2 .. $row_max )
for my $col ( 3 .. 9 )
my $cell = $inws->get_cell( $in_row, $col);
next unless $cell;
for my $in_row ( 2 .. $row_max )
for my $col ( 10 .. 10 )
my $cell = $inws->get_cell( $in_row, $col );
next unless $cell;
$outws->write($in_row,7, $cell->value());
【问题讨论】:
欢迎使用 Stack Overflow 和 Perl 标签。这是一个很好的第一个问题。 :) 直接拥有文件会很好。如果需要,您可以edit 问题添加它们。还要确保使用tour 并阅读How to Ask。 如果我没看错的话,您当前输出和预期输出的区别在于您希望它按Item Name
排序,并且不同项目名称之间有空格。下次,请在问题中包含该信息。效率怎么样?为什么你认为它没有效率?看起来它正在做它应该做的事情,并且 Excel 文件的用户可以轻松地在 Excel 中添加排序功能。这需要大约两到三下点击才能按照您想要的方式对其进行排序。在 $work,我会告诉业务人员自己对它进行排序,并且很高兴他们得到 XLS,而不是 CSV。:)
【参考方案1】:
要对输出进行排序,您需要先收集所有信息,然后再将其写出。现在,您正在行和列之间来回跳跃。
为了对其进行排序并使其更高效(阅读),我会进行一些更改。
在循环之外创建一个数据结构$data
来存储所有信息。
如果只有一个工作表,则无需循环工作表。只需使用一张纸即可。
遍历线条。
在该循环中,使用您必须解析各个字段的代码来解析它们。没有2..2
循环。只是一堆陈述。
my @item_fields = split /_/, $inws->get_cell( $in_row, 0 ) || q;
my @name_fields = split /_/, $inws->get_cell( $in_row, $col ) || q;
将它们存储在$data
中。
push @ $data = [ $item_fields[0], ... ];
完成循环。打开输出文件。
使用sort
循环遍历$data
并写入输出文件。
foreach my $row (sort $a->[0] cmp $b->[0] @ $data ) ...
完成。
我建议您阅读 sort
并查看 perlref 和 perlreftut 以了解有关引用(数据结构)的更多信息。
【讨论】:
以上是关于如何使用 Perl 删除 Excel 工作表中的整列并在新的 Excel 文件中写入更新的数据?的主要内容,如果未能解决你的问题,请参考以下文章
Openpyxl - 从 Excel 文件中的所有工作表中删除格式