File Coverage

lib/Spreadsheet/Reader/ExcelXML/XMLReader/WorkbookMeta.pm
Criterion Covered Total %
statement 58 59 98.3
branch 12 14 85.7
condition 4 6 66.6
subroutine 6 6 100.0
pod 1 1 100.0
total 81 86 94.1


line stmt bran cond sub pod time code
1             package Spreadsheet::Reader::ExcelXML::XMLReader::WorkbookMeta;
2             our $AUTHORITY = 'cpan:JANDREW';
3 3     3   10372 use version; our $VERSION = version->declare('v0.16.8');
  3         3  
  3         22  
4             ###LogSD warn "You uncovered internal logging statements for Spreadsheet::Reader::ExcelXML::XMLReader::WorkbookMeta-$VERSION";
5              
6 3     3   312 use Moose::Role;
  3         6  
  3         26  
7             requires qw(
8             advance_element_position parse_element start_the_file_over
9             close_the_file squash_node current_node_parsed
10             next_sibling skip_siblings good_load
11             );
12 3     3   11412 use Types::Standard qw( Enum ArrayRef HashRef Bool);
  3         3  
  3         27  
13 3     3   2745 use lib '../../../../../lib',;
  3         4  
  3         20  
14             ###LogSD use Log::Shiras::Telephone;
15              
16             #########1 Dispatch Tables 3#########4#########5#########6#########7#########8#########9
17              
18              
19              
20             #########1 Public Attributes 3#########4#########5#########6#########7#########8#########9
21              
22              
23              
24             #########1 Public Methods 3#########4#########5#########6#########7#########8#########9
25              
26             sub load_unique_bits{
27 4     4 1 9 my( $self, ) = @_;
28             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
29             ###LogSD $self->get_all_space . '::load_unique_bits', );
30             ###LogSD $phone->talk( level => 'debug', message => [
31             ###LogSD "Setting the WorkbookMetaInterface unique bits" ] );
32              
33             # Set date epoch
34 4         42 $self->start_the_file_over;
35 4         29 my( $result, $node_name, $node_level, $node_ref ) = $self->advance_element_position( 'Date1904' );
36             ###LogSD $phone->talk( level => 'debug', message => [
37             ###LogSD "Apple date search result: " . ($result//'undef') ] );
38 4         11 my $epoch_start = 1900;
39 4 100       13 if( $result ){
40 3         25 my $workbookPr_ref = $self->parse_element;
41             ###LogSD $phone->talk( level => 'debug', message => [
42             ###LogSD "This is a 1904 epoch sheet" ] );
43 3         7 $epoch_start = 1904;
44             }
45             ###LogSD $phone->talk( level => 'debug', message => [
46             ###LogSD "Setting epoch start to: $epoch_start" ] );
47 4         107 $self->_set_epoch_year( $epoch_start );
48             ###LogSD $phone->talk( level => 'trace', message =>[ "Epoch year set" ] );
49              
50             # Build sheet list
51 4         5 my( $sheet_lookup, $id_lookup, $sheet_list );
52 4         14 $self->start_the_file_over;
53 4         18 ( $result, $node_name, $node_level, $node_ref ) = $self->advance_element_position( 'Worksheet' );# Chartsheets don't appear to be allowed in SpreadsheetML format
54             ###LogSD $phone->talk( level => 'debug', message => [
55             ###LogSD "Arrived at node name -$node_name- with result: $result" ] );
56 4 50       14 if( $result ){
57 4         10 my $position = 0;
58 4         38 my $top_ref = $self->current_node_parsed;
59             ###LogSD $phone->talk( level => 'debug', message => [
60             ###LogSD "Current node parsed to:", $top_ref ] );
61 4         14 COLLECTSHEETDATA: while( $node_name eq 'Worksheet' ){# Redundant on the first pass
62 10         23 my $sheet_name = $top_ref->{Worksheet}->{'ss:Name'};
63 10         19 my $sheet_id = $position + 1;
64 10         19 push @$sheet_list, $sheet_name;
65 10         30 $id_lookup->{$sheet_id} = $sheet_name;
66             ###LogSD $phone->talk( level => 'debug', message =>[
67             ###LogSD "Worksheet node named: $sheet_name",
68             ###LogSD "Worksheet position: $position",
69             ###LogSD "Worksheet ID: $sheet_id", $top_ref, $sheet_list, $id_lookup ] );
70 10         33 ( $result, $node_name, $node_level, $node_ref ) = $self->advance_element_position;
71             ###LogSD $phone->talk( level => 'debug', message => [
72             ###LogSD "Arrived at node name -$node_name- with result: $result" ] );
73 10 50       25 last COLLECTSHEETDATA if !$result;
74 10         31 my $lower_ref = $self->current_node_parsed;
75             ###LogSD $phone->talk( level => 'debug', message =>[ "Lower node is:", $lower_ref ] );
76 10   66     55 COLLECTWORKSHEETOPTIONS: while( $result and $node_name ne 'WorksheetOptions' ){
77 10         41 ( $result, $node_name, $node_level, $node_ref ) = $self->next_sibling;
78 10 100       63 last COLLECTWORKSHEETOPTIONS if !$result;
79             ###LogSD $phone->talk( level => 'debug', message =>[
80             ###LogSD "Next sibling node may be: $node_name", ] );
81             }
82             # Load the sheet settings
83 10         28 my $options_ref;
84 10 100       25 if( $result ){# For specific settings in the file
85 9         36 $options_ref = $self->squash_node( $self->parse_element );
86             ###LogSD $phone->talk( level => 'trace', message =>[
87             ###LogSD "Fulls WorksheetOptions node:", $options_ref ] );
88 9         23 delete $options_ref->{raw_text};
89 9         16 delete $options_ref->{xmlns};
90             }
91             $options_ref->{is_hidden} =
92 10 100 66     61 (exists $options_ref->{Visible} and $options_ref->{Visible} eq 'SheetHidden') ? 1 : 0;
93 10         48 @$options_ref{qw( sheet_id sheet_name sheet_position )} =
94             ( $sheet_id, $sheet_name, $position );
95             ###LogSD $phone->talk( level => 'debug', message =>[
96             ###LogSD "Built sheet data:", $options_ref ] );
97 10         26 $sheet_lookup->{$sheet_name} = $options_ref;
98             ###LogSD $phone->talk( level => 'trace', message =>[
99             ###LogSD "Updated sheet lookup:", $sheet_lookup, $self->current_node_parsed ] );
100 10         37 ( $result, $node_name, $node_level, $node_ref ) = $self->advance_element_position( 'Worksheet' );
101             ###LogSD $phone->talk( level => 'debug', message =>[
102             ###LogSD "Advanced to node -$node_name- with the result: " . ($result//'') ] );
103 10 100       51 last COLLECTSHEETDATA if !$result;
104 6         34 $top_ref = $self->current_node_parsed;
105             ###LogSD $phone->talk( level => 'debug', message =>[ "Next top node is:", $top_ref] );
106 6         50 $position++;
107             }
108             ###LogSD $phone->talk( level => 'info', message =>[ "Made it out of COLLECTSHEETDATA" ] );
109             }else{
110 0         0 confess "Could not find any worksheets";
111             }
112              
113             ###LogSD $phone->talk( level => 'debug', message =>[ "Setting attributes" ] );
114 4         112 $self->_set_sheet_list( $sheet_list );
115 4         107 $self->_set_sheet_lookup( $sheet_lookup );
116 4         102 $self->_set_id_lookup( $id_lookup );
117 4         28 $self->close_the_file;
118 4         108 $self->good_load( 1 );
119             ###LogSD $phone->talk( level => 'info', message =>[ "Returning" ] );
120 4         15 return 1;
121             }
122              
123              
124              
125             #########1 Private Attributes 3#########4#########5#########6#########7#########8#########9
126              
127             has _epoch_year =>(
128             isa => Enum[qw( 1900 1904 )],
129             writer => '_set_epoch_year',
130             reader => 'get_epoch_year',
131             default => 1900,
132             );
133              
134             has _sheet_list =>(
135             isa => ArrayRef,
136             traits => ['Array'],
137             writer => '_set_sheet_list',
138             clearer => '_clear_sheet_list',
139             reader => 'get_sheet_list',
140             handles =>{
141             _get_sheet_name => 'get',
142             _sheet_count => 'count',
143             },
144             default => sub{ [] },
145             );
146              
147             has _sheet_lookup =>(
148             isa => HashRef,
149             traits => ['Hash'],
150             writer => '_set_sheet_lookup',
151             clearer => '_clear_sheet_lookup',
152             reader => 'get_sheet_lookup',
153             handles =>{
154             _get_sheet_info => 'get',
155             _set_sheet_info => 'set',
156             },
157             default => sub{ {} },
158             );
159              
160             has _rel_lookup =>(
161             isa => HashRef,
162             traits => ['Hash'],
163             writer => '_set_rel_lookup',
164             reader => 'get_rel_lookup',
165             handles =>{
166             _get_rel_info => 'get',
167             },
168             default => sub{ {} },
169             );
170              
171             has _id_lookup =>(
172             isa => HashRef,
173             traits => ['Hash'],
174             writer => '_set_id_lookup',
175             reader => 'get_id_lookup',
176             handles =>{
177             _get_id_info => 'get',
178             },
179             default => sub{ {} },
180             );
181              
182             #########1 Private Methods 3#########4#########5#########6#########7#########8#########9
183              
184              
185              
186             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
187              
188 3     3   1599 no Moose::Role;
  3         4  
  3         15  
