boleary has asked for the wisdom of the Perl Monks concerning the following question:
I'm looking for a clever way to override the SpreadSheet/ParseXLSX.pm module so I can add some tweaks to it without having to touch the installed library (on many of my different hosts) I'm pretty weak on object oriented tricks, so I'm hoping someone can tell me a clever way to accomplish this. I presently have the modified Module working with the changes I discuss below... I just really didn't want to touch the actual library module like I did because its locally installed and I'm not tracking changes on them.
The current Spreadsheet::ParseXLSX module is great,
but it parses EVERY sheet in a workbook when ReadData is called and that can be quite time consuming for large spreadsheets with many tabs!
I have 2 workarounds I can add to that module by passing in some extra options when I call the Spreadsheet::ReadData Method
The ReadData function cleverly passes any unrecognized options to the ParseXLSX new function, so I can easily extend the option set like shown...
sub new { my $class = shift; my (%args) = @_; my $self = bless {}, $class; $self->{Password} = $args{Password} if defined $args{Password}; # #my new options # $self->{sheet_filter} = $args{sheet_filter} if defined $args{sheet +_filter}; $self->{just_find_sheet_names} = $args{just_find_sheet_names} if d +efined $args{just_find_sheet_names}; return $self; }
then down in _parse_workbook, I can change:
my @sheets = map { my $idx = $_->att('rels:id'); if ($files->{sheets}{$idx}) { my $sheet = Spreadsheet::ParseExcel::Worksheet->new( Name => $_->att('name'), _Book => $workbook, _SheetNo => $idx, ); $sheet->{SheetHidden} = 1 if defined $_->att('state') and $_ +->att('state') eq 'hidden'; $self->_parse_sheet($sheet, $files->{sheets}{$idx}); ($sheet) } else { () } } $files->{workbook}->find_nodes('//s:sheets/s:sheet');
to this where It will only parse the sheets whose names match the sheet names passed in in sheet_filter option:
#my hack to only process worksheets matching the sheet filter my %sheet_filter=(); if ($self->{sheet_filter}) { map {$sheet_filter{$_}} split ",", $self->{sheet_filter}; } my @sheets = map { my $idx = $_->att('rels:id'); if ($files->{sheets}{$idx}) { my $sheet = Spreadsheet::ParseExcel::Worksheet->new( Name => $_->att('name'), _Book => $workbook, _SheetNo => $idx, ); $sheet->{SheetHidden} = 1 if defined $_->att('state') and $_ +->att('state') eq 'hidden'; $self->_parse_sheet($sheet, $files->{sheets}{$idx}); ($sheet) } else { () } } grep {%sheet_filter ? defined $sheet_filter{$_->att('name')} : 1 +} $files->{workbook}->find_nodes('//s:sheets/s:sheet');
and also add a function to just return sheetnames without sufferring the performance time to fully process each sheet:
#my hack to only return the list of sheet names if($self->{just_find_sheet_names}) { my @sheets = map { $_->att('name'); } $files->{workbook}->find_nodes('//s:sheets/s:sheet'); $workbook->{Worksheet} = \@sheets; $workbook->{SheetCount} = scalar(@sheets); return $workbook; }
Any helpful ideas would be appreciated
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Help to override Spreadsheet/ParseXLSX.pm module
by LanX (Saint) on Apr 02, 2021 at 21:06 UTC | |
by Tux (Canon) on Apr 03, 2021 at 05:35 UTC | |
by LanX (Saint) on Apr 03, 2021 at 09:28 UTC | |
by boleary (Scribe) on Apr 03, 2021 at 12:20 UTC | |
by boleary (Scribe) on Apr 03, 2021 at 12:11 UTC | |
by LanX (Saint) on Apr 03, 2021 at 12:42 UTC | |
by boleary (Scribe) on Apr 06, 2021 at 11:36 UTC | |
by bliako (Abbot) on Apr 03, 2021 at 19:43 UTC | |
by boleary (Scribe) on Apr 06, 2021 at 11:31 UTC |