Perl:将数据从散列转储到Excel中

我有一个关键和值的散列(数组)。 我想将它们转储到电子表格中,但难以安排它们。

哈希%
key1 – > foo吧
key2->约翰亚当鳃
key3->苹果香蕉芒果橙

码:

use strict; use warnings; use Excel::Writer::XLSX; my $pattern = "BEGIN_"; my $format; my @keys = qw(key1 key2 key3); foreach my $key(@keys){ open my $fh, "<","filename.txt" or die $!; while ( <$fh> ) { if (/$pattern/) { push(@matching_lines, $_); } } $hash{$key} = [@matching_lines] ; for (@matching_lines) { $_ = undef } ; #Emptying the array contents,to reuse it for for all the other keys } my $workbook = Excel::Writer::XLSX->new( 'c:\TEMP\filename.xlsx' ); if (not defined $workbook) { die "Failed to create spreadsheet: $!"; } my $worksheet = $workbook->add_worksheet(); # Add and define a format $format = $workbook->add_format(); $format->set_bg_color( 'yellow' ); my $row = 1; my $col = 0; foreach my $k (keys %hash) { $worksheet->write($row, $col, $k, $format); # title $worksheet->write_col($row+1, $col, $hash{$k}); #value $col++; } $workbook->close() or die "Error closing file: $!"; 

当前输出

在这里输入图像描述
期望的输出

在这里输入图像说明

您没有正确清空@matching_lines数组。 这一行:

 for (@matching_lines) { $_ = undef } 

将数组值设置为undef ,但不删除它们
例如,如果@matching_lines('foo', 'bar') ,现在它变成(undef, undef) 。 当你稍后添加bazqux时,它变成(undef, undef, 'baz', 'qux') 。 当您将它们添加到工作表时,这些undef s成为空白单元格。

要正确清空数组,请使用:

 @matching_lines = (); 

编辑:现在你已经更新了你的程序,以澄清问题是你如何阅读你的数据,下面是没有意义的。 但它确实说明了另一种方法。

好的,这里的核心问题是你想要做的是“翻转”一个散列。 您正在逐行打印,但是您的散列按列组织。

使用逗号sep作为打印实际excel的快速代理:

 #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; #initialise my %hash = ( key1 => [qw ( foo bar )], key2 => [qw ( john adam gill )], key3 => [qw ( apple banana mango orange )], ); #print for debug print Dumper \%hash; #get header row. Sort it, because hashes are unordered. #could instead: #my @keys = qw ( key1 key2 key3 ); my @keys = sort keys %hash; #print header row print join ",", @keys, "\n"; #iterate until every element of the hash is gone while ( map { @{ $hash{$_} } } @keys ) { #cycle the keys, shifting a value of the top of each array. #replace any undefined values with ''. print shift( @{ $hash{$_} } ) // '', "," for @keys; print "\n"; } 

这打印:

 key1,key2,key3, foo,john,apple, bar,adam,banana, ,gill,mango, ,,orange, 

如果你把它作为csv加载到Excel中,应该给你想要的结果。 我很确定你可以在模块中使用类似的“写入行”。

所以这实际上似乎是做你想做的事情:

 #!/usr/env/perl use strict; use warnings; use Excel::Writer::XLSX; #initialise my %hash = ( key1 => [qw ( foo bar )], key2 => [qw ( john adam gill )], key3 => [qw ( apple banana mango orange )], ); my $workbook = Excel::Writer::XLSX->new('c:\TEMP\filename.xlsx'); if ( not defined $workbook ) { die "Failed to create spreadsheet: $!"; } my $worksheet = $workbook->add_worksheet(); # Add and define a format my $format = $workbook->add_format(); $format->set_bg_color('yellow'); my @keys = sort keys %hash; my $row = 0; $worksheet->write_row( $row++, 0, \@keys, $format ); while ( map { @{ $hash{$_} } } @keys ) { my $col = 0; $worksheet->write( $row, $col++, shift( @{ $hash{$_} } ) // '' ) for @keys; $row++; } $workbook->close() or die "Error closing file: $!"; 

产量