making cells blank in and excel sheet using perl - perl

I have an excel sheet to which I need to empty some cells
So far this is what it looks like:
I open the sheet, and check for cells not empty in column M.
I add those cells to my array mistake
and then I would like to make black all those cells and save the file (this step not working), as that file needs to be the input to anotherprogram/
thanks!
$infile = $ARGV[0];
$columns = ReadData($infile) or die "cannot open excel table\n\n";
print "xls sheet contains $columns->[1]{maxrow} rows\n";
my $xlsstartrow;
if ( getExcel( A . 1 ) ne "text" ) {
$xlsstartrow = 2;
}
else
{
$xlsstartrow = 4;
}
check_templates();
print "done";
sub check_templates {
for ( $row = $xlsstartrow ; $row < ( $columns->[1]{maxrow} + 1 ) ; $row++ ) {
if (getExcel(M . $row) ne "" ){
$cell = "M" . $row ;
push(#mistakes,$cell);
}
}
rewritesheet(#mistakes);
}
sub rewritesheet {
my $FileName = $infile;
my $parser = Spreadsheet::ParseExcel::SaveParser->new();
my $template = $parser->Parse($FileName);
my $worksheet = $template->worksheet(0);
my $row = 0;
my $col = 0;
# Get the format from the cell
my $format = $template->{Worksheet}[$sheet]
->{Cells}[$row][$col]
->{FormatNo};
foreach (#mistakes){
$worksheet->AddCell( $_, "" );
}
$template->SaveAs($infile2);`

Empty column values in an Excel sheet and save the result?
If the whole purpose of your program is to delete all column M values from a .xls file, then the following program (adopted from your program) will do exactly that:
use strict;
use warnings;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
my $infile = $ARGV[0];
(my $infile2 = $infile) =~ s/(\.xls)$/_2$1/;
my $parser = Spreadsheet::ParseExcel::SaveParser->new();
my $workbook = $parser->Parse($infile);
my $sheet = $workbook->worksheet(0);
print "xls sheet contains rows \[0 .. $sheet->{MaxRow}\]\n";
my $startrow = $sheet->get_cell(0, 0) eq 'text' ? 4-1 : 2-1;
my $col_M = ord('M') - ord('A');
for my $row ($startrow .. $sheet->{MaxRow}) {
my $c = $sheet->get_cell($row, $col_M);
if(defined $c && length($c->value) > 0) { # why check?
$sheet->AddCell($row, $col_M, undef) # delete value
}
}
$workbook->SaveAs($infile2);
print "done";
But, if you really want to clear out column M only, why would you test for values? You could just overwrite them without test. Maybe thats not all your program is required to perform? I don't know.
Regards
rbo

Related

Spreadsheet::ParseExcel building an array or hash

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";
}

Combine an Array object with scalar value within a scalar? Perl

I'm trying to combine an item from an Array list with a scalar $range. Here's how I'm trying to do it.
my $rowinc = 2;
my $colarray = #collet[0];
my $range = $colarray $rowinc;
chomp $range;
$sheet->Range($range)->{Value} = $ir;
shift #collet;
$sheet->Range($range)->{Value} = $sn;
shift #collet;
$sheet->Range($range)->{Value} = (join(", ", #parts));
shift #collet;
$sheet->Range($range)->{Value} = $ref;
$rowinc++;
unshift #collet, 'C';
unshift #collet, 'B';
unshift #collet, 'A';
I've tried multiple ways of doing this and to no avail. Here's the error I receive while running this particular snippet.
Scalar found where operator expected at gen1.pl line 87, near "$colarray $rowinc
"
(Missing operator before $rowinc?)
syntax error at gen1.pl line 87, near "$colarray $rowinc"
Execution of gen1.pl aborted due to compilation errors.
Press any key to continue . . .
I'm assuming that the array can't be used in that manner to denote the value for $range. The problem I'm running into is that I am using Win32::OLE to manage my excel spreadsheets because it gives me the ability to open an already existing spreadsheet. But the drawback is I cannot enter my cell ranges as integers ($row,$col) I've tried this just incrementing $row and $col I want to be able to manage this effectively instead of using a bunch of if else and what not.
What I've tried to do is my #collet = ('A', 'B', 'C', 'D');
tells me which column to print in if I start at 0 it should start printing in A col. which is good and then every time it prints in a column it shifts right so now #collet[0] should be 'B'. I know this isn't the best method but I've changed my original method to this in hopes to solve the issue. any help would be awesome!
Here's my full script for some context.
#!C:\Perl\bin
#manage IR/SRN/Parts Used
#Written for Zebra
#Author Dalton Brady
#Location Bentonville AR
use strict;
use warnings;
use POSIX qw(strftime);
use Win32::OLE;
use Win32::OLE qw( in with);
use Win32::OLE::Const 'Microsoft Excel';
use Win32::OLE::Variant;
$Win32::OLE::Warn = 3; #Die on errors
#different types of units worked on, trying to name the worksheet
#after one depending on user input have yet to add that func.
my #uut = ('VC5090', 'MK2046', 'MK2250', 'MK4900', '#pos');
my $ref = strftime '%Y-%m-%d', localtime(); #create the datestamp
my $i = 0; #increment counter for why loop
my $n = 0; #increment for do until loop
my $xfile = 'X:\dataTest\data.xls'; #location of excel file
my $book; #place for the workbook to exist
my $sheet; #worksheet exists here
my $ex; #a place to hold the excel application
my $row = 2; #track row in which data will
#be placed with the do until loop
my $col = 1;
my #parts ; # store the different parts as a list within
# an area (to be written to the spreadsheet)
my #talk = ( 'IR:', 'SN:',
'#of Parts Used: ', 'PN:',
'Units Completed: ');
my #collet = "A" .. "Z"
# start an instance of excel
$ex = Win32::OLE->new('Excel.Application');
$ex->{DisplayAlerts} = 0; #turn off alerts/textboxes/saveboxes
#check to see if excel file exists if yet open it, if not create it
if (-e $xfile) {
$book = $ex->Workbooks->Open($xfile);
$sheet = $book->Worksheets("Test");
$sheet->Activate();
}
else {
$book = $ex->Workbooks->Add()
; #create new workbook to be used because we couldn't find one
#########SETUP YOUR EXCEL FILE#############
$sheet = $book->Worksheets("Sheet1");
$sheet->Activate();
$sheet->{Name} = "Test";
$sheet->Cells("a1")->{HorizontalAlignment} = x1HAlignCenter;
$sheet->Cells("b1")->{HorizontalAlignment} = x1HAlignCenter;
$sheet->Cells("c1")->{HorizontalAlignment} = x1HAlignCenter;
$sheet->Columns("a")->{ColumnWidth} = 20;
$sheet->Columns("b")->{ColumnWidth} = 20;
$sheet->Columns("c")->{ColumnWidth} = 30;
$sheet->Range("a1")->{Value} = "IR Number";
$sheet->Range("b1")->{Value} = "Serial Number";
$sheet->Range("c1")->{Value} = "Parts Used";
$sheet->Range("d1")->{Value} = "Date";
$book->SaveAs($xfile); #Save the file we just created
}
# ask for how many units user will be
# scanning or has completed to be scanned
print $talk[4] ;
#unit count tracker, determines how many times the do while loop runs
my $uc = <>;
do {
print $talk[0]; #ask for the IR number
my $ir = <>;
chomp $ir;
print $talk[1]; #ask for uut Serial Number
my $sn = <>;
chomp $sn;
print $talk[2];
# ask for the number of parts used, to regulate
# the parts list storage into the #parts array
my $pu = <>;
while ($i < $pu) {
print $talk[3];
my $scan = <>;
chomp $scan;
push #parts, $scan;
$i++;
}
my $rowinc = 2;
my $colarray = #collet[0];
my $range = $colarray $rowinc;
chomp $range;
$sheet->Range($range)->{Value} = $ir;
shift #collet;
$sheet->Range($range)->{Value} = $sn;
shift #collet;
$sheet->Range($range)->{Value} = (join(", ", #parts));
shift #collet;
$sheet->Range($range)->{Value} = $ref;
$rowinc++;
unshift #collet, 'C';
unshift #collet, 'B';
unshift #collet, 'A';
} until ($n == $uc);
# save and exit
$book->SaveAs($xfile);
$book = $ex->WorkBooks->Close();
undef $book;
undef $ex;

print n users and their value using perl

I am new to perl require your help to build a logic.
I have some let say 10 files in a directory, each file has some data like below. Each file contain lines depends upon the number of users setting. For example if 4 users are there then 4 lines will get printed from the server.
1405075666889,4044,SOA_breade,200,OK,Thread Group 1-1,text,true,623,4044
1405075666889,4041,SOA_breade,200,OK,Thread Group 1-1,text,true,623,4041
1405075666889,4043,SOA_breade,200,OK,Thread Group 1-1,text,true,623,4043
1405075666889,4045,SOA_breade,200,OK,Thread Group 1-1,text,true,623,4044
I want to some piece of logic that should create single file in a output directory and that file should contain 10 lines
Min_Value, Max_Value, Avg_Value, User1, User2, User3......User4
and their corresponding values from second line in this case corresponding values are coming from second column.
Min_Value, Max_Value, Avg_Value, User1, User2, User3......User4
4.041,4.045,4.044,4.041,4.043,4.045
.
.
.
.
.
10th file data
Here is my code... It is working however I am not getting how to print user1, user2... in sequence and its corresponding values
my #soaTime;
my #soaminTime;
my #soamaxTime;
my #soaavgTime;
my $soadir = $Json_Time;
foreach my $inputfile (glob("$soadir/*Overview*.txt")) {
open(INFILE, $inputfile) or die("Could not open file.");
foreach my $line (<INFILE>) {
my #values = split(',', $line); # parse the file
my $time_ms = $values[1]/1000;
push (#soaTime, $time_ms);
}
my $min = min #soaTime;
push (#soaminTime, $min);
print $soaminTime[0];
my $max = max #soaTime;
push (#soamaxTime, $max);
sub mean { return #_ ? sum(#_) / #_ : 0 };
#print mean(#soaTime);
push (#soaavgTime, mean());
close(INFILE);
}
my $outputfile = $report_path."abc.txt";
open (OUTFILE, ">$outputfile");
print OUTFILE ("Min_Value,Max_Value,User1,User2,User3,User4"."\n"); # Prining the data
for (my $count = 0; $count <= $#soaTC; $count++) {
print OUTFILE("$soaminTime[0],$soamaxTime[0],$soaTime[0],$soaTime[1],$soaTime[2],$soaTime[3]"."\n" ); #Prining the data
}
close(OUTFILE);
Please help.
is it?
use strict;
use List::Util qw( min max );
my $Json_Time="./test";
my $report_path="./out/";
my #soaTime;
my #soaminTime;
my #soamaxTime;
my #soaavgTime;
my #users;
my $maxusers;
my $soadir = $Json_Time;
foreach my $inputfile (glob("$soadir/*Overview*.txt")) {
open(INFILE, $inputfile) or die("Could not open file.");
my $i=0;
my #m_users;
my #m_soaTime;
foreach my $line (<INFILE>) {
my #values = split(',', $line); # parse the file
my $time_ms = $values[1]/1000;
push (#m_soaTime, $time_ms);
$i++;
push(#m_users, "User".$i);
}
push(#soaTime,\#m_soaTime);
if ($maxusers<$#m_users) {
#users=#m_users;
$maxusers=$#m_users;
}
my $min = min(#m_soaTime);
push (#soaminTime, $min);
my $max =max(#m_soaTime);
push (#soamaxTime, $max);
sub mean { return #_ ? sum(#_) / #_ : 0 };
push (#soaavgTime, mean());
close(INFILE);
}
my $outputfile = $report_path."abc.txt";
open (OUTFILE, ">$outputfile");
print OUTFILE "Min_Value,Max_Value,Avg_Value,".join(',',#users)."\n"; # Prining the data
for (my $count = 0; $count <= $#soaavgTime; $count++) {
print OUTFILE $soaminTime[$count].","
.$soamaxTime[$count].","
.$soaavgTime[$count].","
.join(',',#{$soaTime[$count]})
."\n"; #Prining the data
}
close(OUTFILE);

How I can take the coordinates of a block of numbers?

I have a problem tha bothers me a lot...
I have a file with two columns (thanks to your help in a previous question) like:
14430001 0.040
14430002 0.000
14430003 0.990
14430004 1.000
14430005 0.050
14430006 0.490
....................
the first column is coordinates the second probabilities.
I am trying to find the blocks with probability >=0.990 and to be more than 100 in size.
As output I want to be like this:
14430001 14430250
14431100 14431328
18750003 18750345
.......................
where the first column has the coordinate of the start of each block and the second the end of it.
I wrote this script:
use strict;
#use warnings;
use POSIX;
my $scores_file = $ARGV[0];
#finds the highly conserved subsequences
open my $scores_info, $scores_file or die "Could not open $scores_file: $!";
#open(my $fh, '>', $coords_file) or die;
my $count = 0;
my $cons = "";
my $newcons = "";
while( my $sline = <$scores_info>) {
my #data = split('\t', $sline);
my $coord = $data[0];
my $prob = $data[1];
if ($data[1] >= 0.990) {
#$cons = "$cons + '\n' + $sline + '\n'";
$cons = join("\n", $cons, $sline);
# print $cons;
$count++;
if($count >= 100) {
$newcons = join("\n", $newcons, $cons);
my #array = split /'\n'/, $newcons;
print #array;
}
}
else {
$cons = "";
$count = 0;
}
}
It gives me the lines with probability >=0.990 (the first if works) but the coordinates are wrong. When Im trying to print it in a file it stacks, so I have only one sample to check it.
Im terrible sorry if my explanations aren't helpful, but I am new in programming.
Please, I need your help...
Thank you very much in advance!!!
You seem to be using too much variables. Also, after splitting the array and assigning its parts to variables, use the new variables rather than the original array.
sub output {
my ($from, $to) = #_;
print "$from\t$to\n";
}
my $threshold = 0.980; # Or is it 0.990?
my $count = 0;
my ($start, $last);
while (my $sline = <$scores_info>) {
my ($coord, $prob) = split /\t/, $sline;
if ($prob >= $threshold) {
$count++;
defined $start or $start = $coord;
$last = $coord;
} else {
output($start, $last) if $count > 100;
undef $start;
$count = 0;
}
}
output($start, $last) if $count > 100;
(untested)

Problems reading header line from my Excel 2007 files created with Perl

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.