Reputation: 1019
firstly thanks for reading this. I have a small script that collects various txt files and drops them into an Excel worksheet, I previously used Spreadsheet::WriteExcel to do this, and all worked fine. However as I developed the script it became more obvious that I should use Win::OLE to perform this function as I would prefer to use a template Excel file (with pre existing formulas) which I could add these txt files to as worksheets.
I am struggling with the change from Spreadsheet::WriteExcel to Win::OLE with the paste function to place the text files into a spreadsheet. Here's the code that did work (from the point of adding the txt file @ line >>>> $wrksheet->write_col)
......
my $workbook = Spreadsheet::WriteExcel->new("resultsbook.xls");
(my $sheetname = $file) =~s/\.\w+//;
my $wrksheet = $workbook->add_worksheet($sheetname);
$wrksheet->write_col( 0, 0, readfile($file)); # <-- Old write line
}
}
sub readfile {
my @textfilecontent = ();
open my $fh, '<', shift() or die "can't open file:$!";
while (<$fh>) {
chomp;
push @textfilecontent, [split(/\t/)];
}
return \@textfilecontent;
}
But I have since changed to using OLE and I get as far as naming the Excel worksheet tabs but I am struggling to workout how to paste the extracted txt into a worksheet here (using the same subroutine above @ line >>>> $sheet->Cells(0,0)->{Value} = readfile($file); )...
my $sheet = $book->Worksheets->Add({After => $book->Worksheets(1)})
$sheet->{Name} = $sheetname;
$sheet->Cells(0,0)->{Value} = readfile($file); # <-- New write line
###$sheet->write_col( 0, 0, readfile($file));#### Old method
}
}
sub readfile {
my @textfilecontent = ();
open my $fh, '<', shift() or die "can't open file:$!";
while (<$fh>) {
chomp;
push @textfilecontent, [split(/\t/)];
}
return \@textfilecontent;
}
I get the following error whel I run this script...
Win32::OLE(0.1711) error 0x800a03ec in METHOD/PROPERTYGET "Cells" at line...
Any pointers/advice would be greatly appreciated.
Thanks, MikG
Upvotes: 2
Views: 1821
Reputation: 1560
Take a look at the Range function. e.g.
my $data = readfile($file);
# figure out size of data and adjust "A1:Z20" below accordingly
$sheet->Range("A1:Z20")->{Value} = $data;
Edit:
I haven't used Win32::OLE so this would be my hack: Use this version of your readfile function to pass back the number of rows and columns:
sub readfile {
my @textfilecontent = ();
open my $fh, '<', shift() or die "can't open file:$!";
my ($rows, $cols) = (0,0);
while (<$fh>) {
chomp;
my @row = split(/\t/);
$cols = scalar(@row) if scalar(@row) > $cols;
push @textfilecontent, \@row;
$rows++;
}
return (\@textfilecontent, $rows, $cols);
}
You may want to modify this to pad (with "") rows that do not have the same number of columns as the one with the max number of columns. There is a function in Spreadsheet::WriteExcel::Utility that can convert row/columns to the A1 notation. Include it in your script like this:
use Spreadsheet::WriteExcel::Utility qw(xl_rowcol_to_cell);
Then your main routine would look like this:
my ($data, $rows, $cols) = readfile($file);
my $endCell = xl_rowcol_to_cell($rows, $cols);
$sheet->Range("A1:$endCell")->{Value} = $data;
Upvotes: 1
Reputation: 35198
I don't have Excel and use LibreOffice
, so I've always used Spreadsheet::WriteExcel
instead of Win32::OLE
However, you're attempting to assign a two dimensional array to a single cell. Win32::OLE #Examples
shows a different way to do this:
# write a 2 rows by 3 columns range
$sheet->Range("A8:C9")->{Value} = [[ undef, 'Xyzzy', 'Plugh' ],
[ 42, 'Perl', 3.1415 ]];
Upvotes: 0