It's been a while since I reviewed the available stuff out there but one of the things that Spreadsheet::Reader::ExcelXML solves is access to xlsm files. This is partly because potentially dangerous macros can be stored in spreadsheets with the xlsm extension. Most other packages avoid this risk by intentionally not allowing that extension. Spreadsheet::Reader::ExcelXML avoids the risk of malicious macros by simply not providing access to the macro binary subfile through the interface. The package is old though and somewhat brittle at this point. However, It sounds like Håkon Hægland has expressed an interest in helping with the brittleness so good news!
To potentially solve the OP question see the code below: From Spreadsheet::Reader::ExcelXML::Worksheet
Also review the methods 'fetchrow_array' and 'fetchrow_hashref'
use strict;
use warnings;
use Data::Dumper;
use Spreadsheet::Reader::ExcelXML;
my $workbook = Spreadsheet::Reader::ExcelXML->new( #similar style to Spreadsheet::XLSX
file => 't/test_files/TestBook.xlsx',# in the test folder of this package
group_return_type => 'value',
);
if ( !$workbook->file_opened ) {
die $workbook->error(), ".\n";
}
my $worksheet = $workbook->worksheet( 'Sheet5' );
$worksheet->set_custom_formats( {
2 =>'yyyy-mm-dd',
} );
my $value;
while( !$value or $value ne 'EOF' ){
$value = $worksheet->fetchrow_arrayref;
print Dumper( $value );
}
###########################
# SYNOPSIS Output
# $VAR1 = [ 'Superbowl Audibles', 'Column Labels' ];
# $VAR1 = [ 'Row Labels', 2016-02-06', '2017-02-14', '2018-02-03', 'Grand Total' ];
# $VAR1 = [ 'Blue', '10', '7', '', '17' ];
# $VAR1 = [ 'Omaha', '', '', '2', '2' ];
# $VAR1 = [ 'Red', '30', '5', '3', '38' ];
# $VAR1 = [ 'Grand Total', '40', '12', '5', '57' ];
# $VAR1 = 'EOF';
###########################