I am looking for some examples/advice on how to write a Perl script
to read data from an Excel file by sheet name and not sheet number.
This is an example with Spreadsheet, but it doesn't work with sheet name:
#Code Perl :
use Spreadsheet::Read qw(ReadData);
{
my $book = ReadData ("test.xls");
my $sheet = $book->sheet ("name_3");
my #rows = rows ($sheet);
...
}
Can you help me please?
It works for me when I use the OO API:
use warnings;
use strict;
use Spreadsheet::Read;
my $book = Spreadsheet::Read->new('test.xls');
my $sheet = $book->sheet('Sheet1');
my #rows = $sheet->rows();
Related
I'd like to ask you for a help how to save bold text into variable from Excel via Powershell. I'm not a full time developer, just trying to make my life easier with Powershell :)
This is what I have (it's not a lot unfortunately):
# Open file test.xlsx
$excel = Open-ExcelPackage -Path './test.xlsx'
# Copy content of the worsksheet 'Sheet1'
$worksheet = $excel.Workbook.Worksheets['Sheet1']
# Copy specific cell value to the variable
$String = $worksheet.Value
$StringBold =
# Close Excel file
Close-ExcelPackage -ExcelPackage $Excel
I'm able to save content of the file test.xlsx into &worksheet variable. In some cell might be the string 'How are you today Marek?' So the next step should be to save only word Marek into the variable $StringBold
Thanks a lot for any advice.
After some research this seems possible using the ImportExcel Module, you just need to enumerate each cell and then access their .RichText property. Here is an example of how you can achieve it:
$xlsx = Open-ExcelPackage path\to\my.xlsx
$sheet = $xlsx.Workbook.Worksheets['mySheetName']
foreach($cell in $sheet.Cells) {
foreach($richText in $cell.RichText) {
if($richText.Bold) {
[pscustomobject]#{
Address = $cell.Address
Value = $richText.Text
}
}
}
}
Using this Sheet as an example:
The result with this code becomes:
Address Value
------- -----
A2 Marek
A3 Hello
I am reading Data From Excel and if the text in the cell contains umlauts (äöü) they not be correctly seen by my Perl script. The char is replaced by substitution character.
What do I need to do to correctly read special characters from Excel?
# get reference to Excel, Active Window, Active Sheet
my $excel = Win32::OLE->GetActiveObject('Excel.Application');
my $book = $excel -> ActiveWindow;
my $sheet = $book -> ActiveSheet();
my $text = $sheet->Cells(1, 2)->{Value};
It works for me (Windows 10, Strawberry Perl 5.30) when printing the content to the Windows command prompt window and using STDOUT encoding cp437:
use feature qw(say);
use strict;
use warnings;
use Win32::OLE;
use open ':std', ':encoding(cp437)';
# get reference to Excel, Active Window, Active Sheet
my $excel = Win32::OLE->GetActiveObject('Excel.Application');
my $book = $excel -> ActiveWindow;
my $sheet = $book -> ActiveSheet();
my $text = $sheet->Cells(1, 1)->{Value};
say $text;
Output:
äöü
Edit:
As noted by #ikegami you should determine the console output-code-page programmatically (instead of hardcoding the value cp437 as I did) like this:
use Win32;
my $coe = "cp" . Win32::GetConsoleOutputCP();
binmode STDOUT, "encoding($coe)";
See also this post for more information.
I am trying to write a perl script which reads an excel file(which has many sheets in it) using the sheet name.
I know how to access a particular sheet of the excel file using the sheet number, but not sure how to read it using sheet name.
Any help provided is highly appreciated.
Below is the code I wrote to access the sheet using sheet number:
my $Sheet_Number = 26;
my $workbook = ReadData("<path to the excel file>");
for (my $i =2; $i<$limit; $i++){
my $cell = "A" . $i;
my $key_1 = $workbook->[$Sheet_Number]{$cell};
}
Thanks
----Edit----
I want to open the particular sheet within the Excel file by using the sheet name. And then read the data from that particular sheet. The name of the sheet will be entered by the user while running the script from the command line arguments.
Below is the code that I am using after getting suggested answers for my earlier question:
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse("$path");
my $worksheet;
if ($worksheet->get_name() eq "$Sheet_Name"){
for (my $i =2; $i<$limit; $i++){
my $cell = $worksheet->get_cell($i,"A");
my $value = $cell->value();
push #array_keys, $value;
}
}
I want to read the values of Column A of the particular sheet and push it into an array.
$Sheet_Name : It is the name of the sheet which is entered by the user as cmd line arg.
$path : It is the complete path to the Excel file
Error Message: Can't call method "get_name" on an undefined value at perl_script.pl (The error points to the line where the if-condition is used.)
Thanks for the help.
-----EDIT----
Anyone, with any leads on this post, please post your answer or suggestions. Appreciate any responses.
Thanks
The get_name() method of the worksheet object, in conjunction with Perl's grep command should get you this:
my ($worksheet) = grep { $_->get_name() eq 'Sheet2' } $workbook->worksheets();
This would be an un-golfed version of the same:
my $worksheet;
foreach $worksheet ($workbook->worksheets()) {
last if $worksheet->get_name() eq 'Sheet2';
}
Assuming there is a match... if not, I guess my un-golfed version would give you the last worksheet if there was no match.
-- Edit --
I made assumptions and -- you certainly do need to first call the method to load the workbook:
use strict;
use Spreadsheet::ParseExcel;
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse('/var/tmp/foo.xls');
Then the code above should work.
I was working with perl code to create a spreadsheet having multiple workshhets using Spreadsheet::WriteExcel. But the loop works only once and breaks. Please help to find what actually happening.
Code
use Spreadsheet::WriteExcel;
my $workbook = new_workbook($r, 'Workbook.xls');
my $worksheet;
my #list = ('bike', 'car', 'bus');
foreach my $name (#list){
$worksheet = $workbook->add_worksheet($name);
# writing excel data ...
}
$workbook->close();
You are declaring the $worksheet variable outside of the loop (1) and then overwrite it in each loop iteration (2). That might lead to complications inside Spreadsheet::WriteExcel if the reference to the first worksheet suddently gets replaced with a new worksheet. Probably the XLS comes out with only the last worksheet.
use Spreadsheet::WriteExcel;
my $workbook = new_workbook($r, 'Workbook.xls');
my $worksheet; # <--- 1
my #list = ('bike', 'car', 'bus');
foreach my $name (#list){
$worksheet = $workbook->add_worksheet($name); # <--- 2
# writing excel data ...
}
$workbook->close();
Instead you should just declare a lexical $worksheet inside the loop where you use it. In general, allways declare variables in the smallest lexical scope in Perl.
foreach my $name (#list) {
my $worksheet = $workbook->add_worksheet($name);
# writing excel data ...
}
I have a .xlsx file (only one sheet) with 15 columns. I want to read some specific columns, let's say columns 3, 5, 11, 14 and write it to a new Excel sheet. In this case some cells of input files are empty means don't have any value.
Here what I am trying:
use warnings;
use strict;
use Spreadsheet::ParseXLSX;
use Excel::Writer::XLSX;
my $parser = Spreadsheet::ParseXLSX->new;
my $workbook = $parser->parse("test.xlsx");
if ( !defined $workbook ) {
die $parser->error(), ".\n";
}
my $worksheet = $workbook->worksheet('Sheet1');
# but from here I don't know how to define row and column range to get specific column data.
# I am trying to get all data in an array, so I can write it in new .xlsx file.
# function to write data in new file
sub writetoexcel
{
my #fields = #_;
my $workbook = Excel::Writer::XLSX->new( 'report.xlsx' );
$worksheet = $workbook->add_worksheet();
my $row = 0;
my $col = 0;
for my $token ( #fields )
{
$worksheet->write( $row, $col, $token );
$col++;
}
$row++;
}
I also followed this Question, but no luck.
How can I read specific columns from .xlsx file and write it into new .xlsx file?
Have you never copied a subset of columns from an array of arrays to another?
Here is the input sheet I used for this:
and, this is what I get in the output file after the code is run:
#!/usr/bin/env perl
use strict;
use warnings;
use Excel::Writer::XLSX;
use Spreadsheet::ParseXLSX;
my #cols = (1, 3);
my $reader = Spreadsheet::ParseXLSX->new;
my $bookin = $reader->parse($ARGV[0]);
my $sheetin = $bookin->worksheet('Sheet1');
my $writer = Excel::Writer::XLSX->new($ARGV[1]);
my $sheetout = $writer->add_worksheet('Extract');
my ($top, $bot) = $sheetin->row_range;
for my $r ($top .. $bot) {
$sheetout->write_row(
$r,
0,
# of course, you need to do more work if you want
# to preserve formulas, formats etc. That is left
# to you, as you left that part of the problem
# unspecified.
[ map $sheetin->get_cell($r, $_)->value, #cols ],
);
}
$writer->close;