In my efforts to get more comfortable with Perl, I wrote the script below that
converts a simple Excel spreadsheet into a simple Access table. It's a panless
way to get some Excel data into an Access database, without having to open either app.
I took the Win32::OLE tack since I'm pretty comfortable with ADODB and just wanted
to get something up and running quickly. <digress> I had trouble finding an ODBC driver to
use with DBI, e.g., "DBI->connect("dbi:ODBC:$DSN", '','')" would always give me an
"install_driver(ODBC) failed:..." error message even after I installed the ODBC module. </digress>
The solution is not especially robust:
(1) all sheets are assumed to have the same columns
(2) all Excel data is rendered as of "text" (varchar) data type in Access
(3) the only error trapping happens, if at all, at the end with only the last error
identified.
There are probably other flaws that people will spot. If you see one or experience one
when you run it, I'd be interested to hear about it. If you spot any virtues in this,
only my second Perl script, I'd like to hear about them too (:-).
Peace,
-- Jack
# Adapted from and inspired by
# http://www.perlmonks.com/?node_id=514384, Dec 06, 2005, awohld
use strict;
use Spreadsheet::ParseExcel::Simple;
use Win32::OLE;
# ---------------------------------------------------------
# Parameter 1: Name of Excel File to be Access-ized
my $ExcelFile = $ARGV[0];
# Parameter 2: Name of Table to be created
my $AccessTable = $ARGV[1];
# Parameter 3: Name of predefined DSN for preexisting Access .mdb file
my $DSN = $ARGV[2];
# ---------------------------------------------------------
my $first_row = 1;
my @fields;
my $SQL;
my $conn = Win32::OLE->new('ADODB.Connection');
$conn->open($DSN);
my $xls = Spreadsheet::ParseExcel::Simple->read($ExcelFile);
foreach my $sheet ($xls->sheets)
{
while ($sheet->has_data)
{
my @data = $sheet->next_row;
# For the first row, create a new table and use its data for
+the header row
if ($first_row)
{
foreach my $head (@data)
{
$head =~ s/[^a-zA-Z]//g;
push(@fields, $head);
}
$SQL = "CREATE TABLE `".
$AccessTable .
"` (" .
join( " varchar(255),", @fields) .
" varchar(255))";
$conn->execute($SQL);
$first_row = 0;
}
# Insert all other row data in the table
else
{
$SQL = "INSERT INTO " .
$AccessTable .
" (" .
join (',',@fields) .
") VALUES (\'" .
join ('\',\'', @data) .
"');";
$conn->execute($SQL);
}
}
}
print "That didn't go so well: ",
Win32::OLE->LastError(),
"\n"
if (Win32::OLE->LastError());
$conn->close if ($conn);
exit;
Edit: g0n - moved from SoPW to CUFP
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.