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


In reply to Transforming an Excel Spreadsheet into an Access Table by peace

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • 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:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.