File Coverage

blib/lib/Spreadsheet/WriteExcel/Simple/Tabs.pm
Criterion Covered Total %
statement 82 90 91.1
branch 18 26 69.2
condition 2 5 40.0
subroutine 14 17 82.3
pod 8 8 100.0
total 124 146 84.9


line stmt bran cond sub pod time code
1             package Spreadsheet::WriteExcel::Simple::Tabs;
2 1     1   97318 use strict;
  1         2  
  1         27  
3 1     1   3 use warnings;
  1         5  
  1         38  
4 1     1   1255 use IO::Scalar qw{};
  1         11639  
  1         20  
5 1     1   1606 use Spreadsheet::WriteExcel qw{};
  1         88779  
  1         1734  
6              
7             our $VERSION='0.11';
8             our $PACKAGE=__PACKAGE__;
9              
10             =head1 NAME
11              
12             Spreadsheet::WriteExcel::Simple::Tabs - Simple Interface to the Spreadsheet::WriteExcel Package
13              
14             =head1 SYNOPSIS
15              
16             use Spreadsheet::WriteExcel::Simple::Tabs;
17             my $ss=Spreadsheet::WriteExcel::Simple::Tabs->new;
18             my @data=(
19             ["Heading1", "Heading2"],
20             ["data1", "data2" ],
21             ["data3", "data4" ],
22             );
23             $ss->add(Tab1=>\@data, Tab2=>\@data);
24             print $ss->header(filename=>"filename.xls"), $ss->content;
25              
26             =head1 DESCRIPTION
27              
28             This is a simple wrapper around Spreadsheet::WriteExcel that creates tabs for data. It is meant to be simple not full featured. I use this package to export data from the L sqlarrayarrayname method which is an array of array references where the first array is the column headings.
29              
30             =head1 CONSTRUCTOR
31              
32             =head2 new
33              
34             =cut
35              
36             sub new {
37 1     1 1 174857 my $this = shift();
38 1   33     6 my $class = ref($this) || $this;
39 1         2 my $self = {};
40 1         2 bless $self, $class;
41 1         5 $self->initialize(@_);
42 1         2 return $self;
43             }
44              
45             =head2 initialize
46              
47             =cut
48              
49             sub initialize {
50 1     1 1 2 my $self=shift;
51 1         5 %$self=@_;
52             }
53              
54             =head2 book
55              
56             Returns the workbook object
57              
58             =cut
59              
60             sub book {
61 20     20 1 510 my $self=shift;
62             #Thanks to Tony Bowden for the IO::Scalar stuff
63 20 100       41 unless (defined($self->{"book"})) {
64             $self->{"book"}=Spreadsheet::WriteExcel->new(
65 1         17 IO::Scalar->new_tie(\($self->{"content"}))
66             );
67             }
68 20         1901 return $self->{"book"};
69             }
70              
71             =head2 add
72              
73             $ss->add("Tab Name", \@data);
74             $ss->add(Tab1=>\@data, Tab2=>\@data);
75              
76             =cut
77              
78             sub add {
79 1     1 1 598 my $self=shift;
80 1 50       4 die("Error: The $PACKAGE->add method requires an even number of arguments")
81             if scalar(@_) % 2;
82 1         4 while (@_ > 0) {
83 4         5 my $tab=shift;
84 4         4 my $data=shift;
85 4 50       11 die(sprintf(qq{Error: Expecting data to be an array reference but got "%s" in $PACKAGE->add}, ref($data)))
86             unless ref($data) eq "ARRAY";
87 4         8 $self->_add1($tab=>$data);
88             }
89 1         3 return $self;
90             }
91              
92             sub _add1 {
93 4     4   7 my $self=shift;
94 4         3 my $tab=shift;
95 4         9 $tab=~s/[\[\]:\*\?\/\\]/ /g; #Invalid character []:*?/\ in worksheet name
96 4 50       9 $tab=substr($tab,0,31) if length($tab) > 31; #must be <= 31 chars
97 4         4 my $data=shift;
98 4         7 my $sheet=$self->book->add_worksheet($tab);
99 4         1787 my %format=$self->default; $format{"num_format"}='mm/dd/yyyy hh:mm:ss';
  4         13  
100 4         8 my $format_datetime=$self->book->add_format(%format);
101             my $subref=sub {
102 0     0   0 my $sheet=shift;
103 0         0 my @args=@_;
104 0         0 my ($m,$d,$y,$h,$n,$s)=split(/[\/ :]/, $args[2]);
105 0         0 $args[2]=sprintf("%4d-%02d-%02dT%02d:%02d:%02d", $y, $m, $d, $h, $n, $s);
106 0         0 $args[3]=$format_datetime;
107 0         0 return $sheet->write_date_time(@args);
108 4         704 };
109 4     0   26 $sheet->add_write_handler(qr/^\d{16,}$/, sub{shift->write_string(@_)}); #Long Integer Support - RT61869
  0         0  
110 4     0   47 $sheet->add_write_handler(qr/^0\d+$/, sub{shift->write_string(@_)}); #Leading Zero Support
  0         0  
111 4         36 $sheet->add_write_handler(qr{^\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}$}, $subref); #DateTime Support
112 4         26 $self->_add_data($sheet, $data);
113 4         9 $sheet->freeze_panes(1, 0);
114 4         40 return $sheet;
115             }
116              
117             sub _add_data {
118 4     4   4 my $self=shift;
119 4         6 my $worksheet=shift;
120 4         4 my $data=shift;
121 4         5 my $header=shift(@$data);
122 4         9 $worksheet->write_col(0,0,[$header], $self->book->add_format($self->default, $self->first));
123 4         1539 $worksheet->write_col(1,0, $data, $self->book->add_format($self->default));
124              
125 4         1778 unshift @$data, $header; #put the data back together it is a reference!
126              
127             #Auto resize columns
128 4         10 foreach my $col (0 .. scalar(@$header) - 1) {
129 7   50     76 my $width=(sort {$a<=>$b} map {length($_->[$col]||'')} @$data)[-1];
  21         28  
  21         61  
130 7 50       15 $width = 8 if $width < 8;
131 7         15 $worksheet->set_column($col, $col, $width);
132             }
133 4         94 return $self;
134             }
135              
136             =head2 header
137              
138             Returns a header appropriate for a web application
139              
140             Content-type: application/vnd.ms-excel
141             Content-Disposition: attachment; filename=filename.xls
142              
143             $ss->header #embedded in browser
144             $ss->header(filename=>"filename.xls") #download prompt
145             $ss->header(content_type=>"application/vnd.ms-excel") #default content type
146              
147             =cut
148              
149             sub header {
150 4     4 1 2570 my $self=shift;
151 4         11 my %data=@_;
152             $data{"content_type"}="application/vnd.ms-excel"
153 4 100       14 unless defined $data{"content_type"};
154 4         9 my $header=sprintf("Content-type: %s\n", $data{"content_type"});
155             $header.=sprintf(qq{Content-Disposition: attachment; filename="%s";\n},
156 4 100       10 $data{"filename"}) if defined $data{"filename"};
157 4         12 $header.="\n";
158 4         11 return $header;
159             }
160              
161             =head2 content
162              
163             This returns the binary content of the spreadsheet.
164              
165             print $ss->content;
166              
167             print $ss->header, $ss->content; #CGI Application
168              
169             binmod($fh);
170             print $fh, $ss->content;
171              
172             =cut
173              
174             sub content {
175 1     1 1 3653 my $self=shift;
176 1         3 $self->book->close;
177 1         10400 return $self->{"content"};
178             }
179              
180             =head1 PROPERTIES
181              
182             =head2 first
183              
184             Returns a hash of additional settings for the first row
185              
186             $ss->first({setting=>"value"}); #settings from L
187              
188             =cut
189              
190             sub first {
191 4     4 1 4 my $self=shift;
192 4 50       6 $self->{"first"}=shift if @_;
193             $self->{"first"}={bg_color=>"silver", bold=>1}
194 4 100       12 unless ref($self->{"first"}) eq "HASH";
195 4 50       6 return wantarray ? %{$self->{"first"}} : $self->{"first"};
  4         11  
196             }
197              
198             =head2 default
199              
200             Returns a hash of default settings for the body
201              
202             $ss->default({setting=>"value"}); #settings from L
203              
204             =cut
205              
206             sub default {
207 12     12 1 14 my $self=shift;
208 12 50       37 $self->{"default"}=shift if @_;
209             $self->{"default"}={border=>1, border_color=>"gray"}
210 12 100       25 unless ref($self->{"default"}) eq "HASH";
211 12 50       18 return wantarray ? %{$self->{"default"}} : $self->{"default"};
  12         39  
212             }
213              
214             =head1 AUTHOR
215              
216             Michael R. Davis
217              
218             =head1 COPYRIGHT
219              
220             Copyright (c) 2009 Michael R. Davis
221             Copyright (c) 2001-2005 Tony Bowden (IO::Scalar portion used here "under the same terms as Perl itself")
222              
223             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
224              
225             The full text of the license can be found in the LICENSE file included with this module.
226              
227             =head1 SEE ALSO
228              
229             L, L sqlarrayarrayname method, L, L
230              
231             =cut
232              
233             1;