File Coverage

lib/Spreadsheet/XLSX/Reader/LibXML/XMLReader/WorksheetToRow.pm
Criterion Covered Total %
statement 35 235 14.8
branch 0 144 0.0
condition 0 60 0.0
subroutine 12 19 63.1
pod n/a
total 47 458 10.2


line stmt bran cond sub pod time code
1             package Spreadsheet::XLSX::Reader::LibXML::XMLReader::WorksheetToRow;
2             our $AUTHORITY = 'cpan:JANDREW';
3 3     3   3261 use version; our $VERSION = qv('v0.38.18');
  3         8  
  3         41  
4             ###LogSD warn "You uncovered internal logging statements for Spreadsheet::XLSX::Reader::LibXML::XMLReader::WorksheetToRow-$VERSION";
5              
6 3     3   385 use 5.010;
  3         10  
7 3     3   14 use Moose;
  3         13  
  3         25  
8 3     3   19513 use MooseX::StrictConstructor;
  3         8  
  3         32  
9 3     3   8935 use MooseX::HasDefaults::RO;
  3         5  
  3         31  
10 3     3   17108 use Clone 'clone';
  3         9076  
  3         224  
11 3     3   23 use Carp qw( confess );
  3         6  
  3         158  
12 3         35 use Types::Standard qw(
13             HasMethods InstanceOf ArrayRef
14             Bool Int is_HashRef
15 3     3   19 );
  3         5  
16 3     3   4109 use MooseX::ShortCut::BuildInstance qw ( build_instance should_re_use_classes );
  3         5  
  3         36  
17             should_re_use_classes( 1 );
18 3     3   1770 use lib '../../../../../../lib';
  3         7  
  3         27  
19             ###LogSD use Log::Shiras::Telephone;
20             ###LogSD use Log::Shiras::UnhideDebug;
21             extends 'Spreadsheet::XLSX::Reader::LibXML::XMLReader';
22 3     3   2318 use Spreadsheet::XLSX::Reader::LibXML::Row;
  3         13  
  3         7882  
