From 2fda97fcadcf9bd9668192c9e3fffc39acd105bc Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 1 May 2013 17:46:35 -0500 Subject: generate selections --- lib/Spreadsheet/Template/Generator/Parser/Excel.pm | 4 +- lib/Spreadsheet/Template/Generator/Parser/XLS.pm | 17 +++++ lib/Spreadsheet/Template/Generator/Parser/XLSX.pm | 75 +++++++++++++++++----- 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/lib/Spreadsheet/Template/Generator/Parser/Excel.pm b/lib/Spreadsheet/Template/Generator/Parser/Excel.pm index c9a128a..8c279cf 100644 --- a/lib/Spreadsheet/Template/Generator/Parser/Excel.pm +++ b/lib/Spreadsheet/Template/Generator/Parser/Excel.pm @@ -21,6 +21,7 @@ sub _parse_workbook { my $self = shift; my $data = { + selection => $self->excel->{SelectedSheet}, # XXX worksheets => [], }; @@ -39,8 +40,7 @@ sub _parse_worksheet { name => $sheet->get_name, row_heights => [ $sheet->get_row_heights ], column_widths => [ $sheet->get_col_widths ], - # XXX Spreadsheet::ParseExcel doesn't currently support extracting the - # currently selected cells or worksheets + selection => $sheet->{Selection}, # XXX cells => [], }; diff --git a/lib/Spreadsheet/Template/Generator/Parser/XLS.pm b/lib/Spreadsheet/Template/Generator/Parser/XLS.pm index 194558a..b871ae4 100644 --- a/lib/Spreadsheet/Template/Generator/Parser/XLS.pm +++ b/lib/Spreadsheet/Template/Generator/Parser/XLS.pm @@ -21,12 +21,22 @@ sub _fixup_excel { my $self = shift; my ($excel) = @_; + $self->_parse_selected_sheet($excel); + for my $sheet ($excel->worksheets) { $self->_normalize_cell_sizes($sheet); $self->_parse_formulas($sheet); + $self->_parse_selection($sheet); } } +sub _parse_selected_sheet { + my $self = shift; + my ($excel) = @_; + # XXX no selected sheet support yet + $excel->{SelectedSheet} = 0; +} + sub _normalize_cell_sizes { my $self = shift; my ($sheet) = @_; @@ -46,6 +56,13 @@ sub _parse_formulas { # XXX no formula support yet } +sub _parse_selection { + my $self = shift; + my ($sheet) = @_; + # XXX no selection support yet + $sheet->{Selection} = [ 0, 0 ]; +} + __PACKAGE__->meta->make_immutable; no Moose; diff --git a/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm b/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm index c9d12a1..0a043a1 100644 --- a/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm +++ b/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm @@ -20,25 +20,28 @@ sub _fixup_excel { my $self = shift; my ($excel) = @_; - my $filename = $self->filename; - - my $zip = Archive::Zip->new; - die "Can't open $filename as zip file" - unless $zip->read($filename) == Archive::Zip::AZ_OK; + my $book_xml = $self->_parse_xml("xl/workbook.xml"); + $self->_parse_selected_sheet($excel, $book_xml); for my $sheet ($excel->worksheets) { - my $contents = $zip->memberNamed("xl/$sheet->{path}")->contents; - next unless $contents; + my $sheet_xml = $self->_parse_xml("xl/$sheet->{path}"); - my $xml = XML::Twig->new; - $xml->parse($contents); - my $root = $xml->root; - - $self->_parse_cell_sizes($sheet, $root); - $self->_parse_formulas($sheet, $root); + $self->_parse_cell_sizes($sheet, $sheet_xml); + $self->_parse_formulas($sheet, $sheet_xml); + $self->_parse_sheet_selection($sheet, $sheet_xml); } } +sub _parse_selected_sheet { + my $self = shift; + my ($excel, $root) = @_; + + my ($node) = $root->find_nodes('//workbookView'); + my $selected = $node->att('activeTab'); + + $excel->{SelectedSheet} = defined($selected) ? 0+$selected : 0; +} + sub _parse_cell_sizes { my $self = shift; my ($sheet, $root) = @_; @@ -74,15 +77,53 @@ sub _parse_formulas { for my $formula ($root->find_nodes('//f')) { my $cell_id = $formula->parent->att('r'); - my ($col, $row) = $cell_id =~ /([A-Z]+)([0-9]+)/; - $col =~ tr/A-Z/0-9A-P/; - $col = POSIX::strtol($col, 26); - $row = $row - 1; + my ($row, $col) = $self->_cell_to_row_col($cell_id); my $cell = $sheet->get_cell($row, $col); $cell->{Formula} = "=" . $formula->text; } } +sub _parse_sheet_selection { + my $self = shift; + my ($sheet, $root) = @_; + + my ($selection) = $root->find_nodes('//selection'); + my $cell = $selection->att('activeCell'); + + $sheet->{Selection} = [ $self->_cell_to_row_col($cell) ]; +} + +sub _parse_xml { + my $self = shift; + my ($subfile) = @_; + + my $filename = $self->filename; + + my $zip = Archive::Zip->new; + die "Can't open $filename as zip file" + unless $zip->read($filename) == Archive::Zip::AZ_OK; + + my $contents = $zip->memberNamed($subfile)->contents; + next unless $contents; + + my $xml = XML::Twig->new; + $xml->parse($contents); + + return $xml->root; +} + +sub _cell_to_row_col { + my $self = shift; + my ($cell) = @_; + + my ($col, $row) = $cell =~ /([A-Z]+)([0-9]+)/; + $col =~ tr/A-Z/0-9A-P/; + $col = POSIX::strtol($col, 26); + $row = $row - 1; + + return ($row, $col); +} + # XXX this stuff all feels like working around bugs in Spreadsheet::XLSX - # maybe look into that at some point sub _filter_cell_contents { -- cgit v1.2.3-54-g00ecf