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