2016-04-13 10 views
4

私はキーと値(配列)を持つハッシュを持っています。私はそれらをスプレッドシートに捨てたいが、それらを整理するのが難しい。Perl:ハッシュのデータをExcelにダンプする

%ハッシュ
キー1 - > 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: $!"; 

電流出力

enter image description here
所望の出力

enter image description here

+0

はあなたの例では、いくつかのタイプミスがあります。 'my'が欠けていて、'%hash 'と '%tools'の使用は意味がありません。私はそれらを修正し、それを実行し、正しい出力を得ましたが、行1と列Aは空です。それはB2から始まりますが、完全に正しいと思われます。私はあなたの[mcve]があなたの本当のコードとして何かをしていると思います。 – simbabque

+0

@simbabqueタイプミスを指摘してくれてありがとう。私はそれらを訂正しました。私は自分のコードをダブルチェックして再度実行しましたが、出力は上記の出力と同じです。わからない、何が足りないのですか? – Jill448

+1

'print $行を含めることができますか? "\ n"; 'あなたのループの中で、' $ row'がインクリメントされていないことを確認しますか? –

答えて

2

あなたは正しく@matching_lines配列を空にしていません。このライン:

for (@matching_lines) { $_ = undef } 

undefに配列の値を設定しますが、彼らにを削除されません。
たとえば、@matching_lines('foo', 'bar')の場合は、(undef, undef)になります。後でbazquxを追加すると、(undef, undef, 'baz', 'qux')になります。これらのundefは、ワークシートに追加すると空白のセルになります。

が正しく配列を空にするには、使用:

@matching_lines =(); 
+0

完璧に働いた。ありがとうございました。 – Jill448

3

編集:今、あなたが実際に問題があなたのデータを読んでいるかであることを明確にするあなたのプログラムを更新した、以下の議論の余地があります。しかし、それは別のアプローチを示しています。

ここで重要な問題は、ハッシュを「フリップ」することです。行ごとに印刷していますが、ハッシュは列で構成されています。

実際のExcelを印刷するための迅速なプロキシとしてコンマ9月の使用:

#!/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, 

あなたがExcelにcsvとしてそれをロードする場合は、ご希望の結果を与える必要があります。私はあなたがモジュールで同様の 'write row'を使うことができると確信しています。

だから、これは実際にあなたがやりたいようだ:

#!/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: $!"; 

Output

関連する問題