File Coverage

blib/lib/Spreadsheet/Wright.pm
Criterion Covered Total %
statement 59 80 73.7
branch 13 34 38.2
condition 3 8 37.5
subroutine 13 19 68.4
pod 7 7 100.0
total 95 148 64.1


line stmt bran cond sub pod time code
1             package Spreadsheet::Wright;
2              
3 2     2   197579 use 5.010;
  2         17  
4 2     2   10 use strict;
  2         4  
  2         39  
5 2     2   9 use warnings;
  2         4  
  2         66  
6 2     2   11 no warnings qw( uninitialized numeric );
  2         4  
  2         101  
7              
8             BEGIN {
9 2     2   6 $Spreadsheet::Wright::VERSION = '0.106';
10 2         50 $Spreadsheet::Wright::AUTHORITY = 'cpan:TOBYINK';
11             }
12              
13 2     2   12 use Carp;
  2         4  
  2         122  
14 2     2   987 use IO::File;
  2         17004  
  2         1871  
15              
16             sub new
17             {
18 1     1 1 217 my ($class, %args) = @_;
19            
20 1   50     7 my $format = $args{'format'} // 'auto';
21 1   33     4 my $filename = $args{'file'} // $args{'filename'};
22            
23 1 50       6 if (lc $format eq 'auto')
24             {
25 1 50       9 $format = ($filename =~ /\.([^\.]+)$/) ? lc($1) : 'auto';
26             }
27            
28             my $implementation = {
29             auto => 'CSV',
30             csv => 'CSV',
31             excel => 'Excel',
32             html => 'HTML',
33             json => 'JSON',
34             ods => 'OpenDocument',
35             odsxml => 'OpenDocumentXML',
36             text => 'CSV',
37             txt => 'CSV',
38             xhtml => 'XHTML',
39             xls => 'Excel',
40             xml => 'OpenDocumentXML',
41 1         11 }->{lc $format};
42            
43             my $self = eval
44 1         5 {
45 1 50       3 croak "Format $format is not supported" unless $implementation;
46 1         3 $implementation = join '::', (__PACKAGE__, $implementation);
47 1     1   61 eval "use $implementation;";
  1         424  
  1         3  
  1         19  
48 1 50       6 die $@ if $@;
49 1         6 return $implementation->new(%args);
50             };
51            
52 1 50 33     6 if ($self and !$@)
    0          
    0          
53             {
54 1         5 return $self;
55             }
56             elsif ($args{'failsafe'})
57             {
58 0         0 $implementation = join '::', (__PACKAGE__, 'CSV');
59 0         0 eval "use $implementation;";
60 0 0       0 die $@ if $@;
61 0         0 return $implementation->new(%args);
62             }
63             elsif ($@)
64             {
65 0         0 die $@;
66             }
67             else
68             {
69 0         0 croak "Could not instantiate spreadsheet!\n";
70             }
71             }
72              
73             sub DESTROY
74             {
75 1     1   1260 my $self = shift;
76 1         4 $self->close;
77             }
78              
79             sub error
80             {
81 0     0 1 0 my $self = shift;
82 0         0 return $self->{'_ERROR'};
83             }
84              
85             sub _open
86             {
87 3     3   6 my $self=shift;
88            
89 3 50       7 $self->{'_CLOSED'} && croak "Can't reuse a closed spreadsheet";
90            
91 3         6 my $fh = $self->{'_FH'};
92            
93 3 100       7 if(!$fh)
94             {
95 1 50       4 my $filename = $self->{'_FILENAME'} or return;
96 1         7 $fh = IO::File->new;
97 1 50       46 $fh->open($filename,"w")
98             or croak "Can't open file $filename for writing: $!";
99 1         116 $self->{'_FH'}=$fh;
100             }
101            
102 3         9 return $self->_prepare;
103             }
104              
105             sub _prepare
106             {
107 0     0   0 return $_[0];
108             }
109              
110             sub addrow
111             {
112 3     3 1 10 my $self = shift;
113 3 50       10 $self->_open() or return;
114            
115 3         6 my @cells;
116            
117 3         6 foreach my $item (@_)
118             {
119 6 50       12 if (ref $item eq 'HASH')
120             {
121 0 0       0 if (ref $item->{content} eq 'ARRAY')
122             {
123 0         0 foreach my $i (@{ $item->{'content'} })
  0         0  
124             {
125 0         0 my %newitem = %$item;
126 0         0 $newitem{'content'} = $i;
127 0         0 push @cells, \%newitem;
128             }
129             }
130             else
131             {
132 0         0 push @cells, $item;
133             }
134             }
135             else
136             {
137 6         15 push @cells, { content => $item };
138             }
139             }
140            
141 3         12 return $self->_add_prepared_row(@cells);
142             }
143              
144             sub _add_prepared_row
145             {
146 0     0   0 return $_[0];
147             }
148              
149             sub addrows
150             {
151 1     1 1 10 my $self = shift;
152 1         3 foreach my $row (@_)
153             {
154 2 50       7 if (ref $row eq 'ARRAY')
    0          
155             {
156 2         6 $self->addrow(@$row);
157             }
158             elsif (!ref $row)
159             {
160 0         0 $self->addsheet($row);
161             }
162             else
163             {
164 0         0 carp "Could not add row.";
165             }
166             }
167 1         3 return $self;
168             }
169              
170             sub addsheet
171             {
172 0     0 1 0 croak "addsheet not implemented!!\n";
173             }
174              
175             sub freeze
176             {
177 0     0 1 0 return $_[0];
178             }
179              
180             sub close
181       0 1   {
182             # noop
183             }
184              
185             1;
186              
187             __END__
188              
189             =head1 NAME
190              
191             Spreadsheet::Wright - simple spreadsheet worker
192              
193             =head1 SYNOPSIS
194              
195             # EXCEL spreadsheet
196            
197             use Spreadsheet::Wright;
198            
199             my $s = Spreadsheet::Wright->new(
200             file => 'spreadsheet.xls',
201             format => 'xls',
202             sheet => 'Products',
203             styles => {
204             money => '($#,##0_);($#,##0)',
205             },
206             );
207            
208             $s->addrow('foo',{
209             content => 'bar',
210             type => 'number',
211             style => 'money',
212             font_weight => 'bold',
213             font_color => 42,
214             font_face => 'Times New Roman',
215             font_size => 20,
216             align => 'center',
217             valign => 'vcenter',
218             font_decoration => 'strikeout',
219             font_style => 'italic',
220             });
221             $s->addrow('foo2','bar2');
222             $s->freeze(1, 0);
223              
224             # CSV file
225            
226             use Spreadsheet::Wright;
227            
228             my $s = Spreadsheet::Wright->new(
229             file => 'file.csv',
230             encoding => 'iso8859',
231             );
232             die $s->error if $s->error;
233             $s->addrow('foo', 'bar');
234              
235             =head1 DESCRIPTION
236              
237             C<Spreadsheet::Wright> is a fork of L<Spreadsheet::Write> and
238             may be used as a drop-in replacement.
239              
240             C<Spreadsheet::Wright> writes files in CSV, Microsoft Excel,
241             HTML and OpenDocument formats. It is especially suitable
242             for building various dumps and reports where rows are built
243             in sequence, one after another.
244              
245             It is not especially suitable for modifying existing files.
246              
247             The name is a not just pun on "write" - the word "wright" means
248             worker or crafter, and C<Spreadsheet::Wright> does a lot of the
249             work of spreadsheet output for you!
250              
251             =head2 Constructor
252              
253             =over 4
254              
255             =item C<< Spreadsheet::Wright->new(%args) >>
256              
257             $spreadsheet = Spreadsheet::Wright->new(
258             file => 'table.xls',
259             styles => {
260             mynumber => '#,##0.00',
261             },
262             );
263              
264             Creates a new spreadsheet object. It takes a list of options. The
265             following are valid:
266              
267             =over 4
268              
269             =item * B<file> - filename of the new spreadsheet (mandatory)
270              
271             =item * B<encoding> - encoding of output file (optional, csv format only)
272              
273             =item * B<format> - format of spreadsheet - 'csv', 'xls', 'html', 'xhtml', 'xml', 'ods', 'json' or 'auto' (default).
274              
275             =item * B<sheet> - first sheet name (optional, not supported by some formats)
276              
277             =item * B<styles> - defines cell formatting shortcuts (optional)
278              
279             =item * B<failsafe> - boolean - if true, falls back to CSV in emergencies
280              
281             =back
282              
283             If file format is 'auto' (or omitted), the format is guessed from the
284             filename extension, defaulting to 'csv'.
285              
286             =back
287              
288             =head2 Methods
289              
290             =over 4
291              
292             =item C<< addrow($cell_1, $cell_2, ...) >>
293              
294             Adds a row into the spreadsheet. Takes arbitrary number of
295             arguments. Arguments represent cell values and may be strings or hash
296             references. If an argument is a hash reference, it takes the following
297             structure:
298              
299             content value to put into cell
300             style formatting style, as defined in new()
301             type type of the content (defaults to 'auto')
302             format number format (see Spreadsheet::WriteExcel for details)
303             font_weight weight of font. Only valid value is 'bold'
304             font_style style of font. Only valid value is 'italic'
305             font_decoration 'underline' or 'strikeout' (or both, space separated)
306             font_face font of column; default is 'Arial'
307             font_color color of font (see Spreadsheet::WriteExcel for color values)
308             font_size size of font
309             align alignment
310             valign vertical alignment
311             width column width, excel units (only makes sense once per column)
312             header boolean; is this cell a header?
313              
314             Styles can be used to assign default values for any of these formatting
315             parameters thus allowing easy global changes. Other parameters specified
316             override style definitions.
317              
318             Example:
319              
320             my $sp = Spreadsheet::Wright->new(
321             file => 'employees.xls',
322             styles => {
323             important => { font_weight => 'bold' },
324             },
325             );
326             $sp->addrow(
327             { content => 'First Name', font_weight => 'bold' },
328             { content => 'Last Name', font_weight => 'bold' },
329             { content => 'Age', style => 'important' },
330             );
331             $sp->addrow("John", "Doe", 34);
332             $sp->addrow("Susan", "Smith", 28);
333              
334             Note that in this example all header cells will have identical
335             formatting even though some use direct formats and one uses
336             style.
337              
338             If you want to store text that looks like a number you might want to use
339             { type => 'string', format => '@' } arguments. By default the type detection
340             is automatic, as done by for instance L<Spreadsheet::WriteExcel> write()
341             method.
342              
343             It is also possible to supply an array reference in the 'content'
344             parameter of the extended format. It means to use the same formatting
345             for as many cells as there are elements in this array. Useful for
346             creating header rows. For instance, the above example can be rewritten
347             as:
348              
349             $sp->addrow({
350             style => 'important',
351             content => ['First Name', 'Last Name', 'Age'],
352             });
353              
354             Not all styling options are supported in all formats.
355              
356             =item C<< addrows(\@row_1, \@row_2, ...) >>
357              
358             Shortcut for adding multiple rows.
359              
360             Each argument is an arrayref representing a row.
361              
362             Any argument that is not a reference (i.e. a scalar) is taken to be the
363             title of a new worksheet.
364              
365             =item C<< addsheet($name) >>
366              
367             Adds a new sheet into the document and makes it active. Subsequent
368             addrow() calls will add rows to that new sheet.
369              
370             For CSV format this call is NOT ignored, but produces a fatal error
371             currently.
372              
373             =item C<< freeze($row, $col, $top_row, $left_col) >>
374              
375             Sets a freeze-pane at the given position, equivalent to Spreadsheet::WriteExcel->freeze_panes().
376             Only implemented for Excel spreadsheets so far.
377              
378             =item C<< close >>
379              
380             Saves the spreadsheet to disk (some of the modules save incrementally anyway) and
381             closes the file. Calling this explicitly is usually un-necessary, as the Perl garbage collector
382             will do the job eventually anyway. Once a spreadsheet is closed, calls to addrow() will
383             fail.
384              
385             =item C<< error >>
386              
387             Returns the latest recoverable error.
388              
389             =back
390              
391             =head1 BUGS
392              
393             Please report any bugs to L<http://rt.cpan.org/>.
394              
395             =head1 SEE ALSO
396              
397             L<Spreadsheet::Write>.
398              
399             =head1 AUTHORS
400              
401             Toby Inkster <tobyink@cpan.org>.
402              
403             Excel and CSV output based almost entirely on work by
404             Nick Eremeev <nick.eremeev@gmail.com> L<http://ejelta.com/>.
405              
406             =head1 COPYRIGHT AND LICENCE
407              
408             Copyright 2007 Nick Eremeev.
409              
410             Copyright 2010-2011 Toby Inkster.
411              
412             This library is free software; you can redistribute it and/or modify it
413             under the same terms as Perl itself.
414              
415             =head1 DISCLAIMER OF WARRANTIES
416              
417             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
418             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
419             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
420