meisterperl has asked for the wisdom of the Perl Monks concerning the following question:

I have 20 files that I ran a perl parser on to delimit. (I had to do this because they were fixed width files, but excel did not import them properly.. ugh..) now I have a perl script which builds an excel document, names 20 sheets in that document based on the filenames of the parsed files. I have a regular expression which delimits the files, and drops them into an array.. @parsed_file. What I need now is a way to put this data into their respective excel sheets, while preserving the delimited format. Unfortunately the only way I know to insert this is to use $Sheet->Range("a1")->{'Value'} = "@file"; yada yada yada... This only does one thing for me.. Inserts the entire file array into the first row, but of course, it's not delimited... I am trying to avoid a complicated solution, I.E. putting data into excel row by row from a nasty regex.. Anyone know any quick way to use OLE to accomplish my goal? I have searched far and wide, but probably stopped just short of my goal, so now my solution rests with you.. I am using
use Win32::OLE qw(in with);
  • Comment on inserting parsed results into excel rows and columns in delimited format

Replies are listed 'Best First'.
Re: inserting parsed results into excel rows and columns in delimited format
by jmcnamara (Monsignor) on Feb 11, 2005 at 00:15 UTC

    If you need to write an array of data or an array of arrays in Excel then it is much more effiecient to write the data as a single Range() rather than writing it cell by cell.

    Here is a short example for a single row. Note that you must specify the range in A1 format and that the data must be passed as an array ref.

    #!/usr/bin/perl -w use strict; use Cwd; use Win32::OLE; my $application = Win32::OLE->new("Excel.Application"); my $workbook = $application->Workbooks->Add; my $worksheet = $workbook->Worksheets(1); my @data = ('maggie', 'milly', 'molly', 'may'); $worksheet->Range('A1:D1')->{Value} = \@data; $workbook->SaveAs({FileName => cwd() . '/test.xls'}); $workbook->Close;

    For a 2D array the above example would change as follows:

    my @data = ( ['maggie', 'milly', 'molly', 'may' ], [13, 14, 15, 16 ], ['shell', 'star', 'crab', 'stone'] ); $worksheet->Range('A1:D3')->{Value} = \@data;

    For the sake of comparison here is a similar example using Spreadsheet::WriteExcel:

Re: inserting parsed results into excel rows and columns in delimited format
by Trimbach (Curate) on Feb 10, 2005 at 22:40 UTC
    Once your data is in @file why not something like this:
    my ($row, $col) = ("A", 1); for (@file) { $Sheet->Range($row.$col)->{'Value'} = $_; $col++ }
    Of course, this only handles one row. You can increment through the rows as well, using the automagical ++ incrementer on $row. BTW, when you have delimited files you should be thinking "split/join" and if you have fixed-width files you should be thinking "unpack/pack". Regex's should be your last choice in those situations. :-)

    Gary Blackburn
    Trained Killer