189             1;
190              
191             #########1 Documentation 3#########4#########5#########6#########7#########8#########9
192             __END__
193              
194             =head1 NAME
195              
196             Spreadsheet::Reader::ExcelXML::XMLReader::WorkbookMeta - XML file Workbook Meta unique reader
197              
198             =head1 SYNOPSIS
199              
200             use MooseX::ShortCut::BuildInstance qw( build_instance );
201             use Spreadsheet::Reader::ExcelXML::XMLReader;
202             use Spreadsheet::Reader::ExcelXML::XMLReader::WorkbookMeta;
203             use Spreadsheet::Reader::ExcelXML::WorkbookMetaInterface; # Optional
204             $meta_instance = build_instance(
205             superclasses => ['Spreadsheet::Reader::ExcelXML::XMLReader'],
206             add_roles_in_sequence =>[
207             'Spreadsheet::Reader::ExcelXML::XMLReader::WorkbookMeta',
208             'Spreadsheet::Reader::ExcelXML::WorkbookMetaInterface',
209             ],
210             file => 'TestBook.xml', (for xml flat files the meta parser needs the whole file)
211             );
212             $meta_instance->get_epoch_year;
213              
214             ###########################
215             # SYNOPSIS Screen Output
216             # 01: 1904
217             ###########################
218              
219             =head1 DESCRIPTION
220              
221             This documentation is written to explain ways to use this module when writing your own
222             excel parser. To use the general package for excel parsing out of the box please review
223             the documentation for L<Workbooks|Spreadsheet::Reader::ExcelXML>,
224             L<Worksheets|Spreadsheet::Reader::ExcelXML::Worksheet>, and
225             L<Cells|Spreadsheet::Reader::ExcelXML::Cell>
226              
227             This is the XML based file adaptor for reading the workbook meta data. The file can contain
228             several default sets of information that should be gathered. They can all be retrieved post
229             file initialization with L<Methods|/Methods>. The goal is to standardize the outputs of this
230             metadata from non standard inputs.
231              
232             =head2 Required Methods
233              
234             These are the methods required by the role. A link to the default implementation of
235             these methods is provided.
236              
237             L<Spreadsheet::Reader::ExcelXML::XMLReader/advance_element_position( $element, [$iterations] )>
238              
239             L<Spreadsheet::Reader::ExcelXML::XMLReader/parse_element( [$depth] )>
240              
241             L<Spreadsheet::Reader::ExcelXML::XMLReader/start_the_file_over>
242              
243             L<Spreadsheet::Reader::ExcelXML::XMLReader/close_the_file>
244              
245             L<Spreadsheet::Reader::ExcelXML::XMLReader/squash_node( $node )>
246              
247             L<Spreadsheet::Reader::ExcelXML::XMLReader/current_node_parsed>
248              
249             L<Spreadsheet::Reader::ExcelXML::XMLReader/next_sibling>
250              
251             L<Spreadsheet::Reader::ExcelXML::XMLReader/skip_siblings>
252              
253             L<Spreadsheet::Reader::ExcelXML::XMLReader/good_load( $state )>
254              
255             =head2 Methods
256              
257             These are the methods provided by this role (only).
258              
259             =head3 load_unique_bits
260              
261             =over
262              
263             B<Definition:> This role is meant to run on top of L<Spreadsheet::Reader::ExcelXML::XMLReader>.
264             When it does the reader will call this function as available when it first starts the file.
265             Therefore this is where the unique Metadata for this file is found and stored. (in the
266             attributes)
267              
268             B<Accepts:> nothing
269              
270             B<Returns:> nothing
271              
272             =back
273              
274             =head3 get_epoch_year
275              
276             =over
277              
278             B<Definition:> returns the parsed epoch year that should be found in this file
279              
280             B<Accepts:> nothing
281              
282             B<Returns:> (1900|1904)
283              
284             =back
285              
286             =head3 get_sheet_list
287              
288             =over
289              
290             B<Definition:> returns the full array ref containg all discovered sheets in the
291             file. This will include worksheets and chartsheets.
292              
293             B<Accepts:> nothing
294              
295             B<Returns:> an array ref of strings
296              
297             =back
298              
299             =head3 get_rel_lookup
300              
301             =over
302              
303             B<Definition:> returns the hashref with relId's as keys and the sheet name as
304             values
305              
306             B<Accepts:> nothing
307              
308             B<Returns:> a hash ref with $relId => $sheet_name combos
309              
310             =back
311              
312             =head3 get_id_lookup
313              
314             =over
315              
316             B<Definition:> returns the hashref with sheet id's as keys and the sheet
317             name as values. I beleive that Sheet ID's are the id number used in vbscript
318             to identify the sheet.
319              
320             B<Accepts:> nothing
321              
322             B<Returns:> a hash ref with $sheetId => $sheet_name combos
323              
324             =back
325              
326             =head1 SUPPORT
327              
328             =over
329              
330             L<github Spreadsheet::Reader::ExcelXML/issues
331             |https://github.com/jandrew/p5-spreadsheet-reader-excelxml/issues>
332              
333             =back
334              
335             =head1 TODO
336              
337             =over
338              
339             B<1.> Nothing currently
340              
341             =back
342              
343             =head1 AUTHOR
344              
345             =over
346              
347             =item Jed Lund
348              
349             =item jandrew@cpan.org
350              
351             =back
352              
353             =head1 COPYRIGHT
354              
355             This program is free software; you can redistribute
356             it and/or modify it under the same terms as Perl itself.
357              
358             The full text of the license can be found in the
359             LICENSE file included with this module.
360              
361             This software is copyrighted (c) 2016 by Jed Lund
362              
363             =head1 DEPENDENCIES
364              
365             =over
366              
367             L<Spreadsheet::Reader::ExcelXML> - the package
368              
369             =back
370              
371             =head1 SEE ALSO
372              
373             =over
374              
375             L<Spreadsheet::Read> - generic Spreadsheet reader
376              
377             L<Spreadsheet::ParseExcel> - Excel binary version 2003 and earlier (.xls files)
378              
379             L<Spreadsheet::XLSX> - Excel version 2007 and later
380              
381             L<Spreadsheet::ParseXLSX> - Excel version 2007 and later
382              
383             L<Log::Shiras|https://github.com/jandrew/Log-Shiras>
384              
385             =over
386              
387             All lines in this package that use Log::Shiras are commented out
388              
389             =back
390              
391             =back
392              
393             =cut
394              
395             #########1#########2 main pod documentation end 5#########6#########7#########8#########9