我想将哈希地图数据写入Excel

时间:2017-05-27 14:49:32

标签: perl perl-module perl-data-structures

以下是我在代码中使用print Dumper(\%Data)时得到的输出

{
  "" => undef,
  "123456789012:SRIRAMA" => [123456789012, "SRIRAMA", 856.06, 0, 0, 0],
  "389252737122:RAMA" => [389252737122, "RAMA", 345.76, 0, 0, 0],
}

这个数据我必须写入下面的Excel文件

Number          Name    number        name   amt    amt2    amt3    amt4
123456789012    SRIRAMA 123456789012 SRIRAMA 856.06  0      0       0
389252737122    RAMA    389252737122 RAMA    345.76  0      0       0

前两列是一个SQL结果,其余列是另一个SQL查询结果。

我在地图中放入第一个查询结果并根据第二个查询结果中的键进行搜索,最后得到了上面的输出。

此处,NumberName - 前两列 - 是搜索数据的键。

以下代码是在获得SQL结果之后:

    foreach ( @Sqlresult ) {
        $rec_cntr = $rec_cntr + 1;
        my @fields = undef;
        chop;

        next if /^$/;
        next if /ERROR:/;
        next if /ORA-/;

        @fields = split( /::/, $_ );
        my $fldref = @fields;
        $ent_id = undef;
        $ent_id = $fields[0];
        $key    = undef;
        $key    = $fields[0] . ":" . $name;

        push( @{ $Data{$key} }, $fields[1] );
    }

    $rec_cntr = 0;

我在记录不存在时使用的下面的代码片段为零。

    my $kkey = undef;

    for $kkey ( sort keys %Data ) {
        next if $kkey eq '';
        my $Lent = @{ $Data{$kkey} };
        if ( $Lent < 5 ) {
            push( @{ $Data{$kkey} }, 0 );
        }
        print scalar @{ $Data{$kkey} };

    }

    print Dumper( \%Data );

以上print Dumper生成问题开头显示的信息

这是将数据写入Excel工作表的地方

my $dt = `date +%m-%d-%Y_%\I%\M`;

chop $dt;
my $FileName = "/data_reports/AdjestedFile" . $dt . ".xls";

#my $workbook = Spreadsheet::WriteExcel->new( $FileName );
my $workbook = Excel::Writer::XLSX->new( $FileName );

# Define the format and add it to the worksheet
my $format = $workbook->add_format(
    center_across => 1,
    bold          => 1,
    size          => 10,
    color         => "black",
    bg_color      => "grey",
    border_color  => "black",
    align         => "vcenter",
);

my $formatnum = $workbook->add_format();
$formatnum->set_num_format( '00000000000' );

my $formatamt = $workbook->add_format();
$formatamt->set_num_format( '0.00' );
$formatamt->set_align( 'right' );

my $formattext = $workbook->add_format( num_format => '@' );

my $prev_feetype = "";

my $current_ws;
$current_ws = $workbook->add_worksheet();
$current_ws->keep_leading_zeros( 1 );

$current_ws->set_column( 0, 16, 17, $formattext );
$current_ws->set_column( 1, 1,  13, $formattext );
$current_ws->set_column( 2, 2,  10, $formatnum );
$current_ws->set_column( 3, 3,  10, $formattext );
$current_ws->set_column( 4, 4,  10, $formattext );
$current_ws->set_column( 5, 5,  10, $formattext );
$current_ws->set_column( 6, 6,  10, $formattext );
$current_ws->set_column( 7, 7,  10, $formattext );

my $cl = 0;
$current_ws->write_string( 0, $cl++, "Number", $format );
$current_ws->write_string( 0, $cl++, "Name",   $format );
$current_ws->write_string( 0, $cl++, "amt",    $format );
$current_ws->write_string( 0, $cl++, "NA",     $format );
$current_ws->write_string( 0, $cl++, "NA",     $format );
$current_ws->write_string( 0, $cl++, "NA",     $format );
$current_ws->write_string( 0, $cl++, "NA",     $format );
$current_ws->write_string( 0, $cl++, "NA",     $format );

my $rownum = 1;

foreach ( %Data ) {

    my @fields = undef;
    chop;

    next if /^$/;
    @fields = split( /,/, $_ );

    my $fldref = \@fields;
    my $clcntr = 0;
    my $ent_id = "";

    foreach ( @fields ) {

        if ( $clcntr == 1 ) {
            $ent_id = $_;
        }
        if ( isfloat( $_ ) ) { #and $clcntr != 9 ) {

            $current_ws->write_number( $rownum, $clcntr++, $_ );
        }
        else {
            $current_ws->write_string( $rownum, $clcntr++, $_ );
        }
    }
}

1 个答案:

答案 0 :(得分:2)

在那里阅读很多,但这些想法可能会有所帮助

  • 始终 use strictuse warnings位于您编写的每个Perl程序的顶部。找到更明显的错误

  • 是非常宝贵的
  • 不要使用@data = undef初始化数组。如果要清空现有数组,请写入@data = ()。如果您要声明一个新数组,那么my @data将创建一个新的空数组

    完全相同的建议适用于哈希,这将是"" => undef哈希

  • 开始时%Data的原因
  • 不要使用my $dt = `date +%m-%d-%Y_%\I%\M`。您正在开始一个全新的shell进程,只是为了问它时间。你应该

    use Time::Piece;
    

    my $dt = localtime->strftime('%m-%d-%Y_%I%M');
    

    此结果不需要chomp

    但是你确定你想要%I吗?这为您提供了12小时的时间,因此该值将在中午重置为零。 %H为您提供24小时制,而且更有可能是有用的

  • chomp优于chop,除非您做一些不寻常的事情。 chop只会删除字符串中的最后一个字符,无论它是什么,而chomp将删除最后一个字符(如果它是换行符)

  • for ( %Data ) { ... }会将哈希设置$_循环到key1,val1,key2,val2等。这不是你想要的

    在这种情况下,由于密钥中的信息在值中重复,因此您可能需要for ( values %Data ) { ... }。但该值是数组引用,因此不需要拆分

这可能更接近您的需要

my $rownum = 0;

for my $values ( values %Data ) {

    my $colnum = 0;

    for my $val ( @$values ) {

        if ( isfloat($_) ) {
            $current_ws->write_number( $rownum, $colnum++, $val );
        }
        else {
            $current_ws->write_string( $rownum, $colnum++, $val );
        }
    }
}