File Coverage

blib/lib/Spreadsheet/WriteExcelXML/Workbook.pm
Criterion Covered Total %
statement 190 292 65.0
branch 34 62 54.8
condition 5 41 12.2
subroutine 26 35 74.2
pod 0 13 0.0
total 255 443 57.5


line stmt bran cond sub pod time code
1             package Spreadsheet::WriteExcelXML::Workbook;
2              
3             ###############################################################################
4             #
5             # Workbook - A writer class for Excel Workbooks.
6             #
7             #
8             # Used in conjunction with Spreadsheet::WriteExcelXML
9             #
10             # Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
11             #
12             # Documentation after __END__
13             #
14              
15 22     22   202 use Exporter;
  22         39  
  22         953  
16 22     22   121 use strict;
  22         37  
  22         845  
17 22     22   120 use Carp;
  22         34  
  22         1967  
18 22     22   25241 use FileHandle;
  22         391359  
  22         144  
19 22     22   42959 use Spreadsheet::WriteExcelXML::XMLwriter;
  22         59  
  22         4590  
20 22     22   39261 use Spreadsheet::WriteExcelXML::Worksheet;
  22         111  
  22         2002  
21 22     22   270 use Spreadsheet::WriteExcelXML::Format;
  22         50  
  22         998  
22              
23              
24              
25 22     22   122 use vars qw($VERSION @ISA);
  22         45  
  22         65206  
