If all you want to do is read the whole excel sheet, here's how I go about
it without OLE.
The only thing that keeps annoying me is that even though I specify
FIRSTROWHASNAMES=0,
with my Excel drivers, it still won't return the topmost row. But reading
huge files is
not an issue - all it takes is the "... $db->Data() while $db->FetchRow ();"
bit in
the second-to-last line. The rest is preparation.
$excelfile = "c:\\my documents\\testfile.xls";
use Win32::ODBC;
$XLDrv = "";
END {
Win32::ODBC::ConfigDSN (ODBC_REMOVE_DSN, $XLDrv, "DSN=$dsn")
if $XLDrv;
}
$excelfile =~ /((?<!:)\\)?([^\\]+)$/;
$path = $`; # path without trailing backslash except if root
(x:\)
$dsn = $2; # filename without path - used as dsn
# create a temp DSN
%Drivers = Win32::ODBC::Drivers()
or die "can\'t get list of ODBC drivers - aborting\n";
($XLDrv) = grep /excel/i, keys %Drivers;
die "don't have an ODBC driver for Excel files - aborting\n"
unless $XLDrv;
Win32::ODBC::ConfigDSN (ODBC_REMOVE_DSN, $XLDrv, "DSN=$dsn");
Win32::ODBC::ConfigDSN (ODBC_ADD_DSN, $XLDrv,
("DSN=$dsn", "Description=$dsn", "DBQ=$dsn", "DEFAULTDIR=$path",
"FIRSTROWHASNAMES=0", "UID=", "PWD="))
or die "can't create ODBC DSN for $dsn - aborting\n";
$db = new Win32::ODBC ($dsn)
or die "cannot access $dsn\n";
# read "table" name of current sheet
$db->Catalog ("", "", "%", "");
$db->FetchRow ();
%Data = $db->DataHash ();
$Data{'TABLE_NAME'} =~ /([^']+)/;
# select data
# need [] around table name because it's like "Sheet1$"
$db->Sql ($_ = "select * from [$1]")
and die "'$_' returned ", $db->Error, "\n";
# retrieve data
print join "; ", $db->FieldNames (), "\n";
print join "; ", $db->Data(), "\n" while $db->FetchRow ();
$db->Close ();