2016-04-13 2 views
4

У меня есть хэш с ключом и значениями (массив). Я хочу сбросить их в электронную таблицу, но с трудом их организовать.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: $!"; 

Выходной ток

enter image description here
Желаемая Выход

enter image description here

+0

Есть некоторые опечатки в вашем примере. Там 'my' отсутствует, и использование'% hash' и '% tools' не имеет смысла. Я исправил их и запустил, что дало мне правильный результат, но строки 1 и столбец А пустые. Он начинается с B2, но выглядит совершенно правильно. Я думаю, что ваш [mcve] делает что-то еще, как ваш настоящий код. – simbabque

+0

@simbabque Спасибо за указание опечаток.Я их исправил. Я дважды проверил свой код и снова побежал, и все же результат такой же, как и текущий вывод, упомянутый выше. Не уверен, что мне не хватает – Jill448

+1

Можете ли вы включить строку 'print $. "\ n"; 'внутри вашего цикла, чтобы убедиться, что' $ row' не увеличивается? –

ответ

2

Вы не правильно опорожнения @matching_lines массива. Эта линия:

for (@matching_lines) { $_ = undef } 

Устанавливает значение массива в undef, но не удаляет их.
Например, если @matching_lines был ('foo', 'bar'), теперь это будет (undef, undef). Когда вы добавляете baz и qux к нему позже, он становится (undef, undef, 'baz', 'qux'). Эти undef s становятся пустыми ячейками, когда вы добавляете их на рабочий лист.

Чтобы правильно очистить массив, используйте:

@matching_lines =(); 
+0

Да. Работала отлично. Спасибо. – Jill448

3

Edit: Теперь вы действительно обновили вашу программу, чтобы уточнить, что проблема заключается в том, как вы читаете данные, ниже спорно. Но это иллюстрирует альтернативный подход.

ОК, основная проблема здесь в том, что вы пытаетесь сделать, это «перевернуть» хэш. Вы печатаете строку за строкой, но ваш хэш организован в столбцах.

Использование запятой сно как быстрый прокси для печати реально первенствовать:

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

Output