perl 中的 CSV 到 xls 转换

问题描述 投票:0回答:1

我想用 perl 解析 csv 文件并生成 Excel 工作表。 截至目前,我能够解析 CSV 文件并转换为 xls。这段代码工作正常,根据 CSV 给出了一些 6 行和 3 列。这是正确的。解析后我也想做一些格式化。let说任何具有“通过”字符串的行或列应该是绿色的,失败的话应该是红色的。我该怎么做,请帮忙..

     #!/run/pkg/TWW-perl-/5.8.8/bin/perl -w
     use strict;
     use warnings; 
     use Spreadsheet::WriteExcel;
     use Text::CSV::Simple;
     use Spreadsheet::ParseExcel::Format
my $infile = "/project/ls1socdft_nobackup/rev2.0/user/Shah-       B53654/dft/dfta/perl/pattern_qa/output_0/xls_info.csv";
#usage()  unless defined $infile && -f $infile;
  my $parser = Text::CSV::Simple->new; 
  my @data = $parser->read_file($infile);
  my $headers = shift @data;

   my $outfile = shift || "/project/ls1socdft_nobackup/rev2.0/user/Shah-B53654/dft/dfta/perl/pattern_qa/output_0/xls_info.xls";
my $subject = shift || 'worksheet';

 my $workbook = Spreadsheet::WriteExcel->new($outfile);
my $bold = $workbook->add_format();
$bold->set_bold(1) ;
 my $color =$workbook->add_format(); 
 $color->set_bg_color('green'); 
 my $color1=$workbook->add_format();
 $color1->set_bg_color('red');
import_data($workbook, $subject, $headers, \@data);

# Add a worksheet
 sub import_data {
my $workbook  = shift;
my $base_name = shift ;
my $colums    = shift;
my $data      = shift;
my $limit     = shift || 50_000;
my $start_row = shift ||1;
my $worksheet = $workbook->add_worksheet($base_name);
$worksheet->add_write_handler(qr[\w], \&store_string_widths);
my $w = 1;
$worksheet->write('A' . $start_row, $colums,$bold);
my $i = $start_row;
my $qty = 0;
for my $row (@$data) {
    $qty++;
    if ($i > $limit) {
         $i = $start_row;
         $w++;
         $worksheet = $workbook->add_worksheet("$base_name - $w");
                     $worksheet->write('A1', $colums);

          }

$worksheet->write(1+$i++,0, $row);}

   autofit_columns($worksheet);
warn "Convereted $qty rows.";
return $worksheet;
  }
 sub store_string_widths {

my $worksheet = shift;
my $col       = $_[1];
my $token     = $_[2];

# Ignore some tokens that we aren't interested in.
return if not defined $token;       # Ignore undefs.
return if $token eq '';             # Ignore blank cells.
return if ref $token eq 'ARRAY';    # Ignore array refs.
return if $token =~ /^=/;           # Ignore formula

# Ignore numbers
#return if $token =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d++))?$/;

# Ignore various internal and external hyperlinks. In a real scena+rio
# you may wish to track the length of the optional strings used wi+th
# urls.
return if $token =~ m{^[fh]tt?ps?://};
return if $token =~ m{^mailto:};
return if $token =~ m{^(?:in|ex)ternal:};


# We store the string width as data in the Worksheet object. We us+e
# a double underscore key name to avoid conflicts with future name +s.
#
my $old_width    = $worksheet->{__col_widths}->[$col];
my $string_width = string_width($token);

if (not defined $old_width or $string_width > $old_width) {
    # You may wish to set a minimum column width as follows.
    #return undef if $string_width < 10;

    $worksheet->{__col_widths}->[$col] = $string_width;
  }


# Return control to write();
return undef;
  }


sub string_width {

  return length $_[0];
   }
  sub autofit_columns {

my $worksheet = shift;
my $col       = 0;

for my $width (@{$worksheet->{__col_widths}}) {

    $worksheet->set_column($col, $col, $width) if $width;
    $col++;
}
 }
excel perl csv
1个回答
2
投票

有两种方法可以按照您期望的方式设置单个单元格的格式。

1:不要将数据数组传递到 $worksheet->write() 方法中,而是循环遍历每一行和每一列并单独写入每个单元格。 例如:

改变

$worksheet->write('A1', $colums);

for (my $r=0; $r < @$colums; $r++) {
    for (my $c=0; $c < @{$colums->[$r]}; $c++) {
        $worksheet->write($r,$c,$colums->[$r]->[$c]);
    } 

现在,您可以测试根据您的标准编写的每个值。如果匹配,只需包含您要使用的格式。

$worksheet->write($r, $c, $columns->[$r]->[$c], $color1);

}

2:另一种选择是使用 Excel::Writer::XLSX

Spreadsheet::WriteExcel 处于仅维护模式并且具有 实际上已被 Excel::Writer::XLSX 取代。

该模块更新了,包括条件格式化功能,可以在写入数据后添加。
另外,除了包含模块和初始化模块时之外,Excel 生成代码不应发生任何更改。
然后,您只需指定条件格式的规则即可。

$worksheet->conditional_formatting( 'A1:J10',
        {
            type     => 'text',
            criteria => 'containing',
            value    => 'Pass',
            format   => $color,
        }
    );
$worksheet->conditional_formatting( 'A1:J10',
        {
            type     => 'text',
            criteria => 'containing',
            value    => 'Fail',
            format   => $color1,
        }
    );
© www.soinside.com 2019 - 2024. All rights reserved.