23              
24             #########1 Dispatch Tables & Package Variables 5#########6#########7#########8#########9
25              
26              
27              
28             #########1 Public Attributes 3#########4#########5#########6#########7#########8#########9
29              
30             has is_hidden =>(
31             isa => Bool,
32             reader => 'is_sheet_hidden',
33             );
34            
35             has workbook_instance =>(
36             isa => HasMethods[qw(
37             counting_from_zero boundary_flag_setting
38             change_boundary_flag _has_shared_strings_file
39             get_shared_string_position _has_styles_file
40             get_format_position set_empty_is_end
41             is_empty_the_end _starts_at_the_edge
42             get_group_return_type set_group_return_type
43             get_epoch_year change_output_encoding
44             get_date_behavior set_date_behavior
45             get_empty_return_type set_error
46             get_values_only set_values_only
47             parse_excel_format_string
48             )],
49             handles => [qw(
50             counting_from_zero boundary_flag_setting
51             change_boundary_flag _has_shared_strings_file
52             get_shared_string_position _has_styles_file
53             get_format_position set_empty_is_end
54             is_empty_the_end _starts_at_the_edge
55             get_group_return_type set_group_return_type
56             get_epoch_year change_output_encoding
57             get_date_behavior set_date_behavior
58             get_empty_return_type set_error
59             get_values_only set_values_only
60             parse_excel_format_string
61             )],
62             required => 1,
63             );
64             ###LogSD use Log::Shiras::UnhideDebug;
65             with 'Spreadsheet::XLSX::Reader::LibXML::CellToColumnRow',
66             'Spreadsheet::XLSX::Reader::LibXML::XMLToPerlData',
67             ;
68              
69             #########1 Public Methods 3#########4#########5#########6#########7#########8#########9
70              
71              
72              
73             #########1 Private Attributes 3#########4#########5#########6#########7#########8#########9
74              
75             has _sheet_min_col =>(
76             isa => Int,
77             writer => '_set_min_col',
78             reader => '_min_col',
79             predicate => 'has_min_col',
80             );
81              
82             has _sheet_min_row =>(
83             isa => Int,
84             writer => '_set_min_row',
85             reader => '_min_row',
86             predicate => 'has_min_row',
87             );
88              
89             has _sheet_max_col =>(
90             isa => Int,
91             writer => '_set_max_col',
92             reader => '_max_col',
93             predicate => 'has_max_col',
94             );
95              
96             has _sheet_max_row =>(
97             isa => Int,
98             writer => '_set_max_row',
99             reader => '_max_row',
100             predicate => 'has_max_row',
101             );
102              
103             has _merge_map =>(
104             isa => ArrayRef,
105             traits => ['Array'],
106             writer => '_set_merge_map',
107             reader => '_get_merge_map',
108             handles =>{
109             _get_row_merge_map => 'get',
110             },
111             );
112              
113             has _column_formats =>(
114             isa => ArrayRef,
115             traits => ['Array'],
116             writer => '_set_column_formats',
117             reader => '_get_column_formats',
118             default => sub{ [] },
119             handles =>{
120             _get_custom_column_data => 'get',
121             },
122             );
123              
124             has _old_row_inst =>(
125             isa => InstanceOf[ 'Spreadsheet::XLSX::Reader::LibXML::Row' ],
126             reader => '_get_old_row_inst',
127             writer => '_set_old_row_inst',
128             clearer => '_clear_old_row_inst',
129             predicate => '_has_old_row_inst',
130             handles =>{
131             _get_old_row_number => 'get_row_number',
132             _is_old_row_hidden => 'is_row_hidden',
133             _get_old_row_formats => 'get_row_format', # pass the desired format key
134             _get_old_column => 'get_the_column', # pass a column number (no next default) returns (cell|undef|EOR)
135             _get_old_last_value_col => 'get_last_value_column',
136             _get_old_row_list => 'get_row_all',
137             _get_old_row_end => 'get_row_end'
138             },
139             );
140              
141             has _new_row_inst =>(
142             isa => InstanceOf[ 'Spreadsheet::XLSX::Reader::LibXML::Row' ],
143             reader => '_get_new_row_inst',
144             writer => '_set_new_row_inst',
145             clearer => '_clear_new_row_inst',
146             predicate => '_has_new_row_inst',
147             handles =>{
148             _get_new_row_number => 'get_row_number',
149             _is_new_row_hidden => 'is_row_hidden',
150             _get_new_row_formats => 'get_row_format', # pass the desired format key
151             _get_new_column => 'get_the_column', # pass a column number (no next default) returns (cell|undef|EOR)
152             _get_new_next_value => 'get_the_next_value_position', # pass nothing returns next (cell|EOR)
153             _get_new_last_value_col => 'get_last_value_column',
154             _get_new_row_list => 'get_row_all',
155             _get_new_row_end => 'get_row_end'
156             },
157             );
158            
159             has _row_hidden_states =>(
160             isa => ArrayRef[ Bool ],
161             traits =>['Array'],
162             default => sub{ [] },
163             handles =>{
164             _set_row_hidden => 'set',
165             _get_row_hidden => 'get',
166             },
167             );
168              
169             #########1 Private Methods 3#########4#########5#########6#########7#########8#########9
170              
171             sub _get_col_row{
172 0     0     my( $self, $target_col, $target_row ) = @_;
173             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
174             ###LogSD $self->get_all_space . '::WorksheetToRow::_get_col_row', );
175             ###LogSD $phone->talk( level => 'debug', message => [
176             ###LogSD "Reached _get_col_row",
177             ###LogSD ( $target_row ? "Requesting target row and column: [ $target_row, $target_col ]" : '' ),
178             ###LogSD ( $self->_has_old_row_inst ? ("With stored old row: " . $self->_get_old_row_number) : ''),
179             ###LogSD ( $self->_has_new_row_inst ? ("..and stored current row: " . $self->_get_new_row_number) : '') ] );
180              
181             # Attempt to pull the data from stored values or index the row forward
182 0           my $index_result = 'NoParse';
183 0           my ( $cell_ref, $max_value_col );
184 0           while( !defined $max_value_col ){
185 0 0         if( !$self->_has_new_row_inst ){
    0          
    0          
    0          
186             ###LogSD $phone->talk( level => 'debug', message => [
187             ###LogSD "No stored data available - index to the next (first?) row" ] );
188 0           $index_result = $self->_index_row;
189             }elsif( $self->_get_new_row_number < $target_row ){
190             ###LogSD $phone->talk( level => 'debug', message => [
191             ###LogSD 'The value is past the latest row pulled' ] );
192 0           $index_result = $self->_index_row;
193             }elsif( $self->_get_new_row_number == $target_row ){
194             ###LogSD $phone->talk( level => 'debug', message => [
195             ###LogSD 'The value might be in the latest row pulled' ] );
196 0           $max_value_col = $self->_get_new_last_value_col;
197 0 0         if( $target_col > $max_value_col ){
198 0 0 0       $cell_ref = ($self->is_empty_the_end or $self->_get_new_row_end < $target_col) ? 'EOR' : undef;
199             }else{
200 0           $cell_ref = $self->_get_new_column( $target_col );
201             }
202 0 0 0       if( $cell_ref and $cell_ref eq 'EOR' ){
203 0           $index_result = $self->_index_row;
204 0 0         $cell_ref = 'EOF' if $index_result eq 'EOF';
205             }
206             }elsif( $self->_has_old_row_inst ){
207 0 0         if( $self->_get_old_row_number < $target_row ){
    0          
208             ###LogSD $phone->talk( level => 'debug', message => [
209             ###LogSD 'The requested value falls between the last row and the current row' ] );
210 0           $index_result = undef;
211             }elsif( $self->_get_old_row_number == $target_row ){
212             ###LogSD $phone->talk( level => 'debug', message => [
213             ###LogSD 'The value might be in the previous row pulled' ] );
214 0           $max_value_col = $self->_get_old_last_value_col;
215 0 0         if( $target_col > $max_value_col ){
216 0 0 0       $cell_ref = ($self->is_empty_the_end or $self->_get_old_row_end < $target_col) ? 'EOR' : undef;
217             }else{
218 0           $cell_ref = $self->_get_old_column( $target_col );
219             }
220             }else{
221             ###LogSD $phone->talk( level => 'debug', message => [
222             ###LogSD 'The value appears to exist prior to the older saved row - restarting the sheet' ] );
223 0           $self->start_the_file_over;
224 0           $self->_clear_old_row_inst;
225 0           $self->_clear_new_row_inst;
226 0           $index_result = $self->_index_row;
227             }
228             }else{
229             ###LogSD $phone->talk( level => 'debug', message => [
230             ###LogSD 'The requested value falls between the beginning and the current row (and is empty)' ] );
231 0           $index_result = undef;
232             }
233 0 0 0       if( !$index_result ){
    0          
234             return
235 0 0         ( $self->is_empty_the_end ? 'EOR' :
    0          
236             $self->_max_col < $target_col ? 'EOR' : undef );
237             }elsif( !$cell_ref and $index_result =~ /^EO(F|R)$/ ){
238 0           return $index_result;
239             }
240             }
241             ###LogSD $phone->talk( level => 'debug', message => [
242             ###LogSD 'The index result after parsing through the rows:', $index_result,
243             ###LogSD "The cell ref after pulling column -$target_col-", $cell_ref, ] );
244 0 0 0       my $updated_cell =
    0          
    0          
245             ( $cell_ref ?
246             ( $cell_ref =~ /^EO(F|R)$/ ? $cell_ref : $self->_complete_cell( $cell_ref ) ) :
247             ($self->is_empty_the_end and $max_value_col < $target_col) ? 'EOR' : undef );
248             ###LogSD $phone->talk( level => 'debug', message => [
249             ###LogSD 'returning ref:', $updated_cell,] );
250 0           return $updated_cell;
251             }
252            
253             sub _get_next_value_cell{
254 0     0     my( $self, ) = @_; # to fast forward use _get_col_row
255             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
256             ###LogSD $self->get_all_space . '::WorksheetToRow::_get_next_value_cell', );
257             ###LogSD $phone->talk( level => 'debug', message => [
258             ###LogSD "Reached _get_next_value_cell",
259             ###LogSD ( $self->_has_new_row_inst ? ("With current stored new row: " . $self->_get_new_row_number) : '') ] );
260              
261             # Attempt to pull the data from stored values or index the row forward
262 0           my $index_result = 'NoParse';
263 0           my $cell_ref;
264 0           while( !$cell_ref ){
265 0 0         if( !$self->_has_new_row_inst ){
266             ###LogSD $phone->talk( level => 'debug', message => [
267             ###LogSD "No stored data available - index to the next (first?) row" ] );
268 0           $index_result = $self->_index_row;
269             }else{
270 0           $cell_ref = $self->_get_new_next_value;
271             ###LogSD $phone->talk( level => 'debug', message => [
272             ###LogSD 'Pulling the next value in the row:', $cell_ref ] );
273 0 0         if( $cell_ref eq 'EOR' ){
274             ###LogSD $phone->talk( level => 'debug', message => [
275             ###LogSD 'Reached the end of the row - starting over' ] );
276 0           $index_result = $self->_index_row;
277 0           $cell_ref = undef;
278             }
279             }
280 0 0 0       if( !$cell_ref and $index_result =~ /^EOF/ ){
281 0           return $index_result;
282             }
283             }
284             ###LogSD $phone->talk( level => 'debug', message => [
285             ###LogSD 'The cell ref after parsing through the rows:', $cell_ref, ] );
286            
287 0           my $updated_cell = $self->_complete_cell( $cell_ref );
288             ###LogSD $phone->talk( level => 'debug', message => [
289             ###LogSD 'returning ref:', $updated_cell,] );
290 0           return $updated_cell;
291             }
292              
293             sub _get_row_all{
294 0     0     my( $self, $target_row ) = @_;
295             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
296             ###LogSD $self->get_all_space . '::WorksheetToRow::_get_row_all', );
297             ###LogSD $phone->talk( level => 'debug', message => [
298             ###LogSD "Reached _get_row_all",
299             ###LogSD ( $target_row ? "Requesting target row: $target_row" : '' ),
300             ###LogSD ( $self->_has_old_row_inst ? ("With stored old row: " . $self->_get_old_row_number) : ''),
301             ###LogSD ( $self->_has_new_row_inst ? ("..and stored current row: " . $self->_get_new_row_number) : '') ] );
302              
303             # Attempt to pull the data from stored values or index the row forward
304 0           my $index_result = 'NoParse';
305 0           my $row_ref;
306 0   0       while( $index_result and !defined $row_ref ){
307 0 0         if( !$self->_has_new_row_inst ){
    0          
    0          
    0          
308             ###LogSD $phone->talk( level => 'debug', message => [
309             ###LogSD "No stored data available - index to the next (first?) row" ] );
310 0           $index_result = $self->_index_row;
311             }elsif( $self->_get_new_row_number < $target_row ){
312             ###LogSD $phone->talk( level => 'debug', message => [
313             ###LogSD 'The requested row is past the latest row pulled' ] );
314 0           $index_result = $self->_index_row;
315             }elsif( $self->_get_new_row_number == $target_row ){
316             ###LogSD $phone->talk( level => 'debug', message => [
317             ###LogSD 'The requested row is the latest row pulled' ] );
318 0           $row_ref = $self->_get_new_row_list;
319             }elsif( $self->_has_old_row_inst ){
320 0 0         if( $self->_get_old_row_number < $target_row ){
    0          
321             ###LogSD $phone->talk( level => 'debug', message => [
322             ###LogSD 'The requested row falls between the last row and the current row' ] );
323 0           $index_result = undef;
324             }elsif( $self->_get_old_row_number == $target_row ){
325             ###LogSD $phone->talk( level => 'debug', message => [
326             ###LogSD 'The requested row is the previous row pulled' ] );
327 0           $row_ref = $self->_get_new_old_list;
328             }else{
329             ###LogSD $phone->talk( level => 'debug', message => [
330             ###LogSD 'The requested row appears to exist prior to the older saved row - restarting the sheet' ] );
331 0           $self->start_the_file_over;
332 0           $self->_clear_old_row_inst;
333 0           $self->_clear_new_row_inst;
334 0           $index_result = $self->_index_row;
335             }
336             }else{
337             ###LogSD $phone->talk( level => 'debug', message => [
338             ###LogSD 'The requested row falls between the beginning and the current row (and is empty)' ] );
339 0           $index_result = undef;
340             }
341 0 0 0       if( !$index_result ){
    0          
342 0           return [];
343             }elsif( !$row_ref and $index_result eq 'EOF' ){
344 0           return $index_result;
345             }
346             }
347             ###LogSD $phone->talk( level => 'debug', message => [
348             ###LogSD 'The index result after parsing through the rows:', $index_result,
349             ###LogSD "The row ref after pulling row -$target_row-", $row_ref, ] );
350 0           my $updated_row;
351 0           for my $cell_ref ( @$row_ref ){
352 0 0         push @$updated_row, $cell_ref ? $self->_complete_cell( $cell_ref ) : $cell_ref ;
353             }
354             ###LogSD $phone->talk( level => 'debug', message => [
355             ###LogSD 'returning row ref:', $updated_row,] );
356 0           return $updated_row;
357             }
358              
359             sub _complete_cell{
360 0     0     my( $self, $cell_ref ) = @_;#, $new_file, $old_file
361             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
362             ###LogSD $self->get_all_space . '::WorksheetToRow::_complete_cell', );
363             ###LogSD $phone->talk( level => 'debug', message => [
364             ###LogSD "adding worksheet data to the cell:", $cell_ref ] );
365            
366             #Add merge value
367 0           my $merge_row = $self->_get_row_merge_map( $cell_ref->{cell_row} );
368             ###LogSD $phone->talk( level => 'debug', message => [
369             ###LogSD "Row merge map:", $merge_row, ] );
370 0 0 0       if( ref( $merge_row ) and $merge_row->[$cell_ref->{cell_col}] ){
371 0           $cell_ref->{cell_merge} = $merge_row->[$cell_ref->{cell_col}];
372             }
373            
374             # Check for hiddenness (This logic needs a deep rewrite when adding the skip_hidden attribute to the workbook)
375 0 0         if( $self->is_sheet_hidden ){
376             ###LogSD $phone->talk( level => 'trace', message => [
377             ###LogSD 'This cell is from a hidden sheet',] );
378 0           $cell_ref->{cell_hidden} = 'sheet';
379             }else{
380 0           my $column_attributes = $self->_get_custom_column_data( $cell_ref->{cell_col} );
381             #~ my $row_attributes = $self->_get_custom_row_data( $sub_ref->{cell_row} );
382             ###LogSD $phone->talk( level => 'trace', message => [
383             ###LogSD "Column -$cell_ref->{cell_col}- has attributes:", $column_attributes, ] );
384 0 0 0       if( $column_attributes and $column_attributes->{hidden} ){
385             ###LogSD $phone->talk( level => 'trace', message => [
386             ###LogSD 'This cell is from a hidden column',] );
387 0           $cell_ref->{cell_hidden} = 'column';
388             }
389             }
390             ###LogSD $phone->talk( level => 'trace', message => [
391             ###LogSD 'Ref to this point:', $cell_ref,] );
392 0           return $cell_ref;
393             }
394              
395             sub _index_row{
396 0     0     my( $self, ) = @_;#, $new_file, $old_file
397             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
398             ###LogSD $self->get_all_space . '::WorksheetToRow::_index_row', );
399             ###LogSD $phone->talk( level => 'debug', message => [
400             ###LogSD "Indexing the row forward by one value found position", ] );
401            
402             # Index the row as needed to get the next cell
403 0           my $row_node_ref;
404 0           while( !$row_node_ref ){
405            
406             # Advance to the next row node
407 0           my ( $node_depth, $node_name, $node_type ) = $self->location_status;
408             ###LogSD $phone->talk( level => 'debug', message => [
409             ###LogSD "Attempting to build the next row node from node: $node_name", ] );
410 0 0         if( $node_name eq 'row' ){
    0          
411             ###LogSD $phone->talk( level => 'trace', message => [
412             ###LogSD 'The index is at a row node.' ] );
413             }elsif( $self->advance_element_position( 'row' ) ){
414             ###LogSD $phone->talk( level => 'trace', message => [
415             ###LogSD 'The index was moved to a row node.' ] );
416             }else{
417 0           $self->set_error( "No row node found where I was looking in the worksheet" );
418 0           $self->_set_max_row( $self->_get_new_row_number );
419 0           $self->start_the_file_over;
420 0           $self->_clear_old_row_inst;
421 0           $self->_clear_new_row_inst;
422 0           return 'EOF';
423             }
424            
425             # Turn the xml into basic perl data
426 0           my $row_ref = $self->parse_element;
427             $row_ref->{list} =
428             exists $row_ref->{list} ? $row_ref->{list} :
429 0 0         exists $row_ref->{c} ? [ $row_ref->{c} ] : [];
    0          
430 0 0         delete $row_ref->{c} if exists $row_ref->{c};# Delete the single column c placeholder as needed
431             ###LogSD $phone->talk( level => 'debug', message => [
432             ###LogSD 'Result of row read:', $row_ref ] );
433            
434             # Load text values for each cell where appropriate
435 0           my ( $alt_ref, $column_to_cell_translations, $reported_column, $reported_position, $last_value_column );
436 0           my $x = 0;
437 0           for my $cell ( @{$row_ref->{list}} ){
  0            
438             ###LogSD $phone->talk( level => 'info', message => [
439             ###LogSD 'Processing cell:', $cell ] );
440            
441 0           $cell->{cell_type} = 'Text';
442 0 0         if( exists $cell->{t} ){
    0          
443 0 0         if( $cell->{t} eq 's' ){
    0          
444             ###LogSD $phone->talk( level => 'debug', message =>[
445             ###LogSD "Identified potentially required shared string for cell:", $cell] );
446             my $position = ( $self->_has_shared_strings_file ) ?
447 0 0         $self->get_shared_string_position( $cell->{v}->{raw_text} ) : $cell->{v}->{raw_text};
448             ###LogSD $phone->talk( level => 'debug', message =>[
449             ###LogSD "Shared strings resolved to:", $position] );
450 0 0         if( is_HashRef( $position ) ){
451 0           @$cell{qw( cell_xml_value rich_text )} = ( $position->{raw_text}, $position->{rich_text} );
452 0 0         delete $cell->{rich_text} if !$cell->{rich_text};
453             }else{
454 0           $cell->{cell_xml_value} = $position;
455             }
456             }elsif( $cell->{t} eq 'str' ){
457             ###LogSD $phone->talk( level => 'debug', message =>[
458             ###LogSD "Identified a stored string in the worksheet file: " . ($cell->{v}//'')] );
459 0           $cell->{cell_xml_value} = $cell->{v}->{raw_text};
460             }else{
461 0           confess "Unknow 't' attribute set for the cell: $cell->{t}";
462             }
463 0           delete $cell->{t};
464 0           delete $cell->{v};
465 0 0         delete $cell->{cell_xml_value} if !defined $cell->{cell_xml_value};
466             }elsif( exists $cell->{v} ){
467             ###LogSD $phone->talk( level => 'debug', message =>[
468             ###LogSD "Setting cell_xml_value from: $cell->{v}->{raw_text}", ] );
469 0           $cell->{cell_xml_value} = $cell->{v}->{raw_text};
470 0 0 0       $cell->{cell_type} = 'Numeric' if $cell->{cell_xml_value} and $cell->{cell_xml_value} ne '';
471 0           delete $cell->{v};
472             }
473 0 0 0       if( $self->get_empty_return_type eq 'empty_string' ){
    0 0        
474 0 0         $cell->{cell_xml_value} = '' if !exists $cell->{cell_xml_value};
475             }elsif( !defined $cell->{cell_xml_value} or
476             ($cell->{cell_xml_value} and length( $cell->{cell_xml_value} ) == 0) ){
477 0           delete $cell->{cell_xml_value};
478             }
479             ###LogSD $phone->talk( level => 'debug', message =>[
480             ###LogSD "Updated cell:", $cell] );
481             # Clear empty cells if required
482 0 0 0       if( $self->get_values_only and ( !defined $cell->{cell_xml_value} or length( $cell->{cell_xml_value} ) == 0 ) ){
      0        
483             ###LogSD $phone->talk( level => 'info', message => [
484             ###LogSD 'Values only called - stripping this non-value cell' ] );
485             }else{
486 0 0         $cell->{cell_type} = 'Text' if !exists $cell->{cell_type};
487 0 0         $cell->{cell_hidden} = 'row' if $row_ref->{hidden};
488 0           @$cell{qw( cell_col cell_row )} = $self->_parse_column_row( $cell->{r} );
489 0           $last_value_column = $cell->{cell_col};
490 0 0         $cell->{cell_formula} = $cell->{f}->{raw_text} if $cell->{f};
491 0           delete $cell->{f};
492 0           $column_to_cell_translations->[$cell->{cell_col}] = $x++;
493 0 0         $reported_column = $cell->{cell_col} if !defined $reported_column;
494 0           $reported_position = 0;
495             ###LogSD $phone->talk( level => 'info', message => [
496             ###LogSD 'Saving cell:', $cell ] );
497 0           push @$alt_ref, $cell;
498             }
499             }
500 0 0         $self->_set_row_hidden( $row_ref->{r} => ($row_ref->{hidden} ? 1 : 0) );
501            
502 0 0         if( $alt_ref ){
503 0           my $new_ref;
504             ###LogSD $phone->talk( level => 'trace', message =>[
505             ###LogSD "Row ref:", $row_ref, ] ) if !$row_ref->{spans};
506 0           $new_ref->{row_number} = $row_ref->{r};
507             $new_ref->{row_span} = $row_ref->{spans} ?
508 0 0         [split /:/, $row_ref->{spans}] : [ $self->_min_col, $self->_max_col ];
509 0           delete $row_ref->{r};
510 0           delete $row_ref->{list};
511 0           delete $row_ref->{spans};
512 0           delete $row_ref->{hidden};
513             ###LogSD $phone->talk( level => 'debug', message =>[
514             ###LogSD "Updated row ref:", $new_ref, ] );
515 0 0         $self->_set_old_row_inst( $self->_get_new_row_inst ) if $self->_has_new_row_inst;
516 0           $row_node_ref = build_instance(
517             package => 'RowInstance',
518             superclasses => [ 'Spreadsheet::XLSX::Reader::LibXML::Row' ],
519             %$new_ref,
520             row_value_cells => $alt_ref,
521             row_formats => $row_ref,
522             row_last_value_column => $last_value_column,
523             column_to_cell_translations => $column_to_cell_translations,
524             ###LogSD log_space => $self->get_log_space
525             );
526             ###LogSD $phone->talk( level => 'debug', message =>[
527             ###LogSD "New row instance:", $row_node_ref, ] );
528 0           $self->_set_new_row_inst( $row_node_ref );
529             }else{
530             ###LogSD $phone->talk( level => 'debug', message =>[
531             ###LogSD 'Nothing to see here - move along', ] );
532             }
533             }
534 0 0         return $row_node_ref ? 'GoodParse' : undef;
535             }
536              
537             sub _load_unique_bits{
538 0     0     my( $self, ) = @_;#, $new_file, $old_file
539             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
540             ###LogSD $self->get_all_space . '::WorksheetToRow::_load_unique_bits', );
541             ###LogSD $phone->talk( level => 'debug', message => [
542             ###LogSD "Setting the Worksheet unique bits", ] );
543            
544             # Read the sheet dimensions
545 0           my ( $node_depth, $node_name, $node_type ) = $self->location_status;
546 0 0 0       if( $node_name eq 'dimension' or $self->advance_element_position( 'dimension' ) ){
547 0           my $dimension = $self->parse_element;
548             ###LogSD $phone->talk( level => 'debug', message => [
549             ###LogSD "parsed dimension value:", $dimension ] );
550 0           my ( $start, $end ) = split( /:/, $dimension->{ref} );
551             ###LogSD $phone->talk( level => 'debug', message => [
552             ###LogSD "Start position: $start",
553             ###LogSD ( $end ? "End position: $end" : '' ), ] );
554 0 0         my ( $start_column, $start_row ) = ( $self->_starts_at_the_edge ) ?
555             ( 1, 1 ) : $self->_parse_column_row( $start );
556 0 0         my ( $end_column, $end_row ) = $end ?
557             $self->_parse_column_row( $end ) :
558             ( $start_column, $start_row ) ;
559             ###LogSD $phone->talk( level => 'debug', message => [
560             ###LogSD "Start column: $start_column", "Start row: $start_row",
561             ###LogSD "End column: $end_column", "End row: $end_row" ] );
562 0           $self->_set_min_col( $start_column );
563 0           $self->_set_min_row( $start_row );
564 0           $self->_set_max_col( $end_column );
565 0           $self->_set_max_row( $end_row );
566 0           $self->_clear_old_row_inst;
567 0           $self->_clear_new_row_inst;
568             }else{
569 0           confess "No sheet dimensions provided";# Shouldn't the error instance be loaded already?
570             }
571            
572             #pull column stats
573 0           my $has_column_data = 1;
574 0           ( $node_depth, $node_name, $node_type ) = $self->location_status;
575             ###LogSD $phone->talk( level => 'debug', message => [
576             ###LogSD "Loading the column configuration" ] );
577 0 0 0       if( $node_name eq 'cols' or $self->advance_element_position( 'cols') ){
578             ###LogSD $phone->talk( level => 'debug', message => [
579             ###LogSD "Already arrived at the column data" ] );
580             }else{
581             ###LogSD $phone->talk( level => 'debug', message => [
582             ###LogSD "Restart the sheet to find the column data" ] );
583 0           $self->start_the_file_over;
584 0           $has_column_data = $self->advance_element_position( 'cols' );
585             ###LogSD $phone->talk( level => 'debug', message => [
586             ###LogSD "Column data search result: $has_column_data" ] );
587             }
588 0 0         if( $has_column_data ){
589 0           my $column_data = $self->parse_element;
590             ###LogSD $phone->talk( level => 'debug', message => [
591             ###LogSD "parsed column elements to:", $column_data ] );
592 0           my $column_store = [];
593 0           for my $definition ( @{$column_data->{list}} ){
  0            
594 0 0         next if !is_HashRef( $definition );
595             ###LogSD $phone->talk( level => 'debug', message => [
596             ###LogSD "Processing:", $definition ] );
597 0           my $row_ref;
598 0 0         map{ $row_ref->{$_} = $definition->{$_} if defined $definition->{$_} } qw( width customWidth bestFit hidden );
  0            
599             ###LogSD $phone->talk( level => 'debug', message => [
600             ###LogSD "Updated row ref:", $row_ref ] );
601 0           for my $col ( $definition->{min} .. $definition->{max} ){
602 0           $column_store->[$col] = $row_ref;
603             ###LogSD $phone->talk( level => 'debug', message => [
604             ###LogSD "Updated column store is:", $column_store ] );
605             }
606             }
607             ###LogSD $phone->talk( level => 'trace', message => [
608             ###LogSD "Final column store is:", $column_store ] );
609 0           $self->_set_column_formats( $column_store );
610             }
611            
612             #build a merge map
613 0           my $merge_ref = [];
614             ###LogSD $phone->talk( level => 'debug', message => [
615             ###LogSD "Loading the mergeCell" ] );
616 0           ( $node_depth, $node_name, $node_type ) = $self->location_status;
617 0           my $found_merges = 0;
618 0 0 0       if( ($node_name and $node_name eq 'mergeCells') or $self->advance_element_position( 'mergeCells') ){
      0        
619 0           $found_merges = 1;
620             }else{
621 0           $self->start_the_file_over;
622 0           $found_merges = $self->advance_element_position( 'mergeCells');
623             }
624 0 0         if( $found_merges ){
625 0           my $merge_range = $self->parse_element;
626             ###LogSD $phone->talk( level => 'debug', message => [
627             ###LogSD "Processing all merge ranges:", $merge_range ] );
628 0           my $final_ref;
629 0           for my $merge_ref ( @{$merge_range->{list}} ){
  0            
630             ###LogSD $phone->talk( level => 'debug', message => [
631             ###LogSD "parsed merge element to:", $merge_ref ] );
632 0           my ( $start, $end ) = split /:/, $merge_ref->{ref};
633 0           my ( $start_col, $start_row ) = $self->_parse_column_row( $start );
634 0           my ( $end_col, $end_row ) = $self->_parse_column_row( $end );
635             ###LogSD $phone->talk( level => 'debug', message => [
636             ###LogSD "Start column: $start_col", "Start row: $start_row",
637             ###LogSD "End column: $end_col", "End row: $end_row" ] );
638 0           my $min_col = $start_col;
639 0           while ( $start_row <= $end_row ){
640 0           $final_ref->[$start_row]->[$start_col] = $merge_ref->{ref};
641 0           $start_col++;
642 0 0         if( $start_col > $end_col ){
643 0           $start_col = $min_col;
644 0           $start_row++;
645             }
646             }
647             }
648             ###LogSD $phone->talk( level => 'trace', message => [
649             ###LogSD "Final merge ref:", $final_ref ] );
650 0           $self->_set_merge_map( $final_ref );
651             }
652 0           $self->start_the_file_over;
653 0           return 1;
654             }
655              
656             sub _is_column_hidden{
657 0     0     my( $self, @column_requests ) = @_;
658             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
659             ###LogSD $self->get_all_space . '::WorksheetToRow::is_column_hidden::subsub', );
660             ###LogSD $phone->talk( level => 'debug', message => [
661             ###LogSD 'Pulling the hidden state for the columns:', @column_requests ] );
662            
663 0           my @tru_dat;
664 0           for my $column ( @column_requests ){
665 0           my $column_format = $self->_get_custom_column_data( $column );
666             ###LogSD $phone->talk( level => 'trace', message =>[
667             ###LogSD "Column formats for column -$column- are:", $column_format ] );
668 0 0 0       push @tru_dat, (( $column_format and $column_format->{hidden} ) ? 1 : 0);
669             }
670             ###LogSD $phone->talk( level => 'info', message =>[
671             ###LogSD "Final column hidden state is list:", @tru_dat] );
672 0           return @tru_dat;
673             }
674              
675             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
676              
677 3     3   28 no Moose;
  3         8  
  3         186  
