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