如何使用 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 文件中写入更新的数据?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Perl Excel 循环遍历单列而不是每一列

Openpyxl - 从 Excel 文件中的所有工作表中删除格式

如何删除EXCEL表中的大量数据行,要删除的行数大概8万

Excel中删除含有空值的整行或是整列

如何删除 vlookup 函数但实用地保留 perl 电子表格中的值

Access VBA:删除单元格值与 Access 表中的值匹配的 Excel 行