678             __PACKAGE__->meta->make_immutable;
679            
680             1;
681              
682             #########1 Documentation 3#########4#########5#########6#########7#########8#########9
683             __END__
684              
685             =head1 NAME
686              
687             Spreadsheet::XLSX::Reader::LibXML::XMLReader::WorksheetToRow - Pull rows out of worksheet xml files
688              
689             =head1 SYNOPSIS
690              
691             See t\Spreadsheet\XLSX\Reader\LibXML02-worksheet_to_row.t
692            
693             =head1 DESCRIPTION
694              
695             This documentation is written to explain ways to use this module when writing your own excel
696             parser. To use the general package for excel parsing out of the box please review the
697             documentation for L<Workbooks|Spreadsheet::XLSX::Reader::LibXML>,
698             L<Worksheets|Spreadsheet::XLSX::Reader::LibXML::Worksheet>, and
699             L<Cells|Spreadsheet::XLSX::Reader::LibXML::Cell>
700              
701             This module provides the basic connection to individual worksheet files (not chartsheets) for
702             parsing xlsx workbooks and coalating shared strings data to cell data. It does not provide
703             a way to connect to L<chartsheets|Spreadsheet::XLSX::Reader::LibXML::Chartsheet>. It does
704             not provide the final view of a given cell. The final view of the cell is collated with
705             the role (Interface) L<Spreadsheet::XLSX::Reader::LibXML::Worksheet>. This reader extends
706             the base reader class L<Spreadsheet::XLSX::Reader::LibXML::XMLReader>. The functionality
707             provided by those modules is not explained here.
708              
709             For now this module reads each full row (with values) into a L<Spreadsheet::XLSX::Reader::LibXML::Row>
710             instance. It stores only the currently read row and the previously read row. Exceptions to
711             this are the start of read and end of read. For start of read only the current row is available
712             with the assumption that all prior implied rows are empty. When a position past the end of the sheet
713             is called both current and prior rows are cleared and an 'EOF' or undef value is returned. See
714             L<Spreadsheet::XLSX::Reader::LibXML/file_boundary_flags> for more details. This allows for storage
715             of row general formats by row and where a requested cell falls in a row without values that the empty
716             state can be determined without rescanning the file.
717              
718             I<All positions (row and column places and integers) at this level are stored and returned in count
719             from one mode!>
720              
721             Modification of this module probably means extending a different reader or using other roles
722             for implementation of the class. Search for
723              
724             extends 'Spreadsheet::XLSX::Reader::LibXML::XMLReader';
725            
726             To replace the base reader. Search for the method 'worksheet' in L<Spreadsheet::XLSX::Reader::LibXML>
727             and the variable '$parser_modules' to replace this whole thing.
728              
729             =head2 Attributes
730              
731             Data passed to new when creating an instance. For access to the values in these
732             attributes see the listed 'attribute methods'. For general information on attributes see
733             L<Moose::Manual::Attributes>. For ways to manage the instance when opened see the
734             L<Public Methods|/Public Methods>.
735            
736             =head3 is_hidden
737              
738             =over
739              
740             B<Definition:> This is set when the sheet is read from the sheet metadata level indicating
741             if the sheet is hidden
742              
743             B<Default:> none
744              
745             B<Range:> (1|0)
746              
747             B<attribute methods> Methods provided to adjust this attribute
748            
749             =over
750              
751             B<is_sheet_hidden>
752              
753             =over
754              
755             B<Definition:> return the attribute value
756              
757             =back
758              
759             =back
760              
761             =back
762              
763             =head3 workbook_instance
764              
765             =over
766              
767             B<Definition:> This attribute holds a reference back to the workbook instance so that
768             the worksheet has access to the global settings managed there. As a consequence many
769             of the workbook methods are be exposed here. This includes some setter methods for
770             workbook attributes. I<Beware that setting or adjusting the workbook level attributes
771             with methods here will be universal and affect other worksheets. So don't forget to
772             return the old value if you want the old behavour after you are done.> If that
773             doesn't make sense then don't use these methods. (Nothing to see here! Move along.)
774              
775             B<Default:> a Spreadsheet::XLSX::Reader::LibXML instance
776              
777             B<attribute methods> Methods of the workbook exposed here by the L<delegation
778             |Moose::Manual::Attributes/Delegation> of the instance to this class through this
779             attribute
780              
781             =over
782              
783             B<counting_from_zero>
784              
785             =over
786              
787             B<Definition:> returns the L<Spreadsheet::XLSX::Reader::LibXML/count_from_zero>
788             instance state
789              
790             =back
791              
792             B<boundary_flag_setting>
793              
794             =over
795              
796             B<Definition:> returns the L<Spreadsheet::XLSX::Reader::LibXML/file_boundary_flags>
797             instance state
798              
799             =back
800              
801             B<change_boundary_flag( $Bool )>
802              
803             =over
804              
805             B<Definition:> sets the L<Spreadsheet::XLSX::Reader::LibXML/file_boundary_flags>
806             instance state (B<For the whole workbook!>)
807              
808             =back
809              
810             B<get_shared_string_position( $int )>
811              
812             =over
813              
814             B<Definition:> returns the shared string data stored in the sharedStrings
815             file at position $int. For more information review
816             L<Spreadsheet::XLSX::Reader::LibXML::SharedStrings>. I<This is a delegation
817             of a delegation!>
818              
819             =back
820              
821             B<get_format_position( $int, [$header] )>
822              
823             =over
824              
825             B<Definition:> returns the format data stored in the styles
826             file at position $int. If the optional $header is passed only the data for that
827             header is returned. Otherwise all styles for that position are returned.
828             For more information review
829             L<Spreadsheet::XLSX::Reader::LibXML::Styles>. I<This is a delegation
830             of a delegation!>
831              
832             =back
833              
834             B<set_empty_is_end( $Bool )>
835              
836             =over
837              
838             B<Definition:> sets the L<Spreadsheet::XLSX::Reader::LibXML/empty_is_end>
839             instance state (B<For the whole workbook!>)
840              
841             =back
842              
843             B<is_empty_the_end>
844              
845             =over
846              
847             B<Definition:> returns the L<Spreadsheet::XLSX::Reader::LibXML/empty_is_end>
848             instance state.
849              
850             =back
851              
852             B<get_group_return_type>
853              
854             =over
855              
856             B<Definition:> returns the L<Spreadsheet::XLSX::Reader::LibXML/group_return_type>
857             instance state.
858              
859             =back
860              
861             B<set_group_return_type( (instance|unformatted|value) )>
862              
863             =over
864              
865             B<Definition:> sets the L<Spreadsheet::XLSX::Reader::LibXML/group_return_type>
866             instance state (B<For the whole workbook!>)
867              
868             =back
869              
870             B<get_epoch_year>
871              
872             =over
873              
874             B<Definition:> uses the L<Spreadsheet::XLSX::Reader::LibXML/get_epoch_year> method.
875              
876             =back
877              
878             B<get_date_behavior>
879              
880             =over
881              
882             B<Definition:> This is a L<delegated|Moose::Manual::Delegation> method from the
883             L<styles|Spreadsheet::XLSX::Reader::LibXML::Styles> class (stored as a private
884             instance in the workbook). It is held (and documented) in the
885             L<Spreadsheet::XLSX::Reader::LibXML::ParseExcelFormatStrings> role. It will
886             indicate how far unformatted L<transformation
887             |Spreadsheet::XLSX::Reader::LibXML::ParseExcelFormatStrings/datetime_dates>
888             is carried for date coercions when returning formatted values.
889              
890             =back
891              
892             B<set_date_behavior>
893              
894             =over
895              
896             B<Definition:> This is a L<delegated|Moose::Manual::Delegation> method from
897             the L<styles|Spreadsheet::XLSX::Reader::LibXML::Styles> class (stored as a private
898             instance in the workbook). It is held (and documented) in the
899             L<Spreadsheet::XLSX::Reader::LibXML::ParseExcelFormatStrings> role. It will set how
900             far unformatted L<transformation
901             |Spreadsheet::XLSX::Reader::LibXML::ParseExcelFormatStrings/datetime_dates>
902             is carried for date coercions when returning formatted values.
903              
904             =back
905              
906             B<get_values_only>
907              
908             =over
909              
910             B<Definition:> gets the L<Spreadsheet::XLSX::Reader::LibXML/values_only>
911             instance state.
912              
913             =back
914              
915             B<set_values_only>
916              
917             =over
918              
919             B<Definition:> sets the L<Spreadsheet::XLSX::Reader::LibXML/values_only>
920             instance state (B<For the whole workbook!>)
921              
922             =back
923              
924             =back
925              
926             =back
927            
928             =head3 _sheet_min_col
929              
930             =over
931              
932             B<Definition:> This is the minimum column in the sheet with data or formatting. For this
933             module it is pulled from the xml file at worksheet/dimension:ref = "upperleft:lowerright"
934              
935             B<Range:> an integer
936              
937             B<attribute methods> Methods provided to adjust this attribute
938            
939             =over
940              
941             B<_set_min_col>
942              
943             =over
944              
945             B<Definition:> sets the attribute value
946              
947             =back
948              
949             B<_min_col>
950              
951             =over
952              
953             B<Definition:> returns the attribute value
954              
955             =back
956              
957             B<has_min_col>
958              
959             =over
960              
961             B<Definition:> attribute predicate
962              
963             =back
964              
965             =back
966              
967             =back
968            
969             =head3 _sheet_min_row
970              
971             =over
972              
973             B<Definition:> This is the minimum row in the sheet with data or formatting. For this
974             module it is pulled from the xml file at worksheet/dimension:ref = "upperleft:lowerright"
975              
976             B<Range:> an integer
977              
978             B<attribute methods> Methods provided to adjust this attribute
979            
980             =over
981              
982             B<_set_min_row>
983              
984             =over
985              
986             B<Definition:> sets the attribute value
987              
988             =back
989              
990             B<_min_row>
991              
992             =over
993              
994             B<Definition:> returns the attribute value
995              
996             =back
997              
998             B<has_min_row>
999              
1000             =over
1001              
1002             B<Definition:> attribute predicate
1003              
1004             =back
1005              
1006             =back
1007              
1008             =back
1009            
1010             =head3 _sheet_max_col
1011              
1012             =over
1013              
1014             B<Definition:> This is the maximum column in the sheet with data or formatting. For this
1015             module it is pulled from the xml file at worksheet/dimension:ref = "upperleft:lowerright"
1016              
1017             B<Range:> an integer
1018              
1019             B<attribute methods> Methods provided to adjust this attribute
1020            
1021             =over
1022              
1023             B<_set_max_col>
1024              
1025             =over
1026              
1027             B<Definition:> sets the attribute value
1028              
1029             =back
1030              
1031             B<_max_col>
1032              
1033             =over
1034              
1035             B<Definition:> returns the attribute value
1036              
1037             =back
1038              
1039             B<has_max_col>
1040              
1041             =over
1042              
1043             B<Definition:> attribute predicate
1044              
1045             =back
1046              
1047             =back
1048              
1049             =back
1050            
1051             =head3 _sheet_max_row
1052              
1053             =over
1054              
1055             B<Definition:> This is the maximum row in the sheet with data or formatting. For this
1056             module it is pulled from the xml file at worksheet/dimension:ref = "upperleft:lowerright"
1057              
1058             B<Range:> an integer
1059              
1060             B<attribute methods> Methods provided to adjust this attribute
1061            
1062             =over
1063              
1064             B<_set_max_row>
1065              
1066             =over
1067              
1068             B<Definition:> sets the attribute value
1069              
1070             =back
1071              
1072             B<_max_row>
1073              
1074             =over
1075              
1076             B<Definition:> returns the attribute value
1077              
1078             =back
1079              
1080             B<has_max_row>
1081              
1082             =over
1083              
1084             B<Definition:> attribute predicate
1085              
1086             =back
1087              
1088             =back
1089              
1090             =back
1091            
1092             =head3 _merge_map
1093              
1094             =over
1095              
1096             B<Definition:> This is an array ref of array refs where the first level represents rows
1097             and the second level of array represents cells. If a cell is merged then the merge span
1098             is stored in the row sub array position. This means the same span is stored in multiple
1099             positions. The data is stored in the Excel convention of count from 1 so the first position
1100             in both levels of the array are essentially placeholders. The data is extracted from the
1101             merge section of the worksheet at worksheet/mergeCells. That array is read and converted
1102             into this format for reading by this module when it first opens the worksheet.
1103              
1104             B<Range:> an array ref
1105              
1106             B<attribute methods> Methods provided to adjust this attribute
1107            
1108             =over
1109              
1110             B<_set_merge_map>
1111              
1112             =over
1113              
1114             B<Definition:> sets the attribute value
1115              
1116             =back
1117              
1118             =back
1119              
1120             B<_get_merge_map>
1121              
1122             =over
1123              
1124             B<Definition:> returns the attribute array of arrays
1125              
1126             =back
1127              
1128             =back
1129              
1130             B<delegated methods> This attribute uses the native trait 'Array'
1131            
1132             =over
1133              
1134             B<_get_row_merge_map( $int )> delgated from 'Array' 'get'
1135              
1136             =over
1137              
1138             B<Definition:> returns the sub array ref representing any merges for that
1139             row. If no merges are available for that row it returns undef.
1140              
1141             =back
1142              
1143             =back
1144            
1145             =head3 _column_formats
1146              
1147             =over
1148              
1149             B<Definition:> In order to (eventually) show all column formats that also affect individual
1150             cells the column based formats are read from the metada when the worksheet is opened. They
1151             are stored here for use although for now they are mostly used to determine the hidden state of
1152             the column. The formats are stored in the array by count from 1 column position.
1153              
1154             B<Range:> an array ref
1155              
1156             B<attribute methods> Methods provided to adjust this attribute
1157            
1158             =over
1159              
1160             B<_set_set_column_formats>
1161              
1162             =over
1163              
1164             B<Definition:> sets the attribute value
1165              
1166             =back
1167              
1168             =back
1169              
1170             B<_get_get_column_formats>
1171              
1172             =over
1173              
1174             B<Definition:> returns the attribute array
1175              
1176             =back
1177              
1178             =back
1179              
1180             B<delegated methods> This attribute uses the native trait 'Array'
1181            
1182             =over
1183              
1184             B<_get_custom_column_data( $int )> delgated from 'Array' 'get'
1185              
1186             =over
1187              
1188             B<Definition:> returns the sub hash ref representing any formatting
1189             for that column. If no custom formatting is available it returns undef.
1190              
1191             =back
1192              
1193             =back
1194            
1195             =head3 _old_row_inst
1196              
1197             =over
1198              
1199             B<Definition:> This is the prior read row instance or undef for the beginning or
1200             end of the sheet read.
1201              
1202             B<Range:> isa => InstanceOf[ L<Spreadsheet::XLSX::Reader::LibXML::Row> ]
1203              
1204             B<attribute methods> Methods provided to adjust this attribute
1205            
1206             =over
1207              
1208             B<_set_old_row_inst>
1209              
1210             =over
1211              
1212             B<Definition:> sets the attribute value
1213              
1214             =back
1215              
1216             B<_get_old_row_inst>
1217              
1218             =over
1219              
1220             B<Definition:> returns the attribute
1221              
1222             =back
1223              
1224             B<_clear_old_row_inst>
1225              
1226             =over
1227              
1228             B<Definition:> clears the attribute
1229              
1230             =back
1231              
1232             B<_has_old_row_inst>
1233              
1234             =over
1235              
1236             B<Definition:> predicate for the attribute
1237              
1238             =back
1239              
1240             B<delegated methods> from L<Spreadsheet::XLSX::Reader::LibXML::Row>
1241            
1242             =over
1243              
1244             B<_get_old_row_number> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_number>
1245              
1246             B<_is_old_row_hidden> = L<Spreadsheet::XLSX::Reader::LibXML::Row/is_row_hidden>
1247              
1248             B<_get_old_row_formats> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_format>
1249              
1250             =over
1251              
1252             pass the desired format key
1253              
1254             =back
1255              
1256             B<_get_old_column> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_the_column( $column )>
1257              
1258             =over
1259              
1260             pass a column number (no next default) returns (cell|undef|EOR)
1261              
1262             =back
1263              
1264             B<_get_old_last_value_col> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_last_value_column>
1265              
1266             B<_get_old_row_list> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_all>
1267              
1268             B<_get_old_row_end> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_endl>
1269              
1270             =back
1271              
1272             =back
1273              
1274             =back
1275            
1276             =head3 _new_row_inst
1277              
1278             =over
1279              
1280             B<Definition:> This is the current read row instance or undef for the end of the sheet
1281             read.
1282              
1283             B<Range:> isa => InstanceOf[ L<Spreadsheet::XLSX::Reader::LibXML::Row> ]
1284              
1285             B<attribute methods> Methods provided to adjust this attribute
1286            
1287             =over
1288              
1289             B<_set_new_row_inst>
1290              
1291             =over
1292              
1293             B<Definition:> sets the attribute value
1294              
1295             =back
1296              
1297             B<_get_new_row_inst>
1298              
1299             =over
1300              
1301             B<Definition:> returns the attribute
1302              
1303             =back
1304              
1305             B<_clear_new_row_inst>
1306              
1307             =over
1308              
1309             B<Definition:> clears the attribute
1310              
1311             =back
1312              
1313             B<_has_new_row_inst>
1314              
1315             =over
1316              
1317             B<Definition:> predicate for the attribute
1318              
1319             =back
1320              
1321             B<delegated methods> from L<Spreadsheet::XLSX::Reader::LibXML::Row>
1322            
1323             =over
1324              
1325             B<_get_new_row_number> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_number>
1326              
1327             B<_is_new_row_hidden> = L<Spreadsheet::XLSX::Reader::LibXML::Row/is_row_hidden>
1328              
1329             B<_get_new_row_formats> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_format>
1330              
1331             =over
1332              
1333             pass the desired format key
1334              
1335             =back
1336              
1337             B<_get_new_column> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_the_column( $column )>
1338              
1339             =over
1340              
1341             pass a column number (no next default) returns (cell|undef|EOR)
1342              
1343             =back
1344              
1345             B<_get_new_next_value> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_the_next_value_position>
1346              
1347             =over
1348              
1349             pass nothing returns next (cell|EOR)
1350              
1351             =back
1352              
1353             B<_get_new_last_value_col> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_last_value_column>
1354              
1355             B<_get_new_row_list> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_all>
1356              
1357             B<_get_new_row_end> = L<Spreadsheet::XLSX::Reader::LibXML::Row/get_row_endl>
1358              
1359             =back
1360              
1361             =back
1362              
1363             =back
1364            
1365             =head3 _row_hidden_states
1366              
1367             =over
1368              
1369             B<Definition:> As the worksheet is parsed it will store the hidden state for
1370             the row in this attribute when each row is read. This is the only worksheet
1371             level caching done. B<It will not test whether the requested row hidden state
1372             has been read when accessing this data.> If a method call a row past the
1373             current max parsed row it will return 0 (unhidden).
1374              
1375             B<Range:> an array ref of Boolean values
1376              
1377             B<delegated methods> This attribute uses the native trait 'Array'
1378            
1379             =over
1380              
1381             B<_set_row_hidden( $int )> delgated from 'Array' 'set'
1382              
1383             =over
1384              
1385             B<Definition:> sets the hidden state for that $int (row) counting from 1.
1386              
1387             =back
1388              
1389             B<_get_row_hidden( $int )> delgated from 'Array' 'get'
1390              
1391             =over
1392              
1393             B<Definition:> returns the known hidden state of the row.
1394              
1395             =back
1396              
1397             =back
1398              
1399             =back
1400              
1401             =head2 Methods
1402              
1403             These are the methods provided by this class for use within the package but are not intended
1404             to be used by the end user. Other private methods not listed here are used in the module but
1405             not used by the package. If the private method is listed here then replacement of this module
1406             either requires replacing them or rewriting all the associated connecting roles and classes.
1407              
1408             =head3 _load_unique_bits
1409              
1410             =over
1411              
1412             B<Definition:> This is called by L<Spreadsheet::XLSX::Reader::LibXML::XMLReader> when the file is
1413             loaded for the first time so that file specific metadata can be collected.
1414              
1415             B<Accepts:> nothing
1416              
1417             B<Returns:> nothing
1418              
1419             =back
1420              
1421             =head3 _get_next_value_cell
1422              
1423             =over
1424              
1425             B<Definition:> This returns the worksheet file hash ref representation of the xml stored for the
1426             'next' value cell. A cell is determined to have value based on the attribute
1427             L<Spreadsheet::XLSX::Reader::LibXML/values_only>. Next is affected by the attribute
1428             L<Spreadsheet::XLSX::Reader::LibXML/empty_is_end>. This method never returns an 'EOR' flag.
1429             It just wraps automatically. This does return values from the shared strings file integrated but
1430             not values from the Styles file integrated.
1431              
1432             B<Accepts:> nothing
1433              
1434             B<Returns:> a hashref of key value pairs
1435              
1436             =back
1437              
1438             =head3 _get_col_row( $col, $row )
1439              
1440             =over
1441              
1442             B<Definition:> This is the way to return the information about a specific position in the worksheet.
1443             Since this is a private method it requires its inputs to be in the 'count from one' index.
1444              
1445             B<Accepts:> ( $column, $row ) - both required in that order
1446              
1447             B<Returns:> whatever is in that worksheet position as a hashref
1448              
1449             =back
1450              
1451             =head3 _get_row_all( $row )
1452              
1453             =over
1454              
1455             B<Definition:> This is returns an array ref of each of the values in the row placed in their 'count
1456             from one' position. If the row is empty but it is not the end of the sheet then this will return an
1457             empty array ref.
1458              
1459             B<Accepts:> ( $row ) - required
1460              
1461             B<Returns:> an array ref
1462              
1463             =back
1464              
1465             =head3 _is_column_hidden( @query_list )
1466              
1467             =over
1468              
1469             B<Definition:> This is returns a list of hidden states for each column integer in the @query_list
1470             it will generally return n array ref of each of the values in the row placed in their 'count
1471             from one' position. If the row is empty but it is not the end of the sheet then this will return an
1472             empty array ref.
1473              
1474             B<Accepts:> ( @query_list ) - integers in count from 1 representing requested columns
1475              
1476             B<Returns (when wantarray):> a list of hidden states as follows; 1 => hidden, 0 => known to be unhidden,
1477             undef => unknown state (usually this represents columns before min_col or after max_col or at least past
1478             the last stored value in the column)
1479              
1480             =back
1481              
1482             =head1 SUPPORT
1483              
1484             =over
1485              
1486             L<github Spreadsheet::XLSX::Reader::LibXML/issues
1487             |https://github.com/jandrew/Spreadsheet-XLSX-Reader-LibXML/issues>
1488              
1489             =back
1490              
1491             =head1 TODO
1492              
1493             =over
1494              
1495             B<1.> Nothing L<yet|/SUPPORT>
1496              
1497             =back
1498              
1499             =head1 AUTHOR
1500              
1501             =over
1502              
1503             =item Jed Lund
1504              
1505             =item jandrew@cpan.org
1506              
1507             =back
1508              
1509             =head1 COPYRIGHT
1510              
1511             This program is free software; you can redistribute
1512             it and/or modify it under the same terms as Perl itself.
1513              
1514             The full text of the license can be found in the
1515             LICENSE file included with this module.
1516              
1517             This software is copyrighted (c) 2014, 2015 by Jed Lund
1518              
1519             =head1 DEPENDENCIES
1520              
1521             =over
1522              
1523             L<version>
1524              
1525             L<perl 5.010|perl/5.10.0>
1526              
1527             L<Moose>
1528              
1529             L<MooseX::StrictConstructor>
1530              
1531             L<MooseX::HasDefaults::RO>
1532              
1533             L<Clone> - clone
1534              
1535             L<Carp> - confess
1536              
1537             L<Type::Tiny> - 1.000
1538              
1539             L<MooseX::ShortCut::BuildInstance> - build_instance should_re_use_classes
1540              
1541             L<Spreadsheet::XLSX::Reader::LibXML>
1542              
1543             L<Spreadsheet::XLSX::Reader::LibXML::XMLReader>
1544              
1545             L<Spreadsheet::XLSX::Reader::LibXML::Row>
1546              
1547             L<Spreadsheet::XLSX::Reader::LibXML::CellToColumnRow>
1548              
1549             L<Spreadsheet::XLSX::Reader::LibXML::XMLToPerlData>
1550              
1551             =back
1552              
1553             =head1 SEE ALSO
1554              
1555             =over
1556              
1557             L<Log::Shiras|https://github.com/jandrew/Log-Shiras>
1558              
1559             =over
1560              
1561             All lines in this package that use Log::Shiras are commented out
1562              
1563             =back
1564              
1565             =back
1566              
1567             =cut
1568              
1569             #########1 Documentation End 3#########4#########5#########6#########7#########8#########9