26             @ISA = qw(Spreadsheet::WriteExcelXML::XMLwriter Exporter);
27              
28             $VERSION = '0.14';
29              
30             ###############################################################################
31             #
32             # new()
33             #
34             # Constructor. Creates a new Workbook object from a XMLwriter object.
35             #
36             sub new {
37              
38 22     22 0 60 my $class = shift;
39 22         277 my $self = Spreadsheet::WriteExcelXML::XMLwriter->new();
40 22         237 my $tmp_format = Spreadsheet::WriteExcelXML::Format->new();
41 22         292 my $byte_order = $self->{_byte_order};
42              
43              
44 22   50     225 $self->{_filename} = $_[0] || '';
45 22         75 $self->{_1904} = 0;
46 22         66 $self->{_activesheet} = 0;
47 22         58 $self->{_firstsheet} = 0;
48 22         76 $self->{_selected} = 0;
49 22         59 $self->{_xf_index} = 21; # 21 internal styles +1
50 22         52 $self->{_fileclosed} = 0;
51 22         57 $self->{_biffsize} = 0;
52 22         75 $self->{_sheetname} = "Sheet";
53 22         62 $self->{_tmp_format} = $tmp_format;
54 22         58 $self->{_codepage} = 0x04E4;
55 22         86 $self->{_worksheets} = [];
56 22         105 $self->{_sheetnames} = [];
57 22         172 $self->{_formats} = [];
58 22         59 $self->{_palette} = [];
59 22         64 $self->{_lower_cell_limits} = 0;
60              
61 22         69 bless $self, $class;
62              
63              
64             # Check for a filename unless it is an existing filehandle
65 22 50 33     396 if (not ref $self->{_filename} and $self->{_filename} eq '') {
66 0         0 carp 'Filename required by Spreadsheet::WriteExcelXML->new()';
67 0         0 return undef;
68             }
69              
70              
71             # If filename is a reference we assume that it is a valid filehandle.
72 22 50       113 if (ref $self->{_filename}) {
73 0         0 $self->{_filehandle} = $self->{_filename};
74             }
75             else {
76 22         285 my $fh = FileHandle->new('>'. $self->{_filename});
77              
78 22 50       150123 return undef unless defined $fh;
79              
80             # Set the output to utf8 in newer perls.
81 22 50       145 if ($] >= 5.008) {
82 22         2595 eval q(binmode $fh, ':utf8');
83             }
84              
85 22         129 $self->{_filehandle} = $fh;
86             }
87              
88              
89             # Set colour palette.
90 22         129 $self->set_palette_xl97();
91              
92 22         88 return $self;
93             }
94              
95              
96             ###############################################################################
97             #
98             # close()
99             #
100             # Calls finalization methods.
101             #
102             sub close {
103              
104 26     26 0 1518 my $self = shift;
105              
106             # In case close() is called twice, by user and by DESTROY.
107 26 50       146 return if $self->{_fileclosed};
108              
109             # Test filehandle in case new() failed and the user didn't check.
110 26 100       1899 return unless defined $self->{_filehandle};
111              
112 18         57 $self->{_fileclosed} = 1;
113 18         195 $self->_store_workbook();
114              
115 18         1904 return close $self->{_filehandle};
116             }
117              
118              
119             ###############################################################################
120             #
121             # DESTROY()
122             #
123             # Close the workbook if it hasn't already been explicitly closed.
124             #
125             sub DESTROY {
126              
127 22     22   151859 my $self = shift;
128              
129 22 100       12014 $self->close() if not $self->{_fileclosed};
130             }
131              
132              
133             ###############################################################################
134             #
135             # sheets(slice,...)
136             #
137             # An accessor for the _worksheets[] array
138             #
139             # Returns: an optionally sliced list of the worksheet objects in a workbook.
140             #
141             sub sheets {
142              
143 4     4 0 11 my $self = shift;
144              
145 4 50       17 if (@_) {
146             # Return a slice of the array
147 0         0 return @{$self->{_worksheets}}[@_];
  0         0  
148             }
149             else {
150             # Return the entire list
151 4         20 return @{$self->{_worksheets}};
  4         61  
152             }
153             }
154              
155              
156             ###############################################################################
157             #
158             # worksheets()
159             #
160             # An accessor for the _worksheets[] array.
161             # This method is now deprecated. Use the sheets() method instead.
162             #
163             # Returns: an array reference
164             #
165             sub worksheets {
166              
167 0     0 0 0 my $self = shift;
168              
169 0         0 return $self->{_worksheets};
170             }
171              
172              
173             ###############################################################################
174             #
175             # add_worksheet($name)
176             #
177             # Add a new worksheet to the Excel workbook.
178             #
179             # Returns: reference to a worksheet object
180             #
181             sub add_worksheet {
182              
183 77     77 0 594 my $self = shift;
184 77   100     351 my $name = $_[0] || "";
185              
186             # Check that sheetname is <= 31 chars (Excel limit).
187 77 50       267 croak "Sheetname $name must be <= 31 chars" if length $name > 31;
188              
189             # Check that sheetname doesn't contain any invalid characters
190 77 50       215 croak 'Invalid Excel character [:*?/\\] in worksheet name: ' . $name
191             if $name =~ m{[:*?/\\]};
192              
193 77         100 my $index = @{$self->{_worksheets}};
  77         3703  
194 77         321 my $sheetname = $self->{_sheetname};
195              
196 77 100       203 if ($name eq "" ) { $name = $sheetname . ($index+1) }
  52         489  
197              
198             # Check that the worksheet name doesn't already exist: a fatal Excel error.
199             # The check must also exclude case insensitive matches.
200 77         121 foreach my $tmp (@{$self->{_worksheets}}) {
  77         853  
201 636 50       1560 if (lc $name eq lc $tmp->get_name()) {
202 0         0 croak "Worksheet name '$name', with case ignored, " .
203             "is already in use";
204             }
205             }
206              
207              
208             # Porters take note, the following scheme of passing references to Workbook
209             # data (in the \$self->{_foo} cases) instead of a reference to the Workbook
210             # itself is a workaround to avoid circular references between Workbook and
211             # Worksheet objects. Feel free to implement this in any way the suits your
212             # language.
213             #
214 77         663 my @init_data = (
215             $name,
216             $index,
217             $self->{_filehandle},
218             $self->{_indentation},
219             \$self->{_activesheet},
220             \$self->{_firstsheet},
221             $self->{_1904},
222             $self->{_lower_cell_limits},
223             );
224              
225 77         853 my $worksheet = Spreadsheet::WriteExcelXML::Worksheet->new(@init_data);
226 77         203 $self->{_worksheets}->[$index] = $worksheet; # Store ref for iterator
227 77         155 $self->{_sheetnames}->[$index] = $name; # Store EXTERNSHEET names
228 77         281 return $worksheet;
229             }
230              
231              
232             ###############################################################################
233             #
234             # add_format(%properties)
235             #
236             # Add a new format to the Excel workbook. This adds an XF record and
237             # a FONT record. Also, pass any properties to the Format::new().
238             #
239             sub add_format {
240              
241 215     215 0 125998 my $self = shift;
242              
243 215         718 my @init_data = (
244             $self->{_xf_index},
245             \$self->{_palette},
246             @_,
247             );
248              
249              
250              
251 215         993 my $format = Spreadsheet::WriteExcelXML::Format->new(@init_data);
252              
253 215         458 $self->{_xf_index} += 1;
254 215         281 push @{$self->{_formats}}, $format; # Store format reference
  215         452  
255              
256 215         620 return $format;
257             }
258              
259              
260             ###############################################################################
261             #
262             # set_1904()
263             #
264             # Set the date system: 0 = 1900 (the default), 1 = 1904
265             #
266             sub set_1904 {
267              
268 0     0 0 0 my $self = shift;
269              
270 0 0       0 if (defined($_[0])) {
271 0         0 $self->{_1904} = $_[0];
272             }
273             else {
274 0         0 $self->{_1904} = 1;
275             }
276             }
277              
278              
279             ###############################################################################
280             #
281             # get_1904()
282             #
283             # Return the date system: 0 = 1900, 1 = 1904
284             #
285             sub get_1904 {
286              
287 0     0 0 0 my $self = shift;
288              
289 0         0 return $self->{_1904};
290             }
291              
292              
293             ###############################################################################
294             #
295             # set_custom_color()
296             #
297             # Change the RGB components of the elements in the colour palette.
298             #
299             sub set_custom_color {
300              
301 0     0 0 0 my $self = shift;
302              
303              
304             # Match a HTML #xxyyzz style parameter
305 0 0 0     0 if (defined $_[1] and $_[1] =~ /^#(\w\w)(\w\w)(\w\w)/ ) {
306 0         0 @_ = ($_[0], hex $1, hex $2, hex $3);
307             }
308              
309              
310 0   0     0 my $index = $_[0] || 0;
311 0   0     0 my $red = $_[1] || 0;
312 0   0     0 my $green = $_[2] || 0;
313 0   0     0 my $blue = $_[3] || 0;
314              
315 0         0 my $aref = $self->{_palette};
316              
317             # Check that the colour index is the right range
318 0 0 0     0 if ($index < 8 or $index > 64) {
319 0         0 carp "Color index $index outside range: 8 <= index <= 64";
320 0         0 return 0;
321             }
322              
323             # Check that the colour components are in the right range
324 0 0 0     0 if ( ($red < 0 or $red > 255) ||
      0        
      0        
      0        
      0        
325             ($green < 0 or $green > 255) ||
326             ($blue < 0 or $blue > 255) )
327             {
328 0         0 carp "Color component outside range: 0 <= color <= 255";
329 0         0 return 0;
330             }
331              
332 0         0 $index -=8; # Adjust colour index (wingless dragonfly)
333              
334             # Set the RGB value
335 0         0 $aref->[$index] = [$red, $green, $blue, 0];
336              
337 0         0 return $index +8;
338             }
339              
340              
341             ###############################################################################
342             #
343             # set_palette_xl97()
344             #
345             # Sets the colour palette to the Excel 97+ default.
346             #
347             sub set_palette_xl97 {
348              
349 22     22 0 59 my $self = shift;
350              
351 22         1270 $self->{_palette} = [
352             [0x00, 0x00, 0x00, 0x00], # 8
353             [0xff, 0xff, 0xff, 0x00], # 9
354             [0xff, 0x00, 0x00, 0x00], # 10
355             [0x00, 0xff, 0x00, 0x00], # 11
356             [0x00, 0x00, 0xff, 0x00], # 12
357             [0xff, 0xff, 0x00, 0x00], # 13
358             [0xff, 0x00, 0xff, 0x00], # 14
359             [0x00, 0xff, 0xff, 0x00], # 15
360             [0x80, 0x00, 0x00, 0x00], # 16
361             [0x00, 0x80, 0x00, 0x00], # 17
362             [0x00, 0x00, 0x80, 0x00], # 18
363             [0x80, 0x80, 0x00, 0x00], # 19
364             [0x80, 0x00, 0x80, 0x00], # 20
365             [0x00, 0x80, 0x80, 0x00], # 21
366             [0xc0, 0xc0, 0xc0, 0x00], # 22
367             [0x80, 0x80, 0x80, 0x00], # 23
368             [0x99, 0x99, 0xff, 0x00], # 24
369             [0x99, 0x33, 0x66, 0x00], # 25
370             [0xff, 0xff, 0xcc, 0x00], # 26
371             [0xcc, 0xff, 0xff, 0x00], # 27
372             [0x66, 0x00, 0x66, 0x00], # 28
373             [0xff, 0x80, 0x80, 0x00], # 29
374             [0x00, 0x66, 0xcc, 0x00], # 30
375             [0xcc, 0xcc, 0xff, 0x00], # 31
376             [0x00, 0x00, 0x80, 0x00], # 32
377             [0xff, 0x00, 0xff, 0x00], # 33
378             [0xff, 0xff, 0x00, 0x00], # 34
379             [0x00, 0xff, 0xff, 0x00], # 35
380             [0x80, 0x00, 0x80, 0x00], # 36
381             [0x80, 0x00, 0x00, 0x00], # 37
382             [0x00, 0x80, 0x80, 0x00], # 38
383             [0x00, 0x00, 0xff, 0x00], # 39
384             [0x00, 0xcc, 0xff, 0x00], # 40
385             [0xcc, 0xff, 0xff, 0x00], # 41
386             [0xcc, 0xff, 0xcc, 0x00], # 42
387             [0xff, 0xff, 0x99, 0x00], # 43
388             [0x99, 0xcc, 0xff, 0x00], # 44
389             [0xff, 0x99, 0xcc, 0x00], # 45
390             [0xcc, 0x99, 0xff, 0x00], # 46
391             [0xff, 0xcc, 0x99, 0x00], # 47
392             [0x33, 0x66, 0xff, 0x00], # 48
393             [0x33, 0xcc, 0xcc, 0x00], # 49
394             [0x99, 0xcc, 0x00, 0x00], # 50
395             [0xff, 0xcc, 0x00, 0x00], # 51
396             [0xff, 0x99, 0x00, 0x00], # 52
397             [0xff, 0x66, 0x00, 0x00], # 53
398             [0x66, 0x66, 0x99, 0x00], # 54
399             [0x96, 0x96, 0x96, 0x00], # 55
400             [0x00, 0x33, 0x66, 0x00], # 56
401             [0x33, 0x99, 0x66, 0x00], # 57
402             [0x00, 0x33, 0x00, 0x00], # 58
403             [0x33, 0x33, 0x00, 0x00], # 59
404             [0x99, 0x33, 0x00, 0x00], # 60
405             [0x99, 0x33, 0x66, 0x00], # 61
406             [0x33, 0x33, 0x99, 0x00], # 62
407             [0x33, 0x33, 0x33, 0x00], # 63
408             ];
409              
410 22         100 return 0;
411             }
412              
413              
414              
415             ###############################################################################
416             #
417             # set_tempdir()
418             #
419             # Change the default temp directory used by _initialize() in Worksheet.pm.
420             #
421             sub set_tempdir {
422              
423 0     0 0 0 my $self = shift;
424              
425             # TODO Update for ExcelXML format
426             }
427              
428              
429             ###############################################################################
430             #
431             # set_codepage()
432             #
433             # See also the _store_codepage method. This is used to store the code page, i.e.
434             # the character set used in the workbook.
435             #
436             sub set_codepage {
437              
438 0     0 0 0 my $self = shift;
439 0   0     0 my $codepage = $_[0] || 1;
440 0 0       0 $codepage = 0x04E4 if $codepage == 1;
441 0 0       0 $codepage = 0x8000 if $codepage == 2;
442 0         0 $self->{_codepage} = $codepage;
443             }
444              
445              
446             ###############################################################################
447             #
448             # use_lower_cell_limits()
449             #
450             # TODO
451             #
452             sub use_lower_cell_limits {
453              
454 4     4 0 46 my $self = shift;
455              
456 4 50       31 croak "use_lower_cell_limits() must be called before add_worksheet()"
457             if $self->sheets();
458              
459 4         15 $self->{_lower_cell_limits} = 1;
460             }
461              
462              
463             ###############################################################################
464             #
465             # _store_workbook()
466             #
467             # Assemble worksheets into a workbook and send the BIFF data to an OLE
468             # storage.
469             #
470             sub _store_workbook {
471              
472 18     18   40 my $self = shift;
473              
474              
475             # Write the XML version.
476 18         216 $self->_write_xml_directive(0, 1, 0, 'xml', 'version', '1.0');
477              
478             # Write the XML directive to make Windows open the file in Excel.
479 18         88 $self->_write_xml_directive(0, 1, 0, 'mso-application',
480             'progid', 'Excel.Sheet');
481              
482             # Write the XML namespaces.
483 18         188 $self->_write_xml_start_tag(0, 1, 1,
484             'Workbook',
485             'xmlns:x',
486             'urn:schemas-microsoft-com:office:excel',
487             'xmlns',
488             'urn:schemas-microsoft-com:office:spreadsheet',
489             'xmlns:ss',
490             'urn:schemas-microsoft-com:office:spreadsheet',
491             );
492              
493              
494              
495 18         138 $self->_store_all_xfs();
496              
497              
498              
499              
500             # Ensure that at least one worksheet has been selected.
501 18 50       79 if ($self->{_activesheet} == 0) {
502 18         44 @{$self->{_worksheets}}[0]->{_selected} = 1;
  18         115  
503             }
504              
505             # Calculate the number of selected worksheet tabs and call the finalization
506             # methods for each worksheet
507 18         44 foreach my $sheet (@{$self->{_worksheets}}) {
  18         56  
508 73 100       253 $self->{_selected}++ if $sheet->{_selected};
509 73         278 $sheet->_close($self->{_sheetnames});
510             }
511              
512             # Add Workbook globals
513 18         273 $self->_store_codepage();
514 18         155 $self->_store_externs(); # For print area and repeat rows
515 18         175 $self->_store_names(); # For print area and repeat rows
516 18         146 $self->_store_window1();
517 18         155 $self->_store_1904();
518 18         159 $self->_store_palette();
519              
520              
521             # Close Workbook tag. WriteExcel _store_eof().
522 18         98 $self->_write_xml_end_tag(0, 1, 1, 'Workbook');
523              
524              
525             # Close the file
526             #$self->{_filehandle}->close(); TODO
527             }
528              
529              
530             ###############################################################################
531             #
532             # _store_all_xfs()
533             #
534             # Write all XF records.
535             #
536             sub _store_all_xfs {
537              
538 18     18   43 my $self = shift;
539 18         35 my @attribs;
540              
541 18         130 $self->_write_xml_start_tag(1, 1, 0, 'Styles');
542              
543             # User defined XFs
544 18         36 foreach my $format (@{$self->{_formats}}) {
  18         69  
545              
546 22         83 $self->_write_xml_start_tag(2, 1, 0,
547             'Style',
548             'ss:ID',
549             's' . $format->get_xf_index());
550              
551              
552             # Write the properties if any
553 22 100       93 if (@attribs = $format->get_align_properties()) {
554 2         38 $self->_write_xml_element(3, 1, 1, 'Alignment', @attribs);
555             }
556              
557              
558             # Write the properties if any
559 22 100       92 if (@attribs = $format->get_border_properties()) {
560 2         10 $self->_write_xml_start_tag(3, 1, 1, 'Borders');
561              
562 2         4 for my $aref (@attribs) {
563 8         34 $self->_write_xml_element(4, 1, 0, 'Border', @$aref);
564             }
565              
566 2         21 $self->_write_xml_end_tag(3, 1, 1, 'Borders');
567             }
568              
569              
570             # Write the properties if any
571 22 100       87 if (@attribs = $format->get_font_properties()) {
572 17         127 $self->_write_xml_element(3, 1, 1, 'Font', @attribs);
573             }
574              
575              
576             # Write the properties if any
577 22 100       85 if (@attribs = $format->get_interior_properties()) {
578 1         3 $self->_write_xml_element(3, 1, 0, 'Interior', @attribs);
579             }
580              
581              
582             # Write the properties if any
583 22 100       99 if (@attribs = $format->get_num_format_properties()) {
584 3         17 $self->_write_xml_element(3, 1, 0, 'NumberFormat',@attribs);
585             }
586              
587              
588             # Write the properties if any
589 22 50       90 if (@attribs = $format->get_protection_properties()) {
590 0         0 $self->_write_xml_element(3, 1, 0, 'Protection', @attribs);
591             }
592              
593              
594              
595 22         123 $self->_write_xml_end_tag(2, 1, 0, 'Style');
596              
597             }
598              
599 18         123 $self->_write_xml_end_tag(1, 1, 0, 'Styles');
600              
601             }
602              
603              
604             ###############################################################################
605             #
606             # _store_externs()
607             #
608             # Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for
609             # the NAME records.
610             #
611             sub _store_externs {
612              
613 18     18   41 my $self = shift;
614              
615             # Create EXTERNCOUNT with number of worksheets
616 18         32 $self->_store_externcount(scalar @{$self->{_worksheets}});
  18         213  
617              
618             # Create EXTERNSHEET for each worksheet
619 18         39 foreach my $sheetname (@{$self->{_sheetnames}}) {
  18         70  
620 73         369 $self->_store_externsheet($sheetname);
621             }
622             }
623              
624              
625             ###############################################################################
626             #
627             # _store_names()
628             #
629             # Write the NAME record to define the print area and the repeat rows and cols.
630             #
631             sub _store_names {
632              
633 18     18   42 my $self = shift;
634              
635             # Create the print area NAME records
636 18         40 foreach my $worksheet (@{$self->{_worksheets}}) {
  18         68  
637             # Write a Name record if the print area has been defined
638 73 50       231 if (defined $worksheet->{_print_rowmin}) {
639 0         0 $self->_store_name_short(
640             $worksheet->{_index},
641             0x06, # NAME type
642             $worksheet->{_print_rowmin},
643             $worksheet->{_print_rowmax},
644             $worksheet->{_print_colmin},
645             $worksheet->{_print_colmax}
646             );
647             }
648             }
649              
650              
651             # Create the print title NAME records
652 18         51 foreach my $worksheet (@{$self->{_worksheets}}) {
  18         60  
653              
654 73         119 my $rowmin = $worksheet->{_title_rowmin};
655 73         99 my $rowmax = $worksheet->{_title_rowmax};
656 73         101 my $colmin = $worksheet->{_title_colmin};
657 73         96 my $colmax = $worksheet->{_title_colmax};
658              
659             # Determine if row + col, row, col or nothing has been defined
660             # and write the appropriate record
661             #
662 73 50 33     426 if (defined $rowmin && defined $colmin) {
    50          
    50          
663             # Row and column titles have been defined.
664             # Row title has been defined.
665 0         0 $self->_store_name_long(
666             $worksheet->{_index},
667             0x07, # NAME type
668             $rowmin,
669             $rowmax,
670             $colmin,
671             $colmax
672             );
673             }
674             elsif (defined $rowmin) {
675             # Row title has been defined.
676 0         0 $self->_store_name_short(
677             $worksheet->{_index},
678             0x07, # NAME type
679             $rowmin,
680             $rowmax,
681             0x00,
682             0xff
683             );
684             }
685             elsif (defined $colmin) {
686             # Column title has been defined.
687 0         0 $self->_store_name_short(
688             $worksheet->{_index},
689             0x07, # NAME type
690             0x0000,
691             0x3fff,
692             $colmin,
693             $colmax
694             );
695             }
696             else {
697             # Print title hasn't been defined.
698             }
699             }
700             }
701              
702              
703              
704              
705             ###############################################################################
706             ###############################################################################
707             #
708             # BIFF RECORDS
709             #
710              
711              
712             ###############################################################################
713             #
714             # _store_window1()
715             #
716             # Write Excel BIFF WINDOW1 record.
717             #
718             sub _store_window1 {
719              
720 18     18   37 my $self = shift;
721              
722 18         42 my $record = 0x003D; # Record identifier
723 18         54 my $length = 0x0012; # Number of bytes to follow
724              
725 18         40 my $xWn = 0x0000; # Horizontal position of window
726 18         36 my $yWn = 0x0000; # Vertical position of window
727 18         39 my $dxWn = 0x25BC; # Width of window
728 18         45 my $dyWn = 0x1572; # Height of window
729              
730 18         35 my $grbit = 0x0038; # Option flags
731 18         54 my $ctabsel = $self->{_selected}; # Number of workbook tabs selected
732 18         30 my $wTabRatio = 0x0258; # Tab to scrollbar ratio
733              
734 18         40 my $itabFirst = $self->{_firstsheet}; # 1st displayed worksheet
735 18         215 my $itabCur = $self->{_activesheet}; # Active worksheet
736              
737             # TODO Update for ExcelXML format
738             }
739              
740              
741             ###############################################################################
742             #
743             # _store_style()
744             #
745             # Write Excel BIFF STYLE records.
746             #
747             sub _store_style {
748              
749 0     0   0 my $self = shift;
750              
751 0         0 my $record = 0x0293; # Record identifier
752 0         0 my $length = 0x0004; # Bytes to follow
753              
754 0         0 my $ixfe = 0x8000; # Index to style XF
755 0         0 my $BuiltIn = 0x00; # Built-in style
756 0         0 my $iLevel = 0xff; # Outline style level
757              
758             # TODO Update for ExcelXML format
759             }
760              
761              
762             ###############################################################################
763             #
764             # _store_1904()
765             #
766             # Write Excel 1904 record to indicate the date system in use.
767             #
768             sub _store_1904 {
769              
770 18     18   57 my $self = shift;
771              
772 18         54 my $record = 0x0022; # Record identifier
773 18         39 my $length = 0x0002; # Bytes to follow
774              
775 18         53 my $f1904 = $self->{_1904}; # Flag for 1904 date system
776              
777             # TODO Update for ExcelXML format
778             }
779              
780              
781             ###############################################################################
782             #
783             # _store_externcount($count)
784             #
785             # Write BIFF record EXTERNCOUNT to indicate the number of external sheet
786             # references in the workbook.
787             #
788             # Excel only stores references to external sheets that are used in NAME.
789             # The workbook NAME record is required to define the print area and the repeat
790             # rows and columns.
791             #
792             # A similar method is used in Worksheet.pm for a slightly different purpose.
793             #
794             sub _store_externcount {
795              
796 18     18   41 my $self = shift;
797              
798 18         48 my $record = 0x0016; # Record identifier
799 18         48 my $length = 0x0002; # Number of bytes to follow
800              
801 18         55 my $cxals = $_[0]; # Number of external references
802              
803             # TODO Update for ExcelXML format
804             }
805              
806              
807             ###############################################################################
808             #
809             # _store_externsheet($sheetname)
810             #
811             #
812             # Writes the Excel BIFF EXTERNSHEET record. These references are used by
813             # formulas. NAME record is required to define the print area and the repeat
814             # rows and columns.
815             #
816             # A similar method is used in Worksheet.pm for a slightly different purpose.
817             #
818             sub _store_externsheet {
819              
820 73     73   108 my $self = shift;
821              
822 73         224 my $record = 0x0017; # Record identifier
823 73         126 my $length = 0x02 + length($_[0]); # Number of bytes to follow
824              
825 73         91 my $sheetname = $_[0]; # Worksheet name
826 73         90 my $cch = length($sheetname); # Length of sheet name
827 73         172 my $rgch = 0x03; # Filename encoding
828              
829             # TODO Update for ExcelXML format
830             }
831              
832              
833             ###############################################################################
834             #
835             # _store_name_short()
836             #
837             #
838             # Store the NAME record in the short format that is used for storing the print
839             # area, repeat rows only and repeat columns only.
840             #
841             sub _store_name_short {
842              
843 0     0   0 my $self = shift;
844              
845 0         0 my $record = 0x0018; # Record identifier
846 0         0 my $length = 0x0024; # Number of bytes to follow
847              
848 0         0 my $index = shift; # Sheet index
849 0         0 my $type = shift;
850              
851 0         0 my $grbit = 0x0020; # Option flags
852 0         0 my $chKey = 0x00; # Keyboard shortcut
853 0         0 my $cch = 0x01; # Length of text name
854 0         0 my $cce = 0x0015; # Length of text definition
855 0         0 my $ixals = $index +1; # Sheet index
856 0         0 my $itab = $ixals; # Equal to ixals
857 0         0 my $cchCustMenu = 0x00; # Length of cust menu text
858 0         0 my $cchDescription = 0x00; # Length of description text
859 0         0 my $cchHelptopic = 0x00; # Length of help topic text
860 0         0 my $cchStatustext = 0x00; # Length of status bar text
861 0         0 my $rgch = $type; # Built-in name type
862              
863 0         0 my $unknown03 = 0x3b;
864 0         0 my $unknown04 = 0xffff-$index;
865 0         0 my $unknown05 = 0x0000;
866 0         0 my $unknown06 = 0x0000;
867 0         0 my $unknown07 = 0x1087;
868 0         0 my $unknown08 = 0x8005;
869              
870 0         0 my $rowmin = $_[0]; # Start row
871 0         0 my $rowmax = $_[1]; # End row
872 0         0 my $colmin = $_[2]; # Start column
873 0         0 my $colmax = $_[3]; # end column
874              
875              
876             # TODO Update for ExcelXML format
877             }
878              
879              
880             ###############################################################################
881             #
882             # _store_name_long()
883             #
884             #
885             # Store the NAME record in the long format that is used for storing the repeat
886             # rows and columns when both are specified. This share a lot of code with
887             # _store_name_short() but we use a separate method to keep the code clean.
888             # Code abstraction for reuse can be carried too far, and I should know. ;-)
889             #
890             sub _store_name_long {
891              
892 0     0   0 my $self = shift;
893              
894 0         0 my $record = 0x0018; # Record identifier
895 0         0 my $length = 0x003d; # Number of bytes to follow
896              
897 0         0 my $index = shift; # Sheet index
898 0         0 my $type = shift;
899              
900 0         0 my $grbit = 0x0020; # Option flags
901 0         0 my $chKey = 0x00; # Keyboard shortcut
902 0         0 my $cch = 0x01; # Length of text name
903 0         0 my $cce = 0x002e; # Length of text definition
904 0         0 my $ixals = $index +1; # Sheet index
905 0         0 my $itab = $ixals; # Equal to ixals
906 0         0 my $cchCustMenu = 0x00; # Length of cust menu text
907 0         0 my $cchDescription = 0x00; # Length of description text
908 0         0 my $cchHelptopic = 0x00; # Length of help topic text
909 0         0 my $cchStatustext = 0x00; # Length of status bar text
910 0         0 my $rgch = $type; # Built-in name type
911              
912 0         0 my $unknown01 = 0x29;
913 0         0 my $unknown02 = 0x002b;
914 0         0 my $unknown03 = 0x3b;
915 0         0 my $unknown04 = 0xffff-$index;
916 0         0 my $unknown05 = 0x0000;
917 0         0 my $unknown06 = 0x0000;
918 0         0 my $unknown07 = 0x1087;
919 0         0 my $unknown08 = 0x8008;
920              
921 0         0 my $rowmin = $_[0]; # Start row
922 0         0 my $rowmax = $_[1]; # End row
923 0         0 my $colmin = $_[2]; # Start column
924 0         0 my $colmax = $_[3]; # end column
925              
926              
927             # TODO Update for ExcelXML format
928             }
929              
930              
931             ###############################################################################
932             #
933             # _store_palette()
934             #
935             # Stores the PALETTE biff record.
936             #
937             sub _store_palette {
938              
939 18     18   41 my $self = shift;
940              
941 18         229 my $aref = $self->{_palette};
942              
943 18         42 my $record = 0x0092; # Record identifier
944 18         57 my $length = 2 + 4 * @$aref; # Number of bytes to follow
945 18         44 my $ccv = @$aref; # Number of RGB values to follow
946 18         38 my $data; # The RGB data
947              
948             # TODO Update for ExcelXML format
949             }
950              
951              
952             ###############################################################################
953             #
954             # _store_codepage()
955             #
956             # Stores the CODEPAGE biff record.
957             #
958             sub _store_codepage {
959              
960 18     18   64 my $self = shift;
961              
962 18         45 my $record = 0x0042; # Record identifier
963 18         38 my $length = 0x0002; # Number of bytes to follow
964 18         78 my $cv = $self->{_codepage}; # The code page
965              
966             # TODO Update for ExcelXML format
967             }
968              
969              
970             1;
971              
972              
973             __END__