I have started using Spreadsheet::WriteExcel::Chart for writing chart.I have 10 worksheet which contain data. I have added one worksheet for chart. My question is, How can I create chart using another worksheet data.
2) I also tried another approach In which,I have created new worksheet and load data from old worksheet than try to create chart.
3)In $data,we are hardcoding value, is it possible that can we fetch value from cell rather
than hardcode value
In both case,I am not able to figure out the solution.
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use Spreadsheet::ParseExcel::SaveParser;
# Open the template with SaveParseir
my $parser = new Spreadsheet::ParseExcel::SaveParser;
my $workbook = $parser->Parse('DD1.xls');
if ( !defined $workbook ) {
die $parser->error(), ".\n";
}
#Create the New worksheet
my $Flop_workbook = Spreadsheet::WriteExcel->new('Flop.xls');
for my $worksheet ( $workbook->worksheets() ) {
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
my $worksheetname = $worksheet->get_name();
print "worksheetname : ", $worksheetname ,"\n";
my $sheet = $Flop_workbook->add_worksheet($worksheetname);
for my $row ( $row_min .. $row_max ) {
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet->get_cell( $row, $col );
next unless $cell;
print "Row, Col = ($row, $col)\n";
print "Value = ", $cell->value, "\n";
print "Unformatted = ", $cell->unformatted(), "\n";
$sheet->write_string($row,$col,$cell->value);
print "\n";
}
}
}
my $chartsheet = $Flop_workbook->add_worksheet('Chart_data');
my $chart = $Flop_workbook->add_chart( type => 'line' );
#Configure the chart.
$chart->add_series(
categories => '=SUM_F_SCDLIB_DFF!$I$2',
values => '=SUM_F_SCDLIB_DFF!$I$2',
); (Failed here As I need to load another worksheet data)
# Add the worksheet data the chart refers to.
my $data = [
[ 'Category', 2, 3, 4, 5, 6, 7 ],
[ 'Value', 1, 4, 5, 2, 1, 5 ],
];
$chartsheet->write( 'AB5', $data );
#$template->SaveAs('newfile.xlsx');
Related
I have a perl code that extract from .xls file. My .xls file is as below
NUMBER NAME ALPHABET
one Jane a
two Adam b
three Josh c
;four
five Agnes e
six Mary f
;seven
eight Lara h
I want to extract the info and only take column 1 and 2. My perl code is as below.
#!/usr/bin/perl
use warnings;
use strict;
use Spreadsheet::ParseExcel;
main ();
sub main {
my $filename = 'Book1.xls';
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse( $filename );
if ( !defined $workbook ) {
die "-E-: cannot parse <$filename>.\n ", $parser->error(), ".\n";
}
my $worksheet = $workbook -> Worksheet ( 'a' ) || die "-E-: cannot parse family pin list.\n";
my ( $row_min, $row_max ) = $worksheet-> row_range();
open ( my $file,"> output.txt");
for my $row ( 1 .. $row_max ) {
my #data;
for my $col ( 0 ) {
my $number = $worksheet-> get_cell( $row, $col );
if ( $number ) {
push #data, $number-> value();
}
else {
push #data, '';
}
}
for my $col ( 2 ) {
my $alphabet = $worksheet->get_cell( $row, $col );
if ( $alphabet ) {
push #data, $alphabet->value();
print $file "#data\n";
}
else {
push #data, '';
}
}
}
close $file;
print "done\n";
}
The result is
one a
two b
three c
;four
five e
six f
;seven
eight h
I want to remove the entire array that start with string ";". I extend my code like below
open ( my $file,"> output.txt");
for my $row ( 1 .. $row_max ) {
my #data;
for my $col ( 0 ) {
my $number = $worksheet-> get_cell( $row, $col );
if ( $number ) {
push #data, $number-> value();
}
else {
push #data, '';
}
}
for my $col ( 11 ) {
my $alphabet = $worksheet->get_cell( $row, $col );
if ( $alphabet ) {
push #data, $alphabet->value();
}
else {
push #data, '';
}
}
my #new_data = grep(!/;/, #data);
my #latest_data = grep ( $_ ne '', #new_data);
print $file "#latest_data\n";
}
close $file;
print "done\n";
}
The output result produce like below.
one a
two b
three c
five e
six f
eight h
I don't want to be empty space. How i want to eliminate the empty space that produce result as below?
one a
two b
three c
five e
six f
eight h
I also try doing like this, but the result is same.
for my $index (reverse 0..$#data) {
if ( $data[$index] =~ /^;/ ) {
splice(#data, $index, 1);
}
}
print $file "#data\n";
I hope you are looking for next
use warnings;
use strict;
#data=("one a", "two b","three c", ";four d","five e","six e","seven g","eight h")
for(#data){
next if (/^;/);
print $_,"\n";
}
let's get your data gist
#data=("one a", "two b","three c", ";four d","five e","six e","seven g","eight h")
for(#data){
s/^;.*//; # // <-- Put Replacer here between `//` , leave it to remove line
push(#new_data,$_)}
print "$_\n" for #new_data
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Below is the output I got when I use print Dumper(\%Data) in my code
{
"" => undef,
"123456789012:SRIRAMA" => [123456789012, "SRIRAMA", 856.06, 0, 0, 0],
"389252737122:RAMA" => [389252737122, "RAMA", 345.76, 0, 0, 0],
}
This data I have to write to an Excel file like below
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
The first two columns are one SQL result and rest of the columns are another SQL query result.
The first query result I have put in a map and searched based on the key in second query result and finally I got the output above.
Here, Number and Name—the first two columns—are keys for searching the data.
The code below is after getting the SQL result:
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;
The below code snippet I use when the records are not there pushing as zero.
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 );
The above print Dumper produces the information shown at the start of the question
Here is where the data is written into an Excel sheet
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++, $_ );
}
}
}
There's a lot to read there, but these ideas may help
Always use strict and use warnings at the top of every Perl program you write. It is invaluable for locating the more obvious bugs
Don't initialise arrays with #data = undef. If you want to empty an existing array then write #data = (). If you are declaring a new array then my #data will create a new empty array
The exact same advice applies to hashes, and that will be the reason for the "" => undef at the start of your %Data hash
Don't use my $dt = `date +%m-%d-%Y_%\I%\M`. You are starting a whole new shell process just to ask it the time. You should
use Time::Piece;
and
my $dt = localtime->strftime('%m-%d-%Y_%I%M');
The result from this won't need chomping
But are you sure you want %I? That gives you the 12-hour time, so the value will reset to zero at midday. %H gives you 24-hour time, and is much more likely to be useful
chomp is preferable to chop unless you're doing something unusual. chop will just remove the last character from a string, whatever it is, while chomp will remove the last character if it is a newline
for ( %Data ) { ... } will loop over the hash setting $_ to key1, val1, key2, val2 etc. That isn't what you want
In this case, since the information in the key is duplicated in the value, you probably want for ( values %Data ) { ... }. But that value is an array reference so no splitting is required
This is probably closer to what you need
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 );
}
}
}
I am new to Perl. I have excel file say "sample.xls" which looks like follows.
Sample.xls
There are about data of 1000 rows like this. I want to parse this file and write it in another file say "output.xls" with following output format.
output.xls
I have written a script in perl, however, it doesn't give me the exact output the way I want. Also, looks like the script is not very efficient. Can anyone guide me how I can improve my script as well as have my output as shown in "output.xls" ??
Here's the Script:
#!/usr/bin/perl –w
use strict;
use warnings;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use Spreadsheet::WriteExcel::Chart;
# Read the input and output filenames.
my $inputfile = "path/sample.xls";
my $outputfile = "path/output.xls";
if ( !$inputfile || !$outputfile ) {
die( "Couldn't find file\n" );
}
my $parser = Spreadsheet::ParseExcel->new();
my $inwb = $parser->parse( $inputfile );
if ( !defined $inwb ) {
die "Parsing error: ", $parser->error(), ".\n";
}
my $outwb = Spreadsheet::WriteExcel->new( $outputfile );
my $inws = $inwb->worksheet( "Sheet1" );
my $outws = $outwb->add_worksheet("Sheet1");
my $out_row = 0;
my ( $row_min, $row_max ) = $inws->row_range();
my ( $col_min, $col_max ) = $inws->col_range();
my $format = $outwb->add_format(
center_across => 1,
bold => 1,
size => 10,
border => 4,
color => 'black',
border_color => 'black',
align => 'vcenter',
);
$outws->write(0,0, "Item Name", $format);
$outws->write(0,1, "Spec", $format);
$outws->write(0,2, "First name", $format);
$outws->write(0,3, "Middle Name", $format);
$outws->write(0,4, "Last Name", $format);
$outws->write(0,5, "Customer Number", $format);
$outws->write(0,6, "Age", $format);
$outws->write(0,7, "Units", $format);
my $col_count = 1;
#$row_min = 1;
for my $inws ( $inwb->worksheets() ) {
my ( $row_min, $row_max ) = $inws->row_range();
my ( $col_min, $col_max ) = $inws->col_range();
for my $in_row ( 2 .. $row_max ) {
for my $col ( 0 .. 0 ) {
my $cell = $inws->get_cell( $in_row, $col);
my #fields = split /_/, $cell->value();
next unless $cell;
$outws->write($in_row,$col, $cell->value());
$outws->write($in_row,$col+1, $fields[1]);
}
}
for my $in_row ( 2 .. $row_max ) {
for my $col ( 1 .. 1 ) {
my $cell = $inws->get_cell( $in_row, $col);
my #fields = split /_/, $cell->value();
next unless $cell;
#$outws->write($in_row,$col+1, $cell->value());
$outws->write($in_row,$col+1, $fields[0]);
$outws->write($in_row,$col+2, $fields[1]);
$outws->write($in_row,$col+3, $fields[2]);
$outws->write($in_row,$col+4, $fields[3]);
}
}
for my $in_row ( 2 .. $row_max ) {
for my $col ( 2 .. 2 ) {
my $cell = $inws->get_cell( $in_row, $col);
my #fields = split /_/, $cell->value();
next unless $cell;
$outws->write($in_row,6, $cell->value());
}
}
for my $in_row ( 2 .. $row_max ) {
for my $col ( 3 .. 9 ) {
my $cell = $inws->get_cell( $in_row, $col);
next unless $cell;
}
}
for my $in_row ( 2 .. $row_max ) {
for my $col ( 10 .. 10 ) {
my $cell = $inws->get_cell( $in_row, $col );
next unless $cell;
$outws->write($in_row,7, $cell->value());
}
}
}
To get your output sorted, you need to collect all the information first before you are writing it out. Right now, you are doing a bit of jumping back and forth between rows and columns.
Here are some changes I would make to get it sorted, and make it more efficient (to read).
Create a data structure $data outside of your loop to store all the information.
If there is only one worksheet, you don't need to loop over sheets. Just work with one sheet.
Loop over the lines.
Inside that loop, use the code you have to parse the individual fields to just parse them. No 2..2 loops. Just a bunch of statements.
my #item_fields = split /_/, $inws->get_cell( $in_row, 0 ) || q{};
my #name_fields = split /_/, $inws->get_cell( $in_row, $col ) || q{};
Store them in $data per item.
push #{ $data } = [ $item_fields[0], ... ];
Done with the loop. Open the output file.
Loop over $data with a sort and write to the output file.
foreach my $row (sort { $a->[0] cmp $b->[0] } #{ $data } ) { ... }
Done.
I suggest you read up on sort and also check out perlref and perlreftut to learn more about references (data structures).
I am new to Spreadsheet::ParseExcel. I have a space-delimited file which I opened in Microsoft Excel and saved it as a XLS file.
I installed Spreadsheet::ParseExcel and used the example code in documentation to print the contents of the file. My objective is to build an array of some of the data to write to a database. I just need a little help building the array -- writing to a database I'll figure out later.
I'm having a hard time understanding this module -- I did read the documentation, but because of my inexperience I'm unable to understand it.
Below is the code I'm using for the output.
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Spreadsheet::ParseExcel;
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse( 'file.xls' );
if ( !defined $workbook ) {
die $parser->error(), ".\n";
}
for my $worksheet ( $workbook->worksheets() ) {
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $row ( $row_min .. $row_max ) {
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet->get_cell( $row, $col );
next unless $cell;
print "Row, Col = ($row, $col)\n";
print "Value = ", $cell->value(), "\n";
print "Unformatted = ", $cell->unformatted(), "\n";
print "\n";
}
}
}
And here is some of the output
Row, Col = (0, 0)
Value = NewRecordFlag
Unformatted = NewRecordFlag
Row, Col = (0, 1)
Value = AgencyName
Unformatted = AgencyName
Row, Col = (0, 2)
Value = CredentialIdnt
Unformatted = CredentialIdnt
Row, Col = (0, 3)
Value = ContactIdnt
Unformatted = ContactIdnt
Row, Col = (0, 4)
Value = AgencyRegistryCardNumber
Unformatted = AgencyRegistryCardNumber
Row, Col = (0, 5)
Value = Description
Unformatted = Description
Row, Col = (0, 6)
Value = CredentialStatusDescription
Unformatted = CredentialStatusDescription
Row, Col = (0, 7)
Value = CredentialStatusDate
Unformatted = CredentialStatusDate
Row, Col = (0, 8)
Value = CredentialIssuedDate
Unformatted = CredentialIssuedDate
My objective is to build an array of CredentialIssuedDate, AgencyRegistryCardNumber, and AgencyName. Once I grasp the concept of doing that, I can go to town with this great module.
Here's a quick example of something that should work for you. It builds an array #rows of arrays of the three field values you want for each worksheet, and displays each result using Data::Dumper. I haven't been able to test it, but it looks right and does compile
It starts by building a hash %headers that relates the column header strings to the column number, based on the first row in each worksheet.
Then the second row onwards is processed, extracting the cells in the columns named in the #wanted array, and putting their values in the array #row, which is pushed onto #rows as each one is accumulated
#!/usr/bin/perl
use strict;
use warnings;
use Spreadsheet::ParseExcel;
use Data::Dumper;
my #wanted = qw/
CredentialIssuedDate
AgencyRegistryCardNumber
AgencyName
/;
my $parser = Spreadsheet::ParseExcel->new;
my $workbook = $parser->parse('file.xls');
if ( not defined $workbook ) {
die $parser->error, ".\n";
}
for my $worksheet ( $workbook->worksheets ) {
my ( $row_min, $row_max ) = $worksheet->row_range;
my ( $col_min, $col_max ) = $worksheet->col_range;
my %headers;
for my $col ( $col_min, $col_max ) {
my $header = $worksheet->get_cell($row_min, $col)->value;
$headers{$header} = $col;
}
my #rows;
for my $row ( $row_min + 1 .. $row_max ) {
my #row;
for my $name ( #wanted ) {
my $col = $headers{$name};
my $cell = $worksheet->get_cell($row, $col);
push #row, $cell ? $cell->value : "";
}
push #rows, \#row;
}
print Dumper \#rows;
}
I was able to resolve this by using the Spreadsheet::BasicReadNamedCol module
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Spreadsheet::BasicReadNamedCol;
my $xlsFileName = 'shit.xls';
my #columnHeadings = (
'AgencyName',
'eMail',
'PhysicalAddress1',
'PhysicalAddress2'
);
my $ss = new Spreadsheet::BasicReadNamedCol($xlsFileName) ||
die "Could not open '$xlsFileName': $!";
$ss->setColumns(#columnHeadings);
# Print each row of the spreadsheet in the order defined in
# the columnHeadings array
my $row = 0;
while (my $data = $ss->getNextRow())
{
$row++;
print join('|', $row, #$data), "\n";
}
I have a problem with merging two dynamically created Excel 2007 files.
My files are created with the Perl Module Excel::Writer::XLSX on Solaris.
Say I have two files, fileA.xlsx and fileB.xlsx. Now I want to merge them together (fileA + fileB => fileC).
It is not really possible at this time to append fileB to fileA. This is a limitation of Excel::Writer::XLSX, which can only create new files.
Both .xlsx files can be opened without complaints in Excel 2007, in LibreOffice 3 (on linux), and (with the help of Microsoft's xlsx to xls converters) even in Excel 2003.
However, when I open them with perl (using the module Spreadsheet::XLSX), the contents of the header row, (row 0) are always skipped;
# ...
foreach my $infile (#infiles) {
my $excel = Spreadsheet::XLSX->new($infile);
my $i = 0;
foreach my $sheet ( #{ $excel->{Worksheet} } ) {
printf( "Infile '$infile', Sheet $i: %s\n", $sheet->{Name} );
$sheet->{MaxRow} ||= $sheet->{MinRow};
print "$infile: " . $sheet->{MaxRow} . " rows\n";
print "data starts at row: " . $sheet->{MinRow} . ". \n";
next unless $i == 0; # only copy data from the first sheet (for speed)
my $start_row = $sheet->{MinRow};
foreach my $row ( $start_row .. $sheet->{MaxRow} ) {
$sheet->{MaxCol} ||= $sheet->{MinCol};
foreach my $col ( $sheet->{MinCol} .. $sheet->{MaxCol} ) {
my $cell = $sheet->{Cells}[$row][$col];
if ($cell) {
# do something with the data
# ...
# write to outfile
$excel_writer->sheets(0)->write($dest_row, $col, $cell->{Val} )
}
}
}
}
}
Now, the ouput of this code fragment is always
data starts at row: 1.
But this is not true, it starts at row 0. If I manually go to read in data from row0, $cell is undefined (although it shouldn't be).
Interestingly, when I open the file in Microsoft Excel, and change it trivially, (say, by adding a blank space to one of the cell values in the header row), and save the file, then the header row IS found by the code above.
data starts at row: 0.
By the way, when I open, change, save the file in LibreOffice, there are numerous warnings concerning date values when I re-read them with the code above. (Thus, datetime values seem to be saved slightly incorrectly by LibreOffice).
The code that produces the files looks like this (note: some vars are defined outside of this sub):
sub exportAsXLS {
#require Spreadsheet::WriteExcel;
require Excel::Writer::XLSX;
my ( $data, $dir, $sep, #not2export ) = #_;
my $val;
my $EXCEL_MAXROW = 1048576;
return undef unless $data;
return "." unless scalar #$data > 0;
my $time = time2str( "%Y%m%d_%H%M%S", time() );
my $file = "$outdir/$dir/${host}_${port}-${time}.xlsx";
#my $workbook = Spreadsheet::WriteExcel->new($file);
my $workbook = Excel::Writer::XLSX->new($file);
$workbook->set_optimization();
my $worksheet = $workbook->add_worksheet();
# Set the default format for dates.
#my $date_formatHMS = $workbook->add_format( num_format => 'mmm d yyyy hh:mm AM/PM' );
#my $date_formatHMS = $workbook->add_format( num_format => 'yyyy-mm-ddThh:mm:ss.sss' );
my %formats;
$formats{date_HM} = $workbook->add_format( num_format => 'yyyy-mm-ddThh:mm' );
$formats{date_HMS} = $workbook->add_format( num_format => 'yyyy-mm-ddThh:mm:ss' );
$formats{num} = $workbook->add_format();
$formats{num}->set_num_format();
$formats{headline} = $workbook->add_format();
$formats{headline}->set_bold();
$formats{headline}->set_num_format('#');
# Format as a string. use the Excel text format #:
# Doesn't change to a number when edited
$formats{string} = $workbook->add_format( num_format => '#' );
$worksheet->set_row( 0, 15, $formats{headline} );
my $row = 0;
my $col = 0;
for ( my $r = -1 ; $r < #$data && $r < $EXCEL_MAXROW ; $r++ ) {
for ( my $i = 0 ; $i < #$column ; $i++ ) {
next if grep( $_ eq $column->[$i], #not2export );
my $val = $data->[$r]{ $column->[$i] };
my $t = int $type->[$i];
if ( $r < 0 ) {
#warn " type: $type->[$i] , ";
# Erste Zeile = Spaltennamen ausgeben
$worksheet->write_string( $row, $col++, $column->[$i], $formats{string});
#$worksheet->write_comment( 0, 0, "\x{263a}" ); # Smiley
#$worksheet->write( $row, $col++, $column->[$i], $formats{headline} );
} elsif ( ( $t == 11 ) or ( $t == 9 ) ) {
# 11 - Der Wert ist ein Datum, im SHORT Format, 9- long
$val = time2str( "%Y-%m-%dT%H:%M:%S", str2time( $data->[$r]{ $column->[$i] } ) );
$worksheet->write_date_time( $row, $col++, $val, $formats{date_HMS} );
} else {
$worksheet->write( $row, $col++, $val );
}
}
$col = 0;
$row++;
}
return $file;
}
The difference between the files is as follows.
On the left is the file that Excel::Writer::XLSX produces. ON the right is the file that MS Excel 2003 produces after a trivial change to the header row. the row header data is refactored, externalized to a different file, sharedStrings.xml
Which looks like this.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="5" uniqueCount="5">
<si>
<t>SITE</t>
</si>
<si>
<t>LOG_DATE</t>
</si>
<si>
<t>KTZI201_WF_TEMPERATUR</t>
</si>
<si>
<t>KTZI300_TEMP_RESERVOIR</t>
</si>
<si>
<t>XPEDITION</t>
</si>
</sst>
Spreadsheet::XLSX can read the header if the .xlsx file is formatted as shown on the right half of the picture, but skips the header row when formatted as shown on the left half.
When I run your program against the output of this Excel::Writer::XLSX example program it correctly reports data in the first row (row == 0):
Infile 'a_simple.xlsx', Sheet 0: Sheet1
a_simple.xlsx: 10 rows
data starts at row: 0.
Perhaps you should double check the program that is producing the input files.
Also, make sure you are on the latest version of Excel::Writer::XLSX.