File Coverage

lib/Spreadsheet/Reader/ExcelXML/ZipReader/WorkbookMeta.pm
Criterion Covered Total %
statement 47 47 100.0
branch 11 16 68.7
condition n/a
subroutine 5 5 100.0
pod 1 1 100.0
total 64 69 92.7


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