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

Hi Monks!
I came across this code and my question is if my .xls file has column names like: C1, C2, C3, C4. How could I access these columns by name, cause this code prints out all the data from the file.
#!/usr/bin/perl -w use strict; use Spreadsheet::ParseExcel; my $parse_excel = Spreadsheet::ParseExcel->new(CellHandler =>\&cell_ha +ndler,NotSetCell => 1); my $workbook = $parse_excel->Parse('file.xls'); sub cell_handler { my $workbook= $_[0]; my $sheet_index = $_[1]; my $row = $_[2]; my $col = $_[3]; my $cell= $_[4]; # Do something with the formatted cell value print $cell->{_Value}, "\n"; # I need to access the values here #print columns names: C1 ..C4 here #print values of C1 ..C4 here }

Thanks!

Replies are listed 'Best First'.
Re: Accessing values in a XSL file.
by jmcnamara (Monsignor) on Oct 27, 2010 at 16:41 UTC
    Excel columns don't have names apart from A, B, C, D etc.

    If you have strings in the first row of the worksheet that you are using for names you will have to store them when they are encountered and reuse them later.

    If you just wish to find the column letter based on the column number you can use the int2col() function from Spreadsheet::parseExcel::Utility.

    --
    John.

Re: Accessing values in a XSL file.
by roboticus (Chancellor) on Oct 27, 2010 at 16:52 UTC

    The problem is that using a cell handler calls your cell handler as each cell is read. You don't really need to do that under normal circumstances, but if you do, then try something like:

    #!/usr/bin/perl -w use strict; use warnings; use Spreadsheet::ParseExcel; my %CellData; # Key1=workbook, Key2=Row, Key3=column my $parse_excel = Spreadsheet::ParseExcel->new( CellHandler => \&cell_handler, NotSetCell => 1 ); my $workbook = $parse_excel->Parse('file.xls'); # Now that we've parsed the sheet, we can access any data we like, # So let's print cell C1 on sheet "FOO" print $CellData{FOO}{C}{1}, "\n"; sub cell_handler { # Cell information passed to us my ($WB, $IDX, $R, $C, $Cell) = @_; # Build our hash keys my $SheetName = $WB->worksheet($IDX)->get_name(); my $ColName = numToColumnName($C); my $RowName = $R; $CellData{$SheetName}{$ColName}{$RowName} = $Cell->{_Value}; } sub numToColumnName { my $C = shift; my $colName = ''; if ($C>25) { $colName = substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $C/26, 1); $C = $C % 26; } $colName .= substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $C, 1); }

    (Note: Untested!)

    Of course, if you don't need to use a cell handler, you can just use the example in the first page of the documentation to access the data by sheet / row / column...

    ...roboticus

      The idea here is to read this xls file and get the values into a database, the columns will not necessarily be called C1 to C4, it will be called something else, that's why I asked about passing the column names to get is value. Any ideas?
        I maintain Spreadsheet::ParseExcel.

        There aren't any column names in an Excel file so you can't use column names to access any data.

        --
        John.

Re: Accessing values in a XSL file.
by umasuresh (Hermit) on Oct 27, 2010 at 16:07 UTC
    Try saving the xls into a tab delimited and then use Text::CSV to access columns by names.