I am using Text::CSV::Slurp to create a CSV file from an array of hashes. It works great except some headers are missing.
hash1
header1 header2
1 2
hash2
header1 header2 header3
11 22 33
I want the final output to be a CSV file:
header1 header2 header3
1 2
11 22 33
not the slurp output
header1 header2
1 2
11 22
Any suggestions?
code:
sub entry_capture_csv {
my ($stores_folder, $cmdstr, $header_field, $entrycmdstr, $entryfilename) = @_;
print "\t\tOSSI-" . $cmdstr . " for " . $entryfilename . " entry detail\n";
$node->pbx_command($cmdstr);
if ( $node->last_command_succeeded() ) {
my @ossi_output = $node->get_ossi_objects();
my $i = 0;
my @ext_array;
foreach my $hash_ref(@ossi_output) {
$i++;
#print "output result $i\n";
for my $field ( sort keys %$hash_ref ) {
my $value = $hash_ref->{$field};
#print "\t$field => $value\n";
}
my $entryNumber = trim($hash_ref->{$header_field});
unless( defined $entryNumber ) { $entryNumber = '' };
if ($entryNumber eq "") {
#empty string
} else {
push(@ext_array, $entryNumber);
}
}
# Issue = failed sometimes there is extra header
#
my @result_array;
foreach (@ext_array) {
my $entrycmd = $entrycmdstr . " " . $_;
$node->pbx_command($entrycmd);
if ( $node->last_command_succeeded() ) {
print "\t\t\t" . $entrycmd . "\n";
my @ossi_output = $node->get_ossi_objects();
push(@result_array, @ossi_output);
#my $csv = Text::CSV::Slurp->create( input => \@ossi_output );
#open (OUTFILE, ">$stores_folder/$store-" . $entryfilename . "-" . "$_" . ".csv") || die "Can't open output file.\n";
#print OUTFILE $csv;
#close(OUTFILE);
} else {
print "Failed\t\t\t" . $entrycmd . "\n";
}
}
my $csv = Text::CSV::Slurp->create( input => \@result_array );
open (OUTFILE, ">$stores_folder/$store-" . $entryfilename . ".csv") || die "Can't open output file.\n";
print OUTFILE $csv;
close(OUTFILE);
}
}
The
Text::CSV::Slurp->createconstructor method takes afield_orderoption which defines the keys of the hash elements to be used and their order in the CSV record.Take a look at this code, which I think is self-explanatory.
output
Update
To automate getting a list of headers from the data, you could write something like this. The output is identical to that from the previous program.
Note that there is no way of knowing how best to sort the list of headers so I have used a simple lexical sort. It produces the desired effect with this trivial data.