File Coverage

blib/lib/Excel/Writer/XLSX/Package/Packager.pm
Criterion Covered Total %
statement 429 430 99.7
branch 64 66 96.9
condition 6 6 100.0
subroutine 45 45 100.0
pod 0 1 0.0
total 544 548 99.2


line stmt bran cond sub pod time code
1             package Excel::Writer::XLSX::Package::Packager;
2              
3             ###############################################################################
4             #
5             # Packager - A class for creating the Excel XLSX package.
6             #
7             # Used in conjunction with Excel::Writer::XLSX
8             #
9             # Copyright 2000-2020, John McNamara, jmcnamara@cpan.org
10             #
11             # Documentation after __END__
12             #
13              
14             # perltidy with the following options: -mbl=2 -pt=0 -nola
15              
16 1081     1081   24948 use 5.008002;
  1081         5149  
17 1081     1081   7375 use strict;
  1081         2345  
  1081         28164  
18 1081     1081   6347 use warnings;
  1081         3525  
  1081         33872  
19 1081     1081   6461 use Exporter;
  1081         3406  
  1081         34183  
20 1081     1081   5507 use Carp;
  1081         5271  
  1081         59399  
21 1081     1081   7651 use File::Copy;
  1081         4784  
  1081         70117  
22 1081     1081   485196 use Excel::Writer::XLSX::Package::App;
  1081         4019  
  1081         53113  
23 1081     1081   467787 use Excel::Writer::XLSX::Package::Comments;
  1081         5541  
  1081         60737  
24 1081     1081   482181 use Excel::Writer::XLSX::Package::ContentTypes;
  1081         4393  
  1081         53025  
25 1081     1081   471498 use Excel::Writer::XLSX::Package::Core;
  1081         5514  
  1081         53084  
26 1081     1081   450492 use Excel::Writer::XLSX::Package::Custom;
  1081         2773  
  1081         52739  
27 1081     1081   448776 use Excel::Writer::XLSX::Package::Relationships;
  1081         4376  
  1081         53257  
28 1081     1081   443590 use Excel::Writer::XLSX::Package::SharedStrings;
  1081         5271  
  1081         51758  
29 1081     1081   525348 use Excel::Writer::XLSX::Package::Styles;
  1081         6282  
  1081         58590  
30 1081     1081   471777 use Excel::Writer::XLSX::Package::Table;
  1081         4042  
  1081         51849  
31 1081     1081   517117 use Excel::Writer::XLSX::Package::Theme;
  1081         8413  
  1081         60530  
32 1081     1081   520052 use Excel::Writer::XLSX::Package::VML;
  1081         4190  
  1081         3578603  
33              
34             our @ISA = qw(Exporter);
35             our $VERSION = '1.07';
36              
37              
38             ###############################################################################
39             #
40             # Public and private API methods.
41             #
42             ###############################################################################
43              
44              
45             ###############################################################################
46             #
47             # new()
48             #
49             # Constructor.
50             #
51             sub new {
52              
53 849     849 0 2625 my $class = shift;
54 849         2117 my $fh = shift;
55 849         3951 my $self = Excel::Writer::XLSX::Package::XMLwriter->new( $fh );
56              
57 849         3556 $self->{_package_dir} = '';
58 849         2495 $self->{_workbook} = undef;
59 849         2969 $self->{_worksheet_count} = 0;
60 849         2419 $self->{_chartsheet_count} = 0;
61 849         2515 $self->{_chart_count} = 0;
62 849         2373 $self->{_drawing_count} = 0;
63 849         3271 $self->{_table_count} = 0;
64 849         2885 $self->{_named_ranges} = [];
65              
66              
67 849         2436 bless $self, $class;
68              
69 849         3140 return $self;
70             }
71              
72              
73             ###############################################################################
74             #
75             # _set_package_dir()
76             #
77             # Set the XLSX OPC package directory.
78             #
79             sub _set_package_dir {
80              
81 849     849   2111 my $self = shift;
82              
83 849         2621 $self->{_package_dir} = shift;
84             }
85              
86              
87             ###############################################################################
88             #
89             # _add_workbook()
90             #
91             # Add the Excel::Writer::XLSX::Workbook object to the package.
92             #
93             sub _add_workbook {
94              
95 849     849   2143 my $self = shift;
96 849         1799 my $workbook = shift;
97              
98 849         4939 $self->{_workbook} = $workbook;
99 849         1952 $self->{_chart_count} = scalar @{ $workbook->{_charts} };
  849         2576  
100 849         1884 $self->{_drawing_count} = scalar @{ $workbook->{_drawings} };
  849         2518  
101 849         2414 $self->{_num_vml_files} = $workbook->{_num_vml_files};
102 849         2373 $self->{_num_comment_files} = $workbook->{_num_comment_files};
103 849         2307 $self->{_named_ranges} = $workbook->{_named_ranges};
104              
105 849         1901 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3260  
106 996 100       4110 if ( $worksheet->{_is_chartsheet} ) {
107 20         70 $self->{_chartsheet_count}++;
108             }
109             else {
110 976         3239 $self->{_worksheet_count}++;
111             }
112             }
113             }
114              
115              
116             ###############################################################################
117             #
118             # _create_package()
119             #
120             # Write the xml files that make up the XLXS OPC package.
121             #
122             sub _create_package {
123              
124 849     849   2044 my $self = shift;
125              
126 849         4443 $self->_write_worksheet_files();
127 849         69632 $self->_write_chartsheet_files();
128 849         5131 $self->_write_workbook_file();
129 849         36139 $self->_write_chart_files();
130 849         23553 $self->_write_drawing_files();
131 849         21357 $self->_write_vml_files();
132 849         4084 $self->_write_comment_files();
133 849         5677 $self->_write_table_files();
134 849         3991 $self->_write_shared_strings_file();
135 849         15207 $self->_write_app_file();
136 849         41746 $self->_write_core_file();
137 849         40494 $self->_write_custom_file();
138 849         4352 $self->_write_content_types_file();
139 849         40933 $self->_write_styles_file();
140 849         44654 $self->_write_theme_file();
141 849         33598 $self->_write_root_rels_file();
142 849         40579 $self->_write_workbook_rels_file();
143 849         36391 $self->_write_worksheet_rels_files();
144 849         25052 $self->_write_chartsheet_rels_files();
145 849         4501 $self->_write_drawing_rels_files();
146 849         20661 $self->_add_image_files();
147 849         34052 $self->_add_vba_project();
148             }
149              
150              
151             ###############################################################################
152             #
153             # _write_workbook_file()
154             #
155             # Write the workbook.xml file.
156             #
157             sub _write_workbook_file {
158              
159 849     849   2185 my $self = shift;
160 849         2455 my $dir = $self->{_package_dir};
161 849         2144 my $workbook = $self->{_workbook};
162              
163 849         5240 _mkdir( $dir . '/xl' );
164              
165 849         6710 $workbook->_set_xml_writer( $dir . '/xl/workbook.xml' );
166 849         10959 $workbook->_assemble_xml_file();
167             }
168              
169              
170             ###############################################################################
171             #
172             # _write_worksheet_files()
173             #
174             # Write the worksheet files.
175             #
176             sub _write_worksheet_files {
177              
178 849     849   2000 my $self = shift;
179 849         2402 my $dir = $self->{_package_dir};
180              
181 849         26533 _mkdir( $dir . '/xl' );
182 849         4927 _mkdir( $dir . '/xl/worksheets' );
183              
184 849         3061 my $index = 1;
185 849         2084 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3730  
186 996 100       10813 next if $worksheet->{_is_chartsheet};
187              
188 976         4676 $worksheet->_set_xml_writer(
189             $dir . '/xl/worksheets/sheet' . $index++ . '.xml' );
190 976         5324 $worksheet->_assemble_xml_file();
191              
192             }
193             }
194              
195              
196             ###############################################################################
197             #
198             # _write_chartsheet_files()
199             #
200             # Write the chartsheet files.
201             #
202             sub _write_chartsheet_files {
203              
204 849     849   3243 my $self = shift;
205 849         2534 my $dir = $self->{_package_dir};
206              
207 849         2071 my $index = 1;
208 849         2767 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         4058  
209 996 100       4719 next unless $worksheet->{_is_chartsheet};
210              
211 20         96 _mkdir( $dir . '/xl' );
212 20         115 _mkdir( $dir . '/xl/chartsheets' );
213              
214 20         128 $worksheet->_set_xml_writer(
215             $dir . '/xl/chartsheets/sheet' . $index++ . '.xml' );
216 20         116 $worksheet->_assemble_xml_file();
217              
218             }
219             }
220              
221              
222             ###############################################################################
223             #
224             # _write_chart_files()
225             #
226             # Write the chart files.
227             #
228             sub _write_chart_files {
229              
230 849     849   3507 my $self = shift;
231 849         2357 my $dir = $self->{_package_dir};
232              
233 849 100       1779 return unless @{ $self->{_workbook}->{_charts} };
  849         4250  
234              
235 377         1832 _mkdir( $dir . '/xl' );
236 377         2255 _mkdir( $dir . '/xl/charts' );
237              
238 377         1390 my $index = 1;
239 377         867 for my $chart ( @{ $self->{_workbook}->{_charts} } ) {
  377         1638  
240 418         3657 $chart->_set_xml_writer(
241             $dir . '/xl/charts/chart' . $index++ . '.xml' );
242 418         4544 $chart->_assemble_xml_file();
243              
244             }
245             }
246              
247              
248             ###############################################################################
249             #
250             # _write_drawing_files()
251             #
252             # Write the drawing files.
253             #
254             sub _write_drawing_files {
255              
256 849     849   2004 my $self = shift;
257 849         2266 my $dir = $self->{_package_dir};
258              
259 849 100       3401 return unless $self->{_drawing_count};
260              
261 465         2559 _mkdir( $dir . '/xl' );
262 465         2732 _mkdir( $dir . '/xl/drawings' );
263              
264 465         1822 my $index = 1;
265 465         1114 for my $drawing ( @{ $self->{_workbook}->{_drawings} } ) {
  465         2174  
266 503         3676 $drawing->_set_xml_writer(
267             $dir . '/xl/drawings/drawing' . $index++ . '.xml' );
268 503         3091 $drawing->_assemble_xml_file();
269             }
270             }
271              
272              
273             ###############################################################################
274             #
275             # _write_vml_files()
276             #
277             # Write the comment VML files.
278             #
279             sub _write_vml_files {
280              
281 849     849   2375 my $self = shift;
282 849         2505 my $dir = $self->{_package_dir};
283              
284 849         2211 my $index = 1;
285 849         1963 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3628  
286              
287 996 100 100     7636 next if !$worksheet->{_has_vml} and !$worksheet->{_has_header_vml};
288              
289 78         343 _mkdir( $dir . '/xl' );
290 78         419 _mkdir( $dir . '/xl/drawings' );
291              
292 78 100       412 if ( $worksheet->{_has_vml} ) {
293 57         602 my $vml = Excel::Writer::XLSX::Package::VML->new();
294              
295 57         219 $vml->_set_xml_writer(
296             $dir . '/xl/drawings/vmlDrawing' . $index . '.vml' );
297             $vml->_assemble_xml_file(
298             $worksheet->{_vml_data_id}, $worksheet->{_vml_shape_id},
299             $worksheet->{_comments_array}, $worksheet->{_buttons_array},
300             undef
301 57         434 );
302              
303 57         3047 $index++;
304             }
305              
306 78 100       524 if ( $worksheet->{_has_header_vml} ) {
307 22         211 my $vml = Excel::Writer::XLSX::Package::VML->new();
308              
309 22         340 $vml->_set_xml_writer(
310             $dir . '/xl/drawings/vmlDrawing' . $index . '.vml' );
311             $vml->_assemble_xml_file(
312             $worksheet->{_vml_header_id},
313             $worksheet->{_vml_header_id} * 1024,
314             undef, undef, $worksheet->{_header_images_array}
315 22         194 );
316              
317 22         912 $self->_write_vml_drawing_rels_file($worksheet, $index);
318              
319 22         1007 $index++;
320             }
321             }
322             }
323              
324              
325             ###############################################################################
326             #
327             # _write_comment_files()
328             #
329             # Write the comment files.
330             #
331             sub _write_comment_files {
332              
333 849     849   1847 my $self = shift;
334 849         2045 my $dir = $self->{_package_dir};
335              
336 849         1702 my $index = 1;
337 849         2120 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         2946  
338 996 100       4045 next unless $worksheet->{_has_comments};
339              
340 43         437 my $comment = Excel::Writer::XLSX::Package::Comments->new();
341              
342 43         186 _mkdir( $dir . '/xl' );
343 43         237 _mkdir( $dir . '/xl/drawings' );
344              
345 43         512 $comment->_set_xml_writer( $dir . '/xl/comments' . $index++ . '.xml' );
346 43         245 $comment->_assemble_xml_file( $worksheet->{_comments_array} );
347             }
348             }
349              
350              
351             ###############################################################################
352             #
353             # _write_shared_strings_file()
354             #
355             # Write the sharedStrings.xml file.
356             #
357             sub _write_shared_strings_file {
358              
359 849     849   1906 my $self = shift;
360 849         2152 my $dir = $self->{_package_dir};
361 849         8844 my $sst = Excel::Writer::XLSX::Package::SharedStrings->new();
362              
363 849         2501 my $total = $self->{_workbook}->{_str_total};
364 849         2146 my $unique = $self->{_workbook}->{_str_unique};
365 849         2293 my $sst_data = $self->{_workbook}->{_str_array};
366              
367 849 100       10083 return unless $total > 0;
368              
369 237         1126 _mkdir( $dir . '/xl' );
370              
371 237         1893 $sst->_set_string_count( $total );
372 237         1128 $sst->_set_unique_count( $unique );
373 237         994 $sst->_add_strings( $sst_data );
374              
375 237         862 $sst->_set_xml_writer( $dir . '/xl/sharedStrings.xml' );
376 237         1583 $sst->_assemble_xml_file();
377             }
378              
379              
380             ###############################################################################
381             #
382             # _write_app_file()
383             #
384             # Write the app.xml file.
385             #
386             sub _write_app_file {
387              
388 849     849   2194 my $self = shift;
389 849         2244 my $dir = $self->{_package_dir};
390 849         2299 my $properties = $self->{_workbook}->{_doc_properties};
391 849         7846 my $app = Excel::Writer::XLSX::Package::App->new();
392              
393 849         4071 _mkdir( $dir . '/docProps' );
394              
395             # Add the Worksheet heading pairs.
396 849         8806 $app->_add_heading_pair( [ 'Worksheets', $self->{_worksheet_count} ] );
397              
398             # Add the Chartsheet heading pairs.
399 849         5126 $app->_add_heading_pair( [ 'Charts', $self->{_chartsheet_count} ] );
400              
401             # Add the Worksheet parts.
402 849         2286 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3829  
403 996 100       4185 next if $worksheet->{_is_chartsheet};
404 976         5383 $app->_add_part_name( $worksheet->get_name() );
405             }
406              
407             # Add the Chartsheet parts.
408 849         2594 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3563  
409 996 100       4189 next unless $worksheet->{_is_chartsheet};
410 20         210 $app->_add_part_name( $worksheet->get_name() );
411             }
412              
413             # Add the Named Range heading pairs.
414 849 100       2438 if ( my $range_count = scalar @{ $self->{_named_ranges} } ) {
  849         4440  
415 18         89 $app->_add_heading_pair( [ 'Named Ranges', $range_count ] );
416             }
417              
418             # Add the Named Ranges parts.
419 849         2409 for my $named_range ( @{ $self->{_named_ranges} } ) {
  849         2679  
420 38         103 $app->_add_part_name( $named_range );
421             }
422              
423 849         4545 $app->_set_properties( $properties );
424              
425 849         3444 $app->_set_xml_writer( $dir . '/docProps/app.xml' );
426 849         4778 $app->_assemble_xml_file();
427             }
428              
429              
430             ###############################################################################
431             #
432             # _write_core_file()
433             #
434             # Write the core.xml file.
435             #
436             sub _write_core_file {
437              
438 849     849   2229 my $self = shift;
439 849         2502 my $dir = $self->{_package_dir};
440 849         3516 my $properties = $self->{_workbook}->{_doc_properties};
441 849         7570 my $core = Excel::Writer::XLSX::Package::Core->new();
442              
443 849         3923 _mkdir( $dir . '/docProps' );
444              
445 849         6359 $core->_set_properties( $properties );
446 849         2938 $core->_set_xml_writer( $dir . '/docProps/core.xml' );
447 849         4551 $core->_assemble_xml_file();
448             }
449              
450              
451             ###############################################################################
452             #
453             # _write_custom_file()
454             #
455             # Write the custom.xml file.
456             #
457             sub _write_custom_file {
458              
459 849     849   2326 my $self = shift;
460 849         2981 my $dir = $self->{_package_dir};
461 849         2802 my $properties = $self->{_workbook}->{_custom_properties};
462 849         8019 my $custom = Excel::Writer::XLSX::Package::Custom->new();
463              
464 849 100       7656 return if !@$properties;
465              
466 4         13 _mkdir( $dir . '/docProps' );
467              
468 4         30 $custom->_set_properties( $properties );
469 4         11 $custom->_set_xml_writer( $dir . '/docProps/custom.xml' );
470 4         20 $custom->_assemble_xml_file();
471             }
472              
473              
474             ###############################################################################
475             #
476             # _write_content_types_file()
477             #
478             # Write the ContentTypes.xml file.
479             #
480             sub _write_content_types_file {
481              
482 849     849   2355 my $self = shift;
483 849         3047 my $dir = $self->{_package_dir};
484 849         7847 my $content = Excel::Writer::XLSX::Package::ContentTypes->new();
485              
486 849         2055 $content->_add_image_types( %{ $self->{_workbook}->{_image_types} } );
  849         6385  
487              
488 849         2062 my $worksheet_index = 1;
489 849         2418 my $chartsheet_index = 1;
490 849         1919 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3836  
491 996 100       4806 if ( $worksheet->{_is_chartsheet} ) {
492 20         106 $content->_add_chartsheet_name( 'sheet' . $chartsheet_index++ );
493             }
494             else {
495 976         6673 $content->_add_worksheet_name( 'sheet' . $worksheet_index++ );
496             }
497             }
498              
499 849         4165 for my $i ( 1 .. $self->{_chart_count} ) {
500 418         2530 $content->_add_chart_name( 'chart' . $i );
501             }
502              
503 849         3496 for my $i ( 1 .. $self->{_drawing_count} ) {
504 503         2910 $content->_add_drawing_name( 'drawing' . $i );
505             }
506              
507 849 100       4122 if ( $self->{_num_vml_files} ) {
508 61         313 $content->_add_vml_name();
509             }
510              
511 849         3506 for my $i ( 1 .. $self->{_table_count} ) {
512 35         194 $content->_add_table_name( 'table' . $i );
513             }
514              
515 849         3230 for my $i ( 1 .. $self->{_num_comment_files} ) {
516 43         245 $content->_add_comment_name( 'comments' . $i );
517             }
518              
519             # Add the sharedString rel if there is string data in the workbook.
520 849 100       4122 if ( $self->{_workbook}->{_str_total} ) {
521 237         1181 $content->_add_shared_strings();
522             }
523              
524             # Add vbaProject if present.
525 849 100       4098 if ( $self->{_workbook}->{_vba_project} ) {
526 6         31 $content->_add_vba_project();
527             }
528              
529             # Add the custom properties if present.
530 849 100       1987 if ( @{ $self->{_workbook}->{_custom_properties} } ) {
  849         3958  
531 4         13 $content->_add_custom_properties();
532             }
533              
534 849         4291 $content->_set_xml_writer( $dir . '/[Content_Types].xml' );
535 849         4559 $content->_assemble_xml_file();
536             }
537              
538              
539             ###############################################################################
540             #
541             # _write_styles_file()
542             #
543             # Write the style xml file.
544             #
545             sub _write_styles_file {
546              
547 849     849   2324 my $self = shift;
548 849         2364 my $dir = $self->{_package_dir};
549 849         2617 my $xf_formats = $self->{_workbook}->{_xf_formats};
550 849         2516 my $palette = $self->{_workbook}->{_palette};
551 849         2040 my $font_count = $self->{_workbook}->{_font_count};
552 849         2018 my $num_format_count = $self->{_workbook}->{_num_format_count};
553 849         2209 my $border_count = $self->{_workbook}->{_border_count};
554 849         2064 my $fill_count = $self->{_workbook}->{_fill_count};
555 849         2070 my $custom_colors = $self->{_workbook}->{_custom_colors};
556 849         1969 my $dxf_formats = $self->{_workbook}->{_dxf_formats};
557 849         1954 my $has_comments = $self->{_workbook}->{_has_comments};
558              
559 849         7514 my $rels = Excel::Writer::XLSX::Package::Styles->new();
560              
561 849         3717 _mkdir( $dir . '/xl' );
562              
563 849         7151 $rels->_set_style_properties(
564             $xf_formats,
565             $palette,
566             $font_count,
567             $num_format_count,
568             $border_count,
569             $fill_count,
570             $custom_colors,
571             $dxf_formats,
572             $has_comments,
573             );
574              
575 849         3208 $rels->_set_xml_writer( $dir . '/xl/styles.xml' );
576 849         5873 $rels->_assemble_xml_file();
577             }
578              
579              
580             ###############################################################################
581             #
582             # _write_theme_file()
583             #
584             # Write the style xml file.
585             #
586             sub _write_theme_file {
587              
588 849     849   2322 my $self = shift;
589 849         2202 my $dir = $self->{_package_dir};
590 849         8391 my $rels = Excel::Writer::XLSX::Package::Theme->new();
591              
592 849         3756 _mkdir( $dir . '/xl' );
593 849         4929 _mkdir( $dir . '/xl/theme' );
594              
595 849         5185 $rels->_set_xml_writer( $dir . '/xl/theme/theme1.xml' );
596 849         4181 $rels->_assemble_xml_file();
597             }
598              
599              
600             ###############################################################################
601             #
602             # _write_table_files()
603             #
604             # Write the table files.
605             #
606             sub _write_table_files {
607              
608 849     849   1911 my $self = shift;
609 849         2031 my $dir = $self->{_package_dir};
610              
611 849         1855 my $index = 1;
612 849         1918 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3012  
613 996         1852 my @table_props = @{ $worksheet->{_tables} };
  996         3070  
614              
615 996 100       4189 next unless @table_props;
616              
617 27         118 _mkdir( $dir . '/xl' );
618 27         152 _mkdir( $dir . '/xl/tables' );
619              
620 27         121 for my $table_props ( @table_props ) {
621              
622 35         348 my $table = Excel::Writer::XLSX::Package::Table->new();
623              
624 35         152 $table->_set_xml_writer(
625             $dir . '/xl/tables/table' . $index++ . '.xml' );
626              
627 35         282 $table->_set_properties( $table_props );
628              
629 35         147 $table->_assemble_xml_file();
630              
631 35         1519 $self->{_table_count}++;
632             }
633             }
634             }
635              
636              
637             ###############################################################################
638             #
639             # _write_root_rels_file()
640             #
641             # Write the _rels/.rels xml file.
642             #
643             sub _write_root_rels_file {
644              
645 849     849   2511 my $self = shift;
646 849         2320 my $dir = $self->{_package_dir};
647 849         8495 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
648              
649 849         3732 _mkdir( $dir . '/_rels' );
650              
651 849         7142 $rels->_add_document_relationship( '/officeDocument', 'xl/workbook.xml' );
652              
653 849         4331 $rels->_add_package_relationship( '/metadata/core-properties',
654             'docProps/core.xml' );
655              
656 849         3607 $rels->_add_document_relationship( '/extended-properties',
657             'docProps/app.xml' );
658              
659 849 100       1517 if ( @{ $self->{_workbook}->{_custom_properties} } ) {
  849         3965  
660 4         39 $rels->_add_document_relationship( '/custom-properties',
661             'docProps/custom.xml' );
662             }
663              
664 849         3647 $rels->_set_xml_writer( $dir . '/_rels/.rels' );
665 849         4490 $rels->_assemble_xml_file();
666             }
667              
668              
669             ###############################################################################
670             #
671             # _write_workbook_rels_file()
672             #
673             # Write the _rels/.rels xml file.
674             #
675             sub _write_workbook_rels_file {
676              
677 849     849   2214 my $self = shift;
678 849         2330 my $dir = $self->{_package_dir};
679 849         5681 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
680              
681 849         3597 _mkdir( $dir . '/xl' );
682 849         4943 _mkdir( $dir . '/xl/_rels' );
683              
684 849         3083 my $worksheet_index = 1;
685 849         1870 my $chartsheet_index = 1;
686              
687 849         1937 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3811  
688 996 100       4243 if ( $worksheet->{_is_chartsheet} ) {
689 20         85 $rels->_add_document_relationship( '/chartsheet',
690             'chartsheets/sheet' . $chartsheet_index++ . '.xml' );
691             }
692             else {
693 976         7033 $rels->_add_document_relationship( '/worksheet',
694             'worksheets/sheet' . $worksheet_index++ . '.xml' );
695             }
696             }
697              
698 849         3942 $rels->_add_document_relationship( '/theme', 'theme/theme1.xml' );
699 849         3564 $rels->_add_document_relationship( '/styles', 'styles.xml' );
700              
701             # Add the sharedString rel if there is string data in the workbook.
702 849 100       3890 if ( $self->{_workbook}->{_str_total} ) {
703 237         766 $rels->_add_document_relationship( '/sharedStrings',
704             'sharedStrings.xml' );
705             }
706              
707             # Add vbaProject if present.
708 849 100       3981 if ( $self->{_workbook}->{_vba_project} ) {
709 6         21 $rels->_add_ms_package_relationship( '/vbaProject', 'vbaProject.bin' );
710             }
711              
712 849         3543 $rels->_set_xml_writer( $dir . '/xl/_rels/workbook.xml.rels' );
713 849         4080 $rels->_assemble_xml_file();
714             }
715              
716              
717             ###############################################################################
718             #
719             # _write_worksheet_rels_files()
720             #
721             # Write the worksheet .rels files for worksheets that contain links to external
722             # data such as hyperlinks or drawings.
723             #
724             sub _write_worksheet_rels_files {
725              
726 849     849   2279 my $self = shift;
727 849         2348 my $dir = $self->{_package_dir};
728              
729 849         2044 my $index = 0;
730 849         1962 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3667  
731              
732 996 100       5843 next if $worksheet->{_is_chartsheet};
733              
734 976         2157 $index++;
735              
736             my @external_links = (
737 976         2635 @{ $worksheet->{_external_hyper_links} },
738 976         2405 @{ $worksheet->{_external_drawing_links} },
739 976         2447 @{ $worksheet->{_external_vml_links} },
740 976         2227 @{ $worksheet->{_external_table_links} },
741 976         1839 @{ $worksheet->{_external_comment_links} },
  976         2950  
742             );
743              
744 976 100       3622 next unless @external_links;
745              
746             # Create the worksheet .rels dirs.
747 618         2621 _mkdir( $dir . '/xl' );
748 618         3456 _mkdir( $dir . '/xl/worksheets' );
749 618         3235 _mkdir( $dir . '/xl/worksheets/_rels' );
750              
751 618         5732 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
752              
753 618         1935 for my $link_data ( @external_links ) {
754 713         2994 $rels->_add_worksheet_relationship( @$link_data );
755             }
756              
757             # Create the .rels file such as /xl/worksheets/_rels/sheet1.xml.rels.
758             $rels->_set_xml_writer(
759 618         2493 $dir . '/xl/worksheets/_rels/sheet' . $index . '.xml.rels' );
760 618         2851 $rels->_assemble_xml_file();
761             }
762             }
763              
764              
765             ###############################################################################
766             #
767             # _write_chartsheet_rels_files()
768             #
769             # Write the chartsheet .rels files for links to drawing files.
770             #
771             sub _write_chartsheet_rels_files {
772              
773 849     849   2118 my $self = shift;
774 849         2304 my $dir = $self->{_package_dir};
775              
776              
777 849         1857 my $index = 0;
778 849         1797 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3347  
779              
780 996 100       4303 next unless $worksheet->{_is_chartsheet};
781              
782 20         43 $index++;
783              
784 20         34 my @external_links = @{ $worksheet->{_external_drawing_links} };
  20         68  
785              
786 20 50       63 next unless @external_links;
787              
788             # Create the chartsheet .rels dir.
789 20         83 _mkdir( $dir . '/xl' );
790 20         113 _mkdir( $dir . '/xl/chartsheets' );
791 20         107 _mkdir( $dir . '/xl/chartsheets/_rels' );
792              
793 20         201 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
794              
795 20         67 for my $link_data ( @external_links ) {
796 20         126 $rels->_add_worksheet_relationship( @$link_data );
797             }
798              
799             # Create the .rels file such as /xl/chartsheets/_rels/sheet1.xml.rels.
800             $rels->_set_xml_writer(
801 20         97 $dir . '/xl/chartsheets/_rels/sheet' . $index . '.xml.rels' );
802 20         89 $rels->_assemble_xml_file();
803             }
804             }
805              
806              
807             ###############################################################################
808             #
809             # _write_drawing_rels_files()
810             #
811             # Write the drawing .rels files for worksheets that contain charts or drawings.
812             #
813             sub _write_drawing_rels_files {
814              
815 849     849   1809 my $self = shift;
816 849         2073 my $dir = $self->{_package_dir};
817              
818              
819 849         1804 my $index = 0;
820 849         1720 for my $worksheet ( @{ $self->{_workbook}->{_worksheets} } ) {
  849         3139  
821              
822 996 100 100     3138 if ( @{ $worksheet->{_drawing_links} } || $worksheet->{_has_shapes} ) {
  996         6147  
823 503         1007 $index++;
824             }
825              
826 996 100       1914 next unless @{ $worksheet->{_drawing_links} };
  996         3638  
827              
828             # Create the drawing .rels dir.
829 493         2101 _mkdir( $dir . '/xl' );
830 493         2737 _mkdir( $dir . '/xl/drawings' );
831 493         2572 _mkdir( $dir . '/xl/drawings/_rels' );
832              
833 493         4582 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
834              
835 493         1108 for my $drawing_data ( @{ $worksheet->{_drawing_links} } ) {
  493         1829  
836 551         2011 $rels->_add_document_relationship( @$drawing_data );
837             }
838              
839             # Create the .rels file such as /xl/drawings/_rels/sheet1.xml.rels.
840             $rels->_set_xml_writer(
841 493         2123 $dir . '/xl/drawings/_rels/drawing' . $index . '.xml.rels' );
842 493         2250 $rels->_assemble_xml_file();
843             }
844             }
845              
846              
847             ###############################################################################
848             #
849             # _write_vml_drawing_rels_files()
850             #
851             # Write the vmlDdrawing .rels files for worksheets with images in header or
852             # footers.
853             #
854             sub _write_vml_drawing_rels_file {
855              
856 22     22   86 my $self = shift;
857 22         44 my $worksheet = shift;
858 22         49 my $index = shift;
859 22         53 my $dir = $self->{_package_dir};
860              
861              
862             # Create the drawing .rels dir.
863 22         99 _mkdir( $dir . '/xl' );
864 22         111 _mkdir( $dir . '/xl/drawings' );
865 22         112 _mkdir( $dir . '/xl/drawings/_rels' );
866              
867 22         249 my $rels = Excel::Writer::XLSX::Package::Relationships->new();
868              
869 22         45 for my $drawing_data ( @{ $worksheet->{_vml_drawing_links} } ) {
  22         75  
870 34         116 $rels->_add_document_relationship( @$drawing_data );
871             }
872              
873             # Create the .rels file such as /xl/drawings/_rels/vmlDrawing1.vml.rels.
874             $rels->_set_xml_writer(
875 22         119 $dir . '/xl/drawings/_rels/vmlDrawing' . $index . '.vml.rels' );
876 22         105 $rels->_assemble_xml_file();
877              
878             }
879              
880              
881             ###############################################################################
882             #
883             # _add_image_files()
884             #
885             # Write the /xl/media/image?.xml files.
886             #
887             sub _add_image_files {
888              
889 849     849   2109 my $self = shift;
890 849         2185 my $dir = $self->{_package_dir};
891 849         2015 my $workbook = $self->{_workbook};
892 849         1818 my $index = 1;
893              
894 849         1766 for my $image ( @{ $workbook->{_images} } ) {
  849         3376  
895 134         10139 my $filename = $image->[0];
896 134         412 my $extension = '.' . $image->[1];
897              
898 134         519 _mkdir( $dir . '/xl' );
899 134         678 _mkdir( $dir . '/xl/media' );
900              
901 134         717 copy( $filename, $dir . '/xl/media/image' . $index++ . $extension );
902             }
903             }
904              
905              
906             ###############################################################################
907             #
908             # _add_vba_project()
909             #
910             # Write the vbaProject.bin file.
911             #
912             sub _add_vba_project {
913              
914 849     849   1840 my $self = shift;
915 849         2070 my $dir = $self->{_package_dir};
916 849         2087 my $vba_project = $self->{_workbook}->{_vba_project};
917              
918 849 100       5002 return unless $vba_project;
919              
920 6         25 _mkdir( $dir . '/xl' );
921              
922 6         30 copy( $vba_project, $dir . '/xl/vbaProject.bin' );
923             }
924              
925              
926             ###############################################################################
927             #
928             # _mkdir()
929             #
930             # Wrapper function for Perl's mkdir to allow error trapping.
931             #
932             sub _mkdir {
933              
934 15333     15333   134128 my $dir = shift;
935              
936 15333 100       251337 return if -e $dir;
937              
938 7190         350443 my $ret = mkdir( $dir );
939              
940 7190 50       36097 if ( !$ret ) {
941 0           croak "Couldn't create sub directory $dir: $!";
942             }
943             }
944              
945              
946             1;
947              
948              
949             __END__