File Coverage

blib/lib/Spreadsheet/BasicRead.pm
Criterion Covered Total %
statement 100 134 74.6
branch 30 68 44.1
condition 10 41 24.3
subroutine 17 23 73.9
pod 17 17 100.0
total 174 283 61.4


line stmt bran cond sub pod time code
1             #
2             # Spreadsheet::BasicRead.pm
3             #
4             # Synopsis: see POD at end of file
5             #
6             #
7             #-- The package
8             #--------------------------------------------------
9             package Spreadsheet::BasicRead;
10            
11             $VERSION = sprintf("%d.%02d", q'$Revision: 1.11 $' =~ /(\d+)\.(\d+)/);
12             #--------------------------------------------------
13             #
14            
15             #-- Required Modules
16             #-------------------
17 1     1   6961 use strict;
  1         2  
  1         36  
18 1     1   7 use warnings;
  1         3  
  1         34  
19 1     1   2394 use Spreadsheet::ParseExcel;
  1         149421  
  1         36  
20 1     1   2137 use Spreadsheet::XLSX;
  1         122427  
  1         1244  
21            
22            
23             #-- Linage
24             #---------
25             our @ISA = qw( Spreadsheet::ParseExcel );
26            
27            
28             sub new
29             {
30 1     1 1 205 my $proto = shift;
31 1   33     8 my $class = ref($proto) || $proto;
32            
33 1         4 my $self = {};
34 1         3 bless($self, $class);
35            
36 1         8 $self->{skipBlankRows} = 0;
37 1         3 $self->{oldCell} = 0;
38            
39             # Do we have any arguments to process
40             #------------------------------------
41            
42             # Is there just one argument? If so treat as filename, otherwise assume named arguments
43 1 50       8 if (@_ == 1)
44             {
45 1         4 $self->{fileName} = $_[0];
46 1         7 $self->openSpreadsheet($self->{fileName});
47            
48 1         9 return $self;
49             }
50            
51            
52            
53             # If we get to here then we assume named arguments to process
54 0         0 my %args = @_;
55            
56             # Is there a log object
57 0 0 0     0 if (defined($args{log}) && $args{log} ne '')
58             {
59 0         0 $self->{log} = $args{log};
60             }
61            
62             # Do we skip blank rows
63 0 0       0 if (defined($args{skipBlankRows}))
64             {
65 0 0       0 $self->{skipBlankRows} = $args{skipBlankRows} ? 1 : 0;
66             }
67            
68             # Is there a file to open
69 0 0 0     0 if (defined($args{fileName}) && $args{fileName} ne '')
70             {
71 0         0 $self->{fileName} = $args{fileName};
72 0         0 $self->openSpreadsheet($args{fileName});
73             }
74            
75             # Skip headings (if defined) else skip the first row
76 0 0       0 if (defined $args{skipHeadings})
77             {
78 0         0 $self->{skipHeadings} = $args{skipHeadings};
79             }
80            
81             # Do we return undef on empty cells (old mode) or ''
82 0 0       0 $self->{oldCell} = $args{oldCell} if $args{oldCell};
83            
84 0         0 return $self;
85             }
86            
87            
88             sub openSpreadsheet
89             {
90 1     1 1 4 my ($self, $ssFileName) = @_;
91            
92             #-- Open the Excel spreadsheet and process
93 1         2 my $ssExcel;
94             my $ssBook;
95 1 50       9 if ($ssFileName =~ /\.xlsx$/i)
96             {
97 0         0 $ssExcel = Spreadsheet::XLSX->new($ssFileName);
98 0         0 $ssBook = $ssExcel;
99             }
100             else
101             {
102 1         9 $ssExcel = new Spreadsheet::ParseExcel;
103 1         6058 $ssBook = $ssExcel->Parse($ssFileName);
104             }
105            
106 1 50       22065 unless ($ssBook)
107             {
108 0         0 $self->logexp("Could not open Excel spreadsheet file '$ssFileName': $!");
109             }
110            
111             # Store the objects
112 1         9 $self->{ssExcel} = $ssExcel;
113 1         3 $self->{ssBook} = $ssBook;
114            
115             # Get the first sheet
116 1         6 $self->getFirstSheet();
117            
118 1         2 return ($ssExcel, $ssBook)
119             }
120            
121            
122            
123            
124             sub numSheets
125             {
126 7     7 1 119 my $self = shift;
127            
128 7 50       40 return defined($self->{ssBook}) ? $self->{ssBook}->{SheetCount} : undef;
129             }
130            
131            
132            
133             sub currentSheetNum
134             {
135 3     3 1 4 my $self = shift;
136            
137 3 100       10 return defined($self->{currentSheetNum}) ? $self->{currentSheetNum} : 0;
138             }
139            
140            
141            
142             sub currentSheetName
143             {
144 4     4 1 154 my $self = shift;
145            
146 4 50       72 return defined($self->{ssSheet}) ? $self->{ssSheet}->{Name} : undef;
147             }
148            
149            
150            
151             sub setCurrentSheetNum
152             {
153 3     3 1 2 my $self = shift;
154 3   50     12 my $shtNo = shift || 0;
155            
156             # Check if this is a valid value
157 3 50 33     10 return undef unless ($shtNo >= 0 && $shtNo <= $self->numSheets());
158            
159             # Set the new sheet number and return the sheet.
160 3         5 $self->{currentSheetNum} = $shtNo;
161 3         7 $self->{ssSheet} = $self->{ssBook}->{Worksheet}[$shtNo];
162 3 100       8 $self->{ssSheetRow} = $self->{ssSheet}->{MinRow} if (defined($self->{ssSheet}));
163 3 100       8 $self->{ssSheetCol} = $self->{ssSheet}->{MinCol} if (defined($self->{ssSheet}));
164 3         3 $self->{ssSheetRow} = -7; # Flag to getNextRow that this is the first row
165 3         4 return $self->{ssSheet};
166             }
167            
168            
169             sub skipHeadings
170             {
171 0   0 0 1 0 $_[0]->{skipHeadings} = $_[1] || 0;
172             }
173            
174            
175             sub getNextSheet
176             {
177 3     3 1 12 my $self = shift;
178            
179 3         8 my $currentSheet = $self->currentSheetNum();
180            
181             # No sheet, so get the first sheet
182 3 50       7 return $self->getFirstSheet() unless (defined($self->{ssSheet}));
183            
184             # Get the next sheet
185 3 50 33     12 if (defined($self->{ssSheet}) && $currentSheet < $self->numSheets())
186             {
187 3         8 $self->setCurrentSheetNum(++$currentSheet);
188 3         5 $self->{ssSheet} = $self->{ssBook}->{Worksheet}[$currentSheet];
189             # $self->{ssSheetRow} = $self->{ssSheet}->{MinRow} if (defined($self->{ssSheet}));
190 3         5 $self->{ssSheetRow} = -7; # So we then find the correct start, setting to min will skip the min row! - Thanks Tim Rossiter
191 3 100       8 $self->{ssSheetCol} = $self->{ssSheet}->{MinCol} if (defined($self->{ssSheet}));
192 3         6 return $self->{ssSheet};
193             }
194            
195 0         0 return undef;
196             }
197            
198            
199            
200             sub getFirstSheet
201             {
202 2     2 1 110 my $self = shift;
203            
204 2         6 $self->{setCurrentSheetNum} = 0;
205 2 50       10 $self->{ssSheet} = $self->{ssBook}->{Worksheet}[0] if (defined($self->{ssBook}));
206 2         5 $self->{ssSheetRow} = -7; # Flag to getNextRow that this is the first row
207 2 50       9 $self->{ssSheetCol} = $self->{ssSheet}->{MinCol} if (defined($self->{ssSheet}));
208 2         5 return $self->{ssSheet};
209             }
210            
211            
212             sub cellValue
213             {
214 21     21 1 36 my ($self, $r, $c) = @_;
215 21 0 33     104 return ($self->{oldCell}? undef : '') unless (defined($self->{ssSheet}) && defined($self->{ssSheet}->{Cells}[$r][$c]));
    50          
216            
217            
218             #return $self->{ssSheet}->{Cells}[$r][$c]->Value;
219             # V1.8 2006/03/05 Changes to cater for OpenOffice returning 'GENERAL'
220 21         62 my $cell_value = $self->{ssSheet}->{Cells}[$r][$c]->Value;
221 21 50       97 if ( $cell_value eq 'GENERAL' ) {
222 0         0 $cell_value = $self->{ssSheet}->{Cells}[$r][$c]->{Val};
223             }
224 21         46 return $cell_value;
225             }
226            
227            
228            
229             sub setHeadingRow
230             {
231 0     0 1 0 my $self = shift;
232 0         0 my $headingRow = shift;
233            
234 0 0 0     0 $self->{headingRow} = ($headingRow >= $self->{ssSheet}->{MinRow} &&
235             $headingRow <= $self->{ssSheet}->{MaxRow}) ?
236             $headingRow : $self->{ssSheet}->{MinRow};
237             }
238            
239            
240             sub getFirstRow
241             {
242 4     4 1 6 my $self = shift;
243            
244 4 50       10 return undef unless defined($self->{ssSheet});
245            
246 4   33     17 my $row = $self->{headingRow} || $self->{ssSheet}->{MinRow};
247 4         7 $self->{ssSheetRow} = $row;
248            
249            
250             # Loop through each column and put into array
251 4         4 my $x = 0;
252 4         6 my @data = ();
253 4         5 my $blank = 0;
254 4         12 for (my $col = $self->{ssSheet}->{MinCol}; $col <= $self->{ssSheet}->{MaxCol}; $x++, $col++)
255             {
256 1     1   14 no warnings qw(uninitialized);
  1         2  
  1         353  
257            
258             # Note that this is the formatted value of the cell (ie what you see, no the real value)
259 12         21 $data[$x] = $self->cellValue($row, $col);
260            
261             # remove leading and trailing whitespace
262 12         28 $data[$x] =~ s/^\s+//;
263 12         33 $data[$x] =~ s/\s+$//;
264 12 50       52 $blank++ unless $data[$x] =~ /^$/;
265             }
266            
267            
268 4 50 33     36 return ($self->{skipHeadings} || ($self->{skipBlankRows} && $blank == 0)) ? $self->getNextRow() : \@data;
269             }
270            
271            
272            
273             sub getNextRow
274             {
275 10     10 1 316 my $self = shift;
276            
277             # Must have a sheet defined
278 10 50       58 return undef unless defined($self->{ssSheet});
279            
280             # Find the next row and make sure it's valid
281 10         12 my $row = ++$self->{ssSheetRow};
282             # Check to make sure there is something on this sheet
283 10 100 66     62 return undef if (! defined($self->{ssSheet}->{MaxRow}) || $row > $self->{ssSheet}->{MaxRow});
284            
285             # If row is zero or negative then this is the first row
286 7 100       22 return $self->getFirstRow() if ($row <= 0);
287            
288            
289             # Loop through each column and put into array
290 3         4 my $x = 0;
291 3         4 my @data = ();
292 3         4 my $blank = 0;
293 3         9 for (my $col = $self->{ssSheet}->{MinCol}; $col <= $self->{ssSheet}->{MaxCol}; $x++, $col++)
294             {
295 1     1   7 no warnings qw(uninitialized);
  1         2  
  1         438  
296            
297             # Note that this is the formatted value of the cell (ie what you see, no the real value)
298 9         18 $data[$x] = $self->cellValue($row, $col);
299            
300             # remove leading and trailing whitespace
301 9         19 $data[$x] =~ s/^\s+//;
302 9         20 $data[$x] =~ s/\s+$//;
303 9 50       38 $blank++ unless $data[$x] =~ /^$/;
304             }
305            
306 3 50 33     28 return ($self->{skipBlankRows} && $blank == 0) ? $self->getNextRow() : \@data;
307             }
308            
309            
310             sub setRow
311             {
312 0   0 0 1   $_[0]->{ssSheetRow} = ($_[1] || 0) - 1;
313             }
314            
315            
316             sub getRowNumber
317             {
318 0   0 0 1   return $_[0]->{ssSheetRow} || -1;
319             }
320            
321            
322             sub logexp
323             {
324 0     0 1   my $self = shift;
325            
326 0           my $msg = join('', @_);
327 0 0         if (defined $self->{log})
328             {
329 0           $self->{log}->exp($msg);
330             }
331            
332 0           die $msg;
333             }
334            
335            
336            
337             sub logmsg
338             {
339 0     0 1   my $self = shift;
340 0           my $level = shift;
341            
342 0           my $msg = join('', @_);
343 0 0         if (defined $self->{log})
344             {
345 0           $self->{log}->msg($level, $msg);
346             }
347             else
348             {
349 0           print STDERR $msg;
350             }
351             }
352            
353            
354            
355             #####################################################################
356             # DO NOT REMOVE THE FOLLOWING LINE, IT IS NEEDED TO LOAD THIS LIBRARY
357             1;
358            
359             __END__