Spreadsheet-Read-0.41/0000755000031300001440000000000011453657405013765 5ustar merijnusersSpreadsheet-Read-0.41/README0000644000031300001440000000320111334732466014640 0ustar merijnusers=head1 NAME Spreadsheet::Read - Meta-Wrapper for reading spreadsheet data =head1 SYNOPSIS use Spreadsheet::Read; my $ref = ReadData ("file.xls"); =head1 DESCRIPTION Spreadsheet::Read offers a uniformed wrapper to Spreadsheet::ParseExcel and Spreadheet::ReadSXC to give the end-user a single point of view to various types of spreadsheets and deal with these in a transparent way. For more thorough documentation please refer to the perl documentation in the module in pod format, or $ man Spreadsheet::Read after installation. =head1 INSTALLATION $ perl Makefile.PL $ make $ make test $ make install If the C warns you in the xls tests, read the message and apply the generated patch. Spreadsheet::ParseExcel has a small bug in the parsing of the default format regarding UTF-8. This module requires perl-5.6.x or newer. Recent changes can be (re)viewed in the public GIT repository at http://repo.or.cz/w/Spreadsheet-Read.git Feel free to clone your own copy: $ git clone http://repo.or.cz/r/Spreadsheet-Read.git Spreadsheet-Read or get it as a tgz: $ wget --output-document=Spreadsheet-Read-git.tgz \ 'http://repo.or.cz/w/Spreadsheet-Read.git?a=snapshot;sf=tgz' =head1 TODO * Make tests for examples/xlscat * Support Parsers native module options * Check if Tk is installed before asking if ss2tk is wanted * Test diagnostics output * Make clip skip empty sheets =head1 AUTHOR H.Merijn Brand, =head1 COPYRIGHT AND LICENSE Copyright (C) 2005-2010 H.Merijn Brand This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Spreadsheet-Read-0.41/t/0000755000031300001440000000000011453657405014230 5ustar merijnusersSpreadsheet-Read-0.41/t/23_csv.t0000644000031300001440000000565011275744712015522 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 117; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("csv") or plan skip_all => "No CSV parser found"; sub ReadDataStream { my $file = shift; open my $fh, "<", $file or return undef; ReadData ($fh, parser => "csv", @_); } # ReadDataStream { my $ref; $ref = ReadDataStream ("no_such_file.csv"); ok (!defined $ref, "Nonexistent file"); $ref = ReadDataStream ("empty.csv"); ok (!defined $ref, "Empty file"); } my $csv; ok ($csv = ReadDataStream ("files/test.csv"), "Read/Parse csv file"); ok (1, "Base values"); is (ref $csv, "ARRAY", "Return type"); is ($csv->[0]{type}, "csv", "Spreadsheet type"); is ($csv->[0]{sheets}, 1, "Sheet count"); is (ref $csv->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$csv->[0]{sheet}}, 1, "Sheet list count"); cmp_ok ($csv->[0]{version}, ">=", 0.01, "Parser version"); is ($csv->[1]{maxrow}, 5, "Last row"); is ($csv->[1]{maxcol}, 19, "Last column"); is ($csv->[1]{cell}[$csv->[1]{maxcol}][$csv->[1]{maxrow}], "LASTFIELD", "Last field"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } ok ($csv = ReadDataStream ("files/test_m.csv", sep => ";"), "Read/Parse M\$ csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } ok ($csv = ReadDataStream ("files/test_x.csv", sep => "=", quote => "_"), "Read/Parse strange csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/65_perc.t0000644000031300001440000000167111211434454015652 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 77; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/perc.xlsx", attr => 1), "Excel Percentage testcase"); my $ss = $xls->[1]; my $attr = $ss->{attr}; foreach my $row (1 .. 19) { is ($ss->{attr}[1][$row]{type}, "numeric", "Type A$row numeric"); is ($ss->{attr}[2][$row]{type}, "percentage", "Type B$row percentage"); is ($ss->{attr}[3][$row]{type}, "percentage", "Type C$row percentage"); SKIP: { $ss->{B18} =~ m/[.]/ and skip "$xls->[0]{parser} $xls->[0]{version} has format problems", 1; my $i = int $ss->{"A$row"}; is ($ss->{"B$row"}, "$i%", "Formatted values for row $row\n"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/62_fmt.t0000644000031300001440000000376611211433346015512 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 40; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/attr.xlsx", attr => 1), "Excel Attributes testcase"); SKIP: { ok (my $fmt = $xls->[$xls->[0]{sheet}{Format}], "format"); $fmt->{attr}[2][2]{merged} or skip "$xls->[0]{parser} $xls->[0]{version} does not reliably support attributes yet", 38; is ($fmt->{B2}, "merged", "Merged cell left formatted"); is ($fmt->{C2}, undef, "Merged cell right formatted"); is ($fmt->{cell}[2][2], "merged", "Merged cell left unformatted"); is ($fmt->{cell}[3][2], undef, "Merged cell right unformatted"); is ($fmt->{attr}[2][2]{merged}, 1, "Merged cell left merged"); is ($fmt->{attr}[3][2]{merged}, 1, "Merged cell right merged"); is ($fmt->{B3}, "unlocked", "Unlocked cell"); is ($fmt->{attr}[2][3]{locked}, 0, "Unlocked cell not locked"); is ($fmt->{attr}[2][3]{merged}, 0, "Unlocked cell not merged"); is ($fmt->{attr}[2][3]{hidden}, 0, "Unlocked cell not hidden"); is ($fmt->{B4}, "hidden", "Hidden cell"); is ($fmt->{attr}[2][4]{hidden}, 1, "Hidden cell hidden"); is ($fmt->{attr}[2][4]{merged}, 0, "Hidden cell not merged"); foreach my $r (1 .. 12) { is ($fmt->{cell}[1][$r], 12345, "Unformatted valued A$r"); } is ($fmt->{attr}[1][1]{format}, undef, "Default format"); is ($fmt->{cell}[1][1], $fmt->{A1}, "Formatted valued A1"); is ($fmt->{cell}[1][10], $fmt->{A10}, "Formatted valued A10"); # String foreach my $r (2 .. 9, 11, 12) { isnt ($fmt->{cell}[1][$r], $fmt->{"A$r"}, "Unformatted valued A$r"); } # Not yet. needs more digging #foreach my $r (2 .. 12) { # ok (defined $fmt->{attr}[1][$r]{format}, "Defined format A$r"); # } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/35_perc.t0000644000031300001440000000151311163712567015654 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 77; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xls") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/perc.xls", attr => 1), "Excel Percentage testcase"); my $ss = $xls->[1]; my $attr = $ss->{attr}; foreach my $row (1 .. 19) { is ($ss->{attr}[1][$row]{type}, "numeric", "Type A$row numeric"); is ($ss->{attr}[2][$row]{type}, "percentage", "Type B$row percentage"); is ($ss->{attr}[3][$row]{type}, "percentage", "Type C$row percentage"); my $i = int $ss->{"A$row"}; is ($ss->{"B$row"}, "$i%", "Formatted values for row $row\n"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/32_fmt.t0000644000031300001440000000340311163712315015475 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 39; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xls") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/attr.xls", attr => 1), "Excel Attributes testcase"); my $fmt = $xls->[$xls->[0]{sheet}{Format}]; is ($fmt->{B2}, "merged", "Merged cell left formatted"); is ($fmt->{C2}, "", "Merged cell right formatted"); is ($fmt->{cell}[2][2], "merged", "Merged cell left unformatted"); is ($fmt->{cell}[3][2], "", "Merged cell right unformatted"); is ($fmt->{attr}[2][2]{merged}, 1, "Merged cell left merged"); is ($fmt->{attr}[3][2]{merged}, 1, "Merged cell right merged"); is ($fmt->{B3}, "unlocked", "Unlocked cell"); is ($fmt->{attr}[2][3]{locked}, 0, "Unlocked cell not locked"); is ($fmt->{attr}[2][3]{merged}, 0, "Unlocked cell not merged"); is ($fmt->{attr}[2][3]{hidden}, 0, "Unlocked cell not hidden"); is ($fmt->{B4}, "hidden", "Hidden cell"); is ($fmt->{attr}[2][4]{hidden}, 1, "Hidden cell hidden"); is ($fmt->{attr}[2][4]{merged}, 0, "Hidden cell not merged"); foreach my $r (1 .. 12) { is ($fmt->{cell}[1][$r], 12345, "Unformatted valued A$r"); } is ($fmt->{attr}[1][1]{format}, undef, "Default format"); is ($fmt->{cell}[1][1], $fmt->{A1}, "Formatted valued A1"); is ($fmt->{cell}[1][10], $fmt->{A10}, "Formatted valued A10"); # String foreach my $r (2 .. 9, 11, 12) { isnt ($fmt->{cell}[1][$r], $fmt->{"A$r"}, "Unformatted valued A$r"); } # Not yet. needs more digging #foreach my $r (2 .. 12) { # ok (defined $fmt->{attr}[1][$r]{format}, "Defined format A$r"); # } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/22_csv.t0000644000031300001440000000233411163712203015477 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 4; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("csv") or plan skip_all => "No CSV parser found"; my $csv; ok ($csv = ReadData ("files/macosx.csv"), "Read/Parse csv file"); #use DP; DDumper $csv; is ($csv->[1]{maxrow}, 16, "Last row"); is ($csv->[1]{maxcol}, 15, "Last column"); is ($csv->[1]{cell}[$csv->[1]{maxcol}][$csv->[1]{maxrow}], "", "Last field"); unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); __END__ ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } is ($csv->[0]{sepchar}, ",", "{sepchar}"); is ($csv->[0]{quote}, '"', "{quote}"); is ($csv->[1]{C3}, "C3", "cell C3"); Spreadsheet-Read-0.41/t/45_ods.t0000644000031300001440000000662411163712761015515 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 301; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("ods") or plan skip_all => "No SXC parser found"; my $content; { local $/; open my $xml, "<", "files/content.xml" or die "files/content.xml: $!\n"; binmode $xml; $content = <$xml>; close $xml; } { my $ref; $ref = ReadData ("no_such_file.ods"); ok (!defined $ref, "Nonexistent file"); # Too noisy #eval { $ref = ReadData ("files/empty.ods") }; #ok (!defined $ref, "Empty file"); #like ($@, qr/too short/); } foreach my $base ( [ "files/test.ods", "Read/Parse ods file" ], [ "files/content.xml", "Read/Parse xml file" ], [ $content, "Parse xml data" ], ) { my ($txt, $msg) = @$base; my $sxc; ok ($sxc = ReadData ($txt), $msg); ok (1, "Base values"); is (ref $sxc, "ARRAY", "Return type"); is ($sxc->[0]{type}, "sxc", "Spreadsheet type"); is ($sxc->[0]{sheets}, 2, "Sheet count"); is (ref $sxc->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$sxc->[0]{sheet}}, 2, "Sheet list count"); # This should match the version required in Makefile.PL's PREREQ_PM cmp_ok ($sxc->[0]{version}, ">=", 0.12, "Parser version"); ok (1, "Sheet 1"); # Simple sheet with cells filled with the cell label: # -- -- -- -- # A1 B1 D1 # A2 B2 # A3 C3 D3 # A4 B4 C4 ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Nonexistent fields"); foreach my $cell (qw( A9 X6 B17 AB4 BE33 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Sheet 2"); # Sheet with merged cells and notes/annotations # x x x # x x # x x x ok (1, "Defined fields"); foreach my $cell (qw( A1 C1 E1 B2 D2 A3 C3 E3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], "x", "Unformatted cell $cell"); is ($sxc->[2]{$cell}, "x", "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B1 D1 A2 C2 E2 B3 D3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[2]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Nonexistent fields"); foreach my $cell (qw( A9 X6 B17 AB4 BE33 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[2]{$cell}, undef, "Formatted cell $cell"); } # Sheet order ok (exists $sxc->[0]{sheet}{Sheet1}, "Sheet labels in metadata"); my @sheets = map { $sxc->[$_]{label} } 1 .. $sxc->[0]{sheets}; SKIP: { $sxc->[0]{version} < 0.20 and skip "Not supported", 1; is ("@sheets", "@{['Sheet1','Second Sheet']}", "Sheet order"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/30_xls.t0000644000031300001440000001165411354634621015527 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser; if ($parser = Spreadsheet::Read::parses ("xls")) { print STDERR "# Parser: $parser-", $parser->VERSION, "\n"; plan tests => 218; Test::NoWarnings->import; } else { plan skip_all => "No M\$-Excel parser found"; } { my $ref; $ref = ReadData ("no_such_file.xls"); ok (!defined $ref, "Nonexistent file"); $ref = ReadData ("empty.xls"); ok (!defined $ref, "Empty file"); } my $content; { local $/; open my $xls, "<", "files/test.xls" or die "files/test.xls: $!"; binmode $xls; $content = <$xls>; close $xls; } my $xls; foreach my $base ( [ "files/test.xls", "Read/Parse xls file" ], [ $content, "Parse xls data" ], ) { my ($txt, $msg) = @$base; ok ($xls = ReadData ($txt), $msg); ok (1, "Base values"); is (ref $xls, "ARRAY", "Return type"); is ($xls->[0]{type}, "xls", "Spreadsheet type"); is ($xls->[0]{sheets}, 2, "Sheet count"); is (ref $xls->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$xls->[0]{sheet}}, 2, "Sheet list count"); cmp_ok ($xls->[0]{version}, ">=", 0.26, "Parser version"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($xls->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($xls->[1]{$cell}, undef, "Formatted cell $cell"); } my @row = Spreadsheet::Read::rows ($xls->[1]); is (scalar @row, 4, "Row'ed rows"); is (scalar @{$row[3]}, 4, "Row'ed columns"); is ($row[0][3], "D1", "Row'ed value D1"); is ($row[3][2], "C4", "Row'ed value C4"); } # This files is generated under Mac OS/X Tiger ok (1, "XLS File fom Mac OS X"); ok ($xls = ReadData ("files/macosx.xls", clip => 0), "Read/Parse Mac OS X xls file"); ok (1, "Base values"); is ($xls->[0]{sheets}, 3, "Sheet count"); is ($xls->[0]{sheet}{Sheet3}, 3, "Sheet labels"); is ($xls->[1]{maxrow}, 25, "MaxRow"); is ($xls->[1]{maxcol}, 3, "MaxCol"); is ($xls->[2]{label}, "Sheet2", "Sheet label"); is ($xls->[2]{maxrow}, 0, "Empty sheet maxrow"); is ($xls->[2]{maxcol}, 0, "Empty sheet maxcol"); ok (1, "Content"); is ($#{$xls->[1]{cell}[3]}, $xls->[1]{maxrow}, "cell structure"); ok (defined $xls->[1]{cell}[$xls->[1]{maxcol}][$xls->[1]{maxrow}], "last cell"); foreach my $x (1 .. 17) { my $cell = cr2cell (1, $x); is ($xls->[1]{$cell}, $x, "Cell $cell"); is ($xls->[1]{cell}[1][$x], $x, "Cell 1, $x"); } foreach my $x (1 .. 25) { my $cell = cr2cell (3, $x); is ($xls->[1]{$cell}, $x, "Cell $cell"); is ($xls->[1]{cell}[3][$x], $x, "Cell 3, $x"); } foreach my $cell (qw( A18 B1 B6 B20 C26 D14 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], undef, "Cell $cell"); is ($xls->[1]{$cell}, undef, "Cell $c, $r"); } eval { eval "use ".$parser."::FmtDefault"; my ($pm) = map { $INC{$_} } grep m{FmtDefault.pm$}i => keys %INC; if (open my $ph, "<", $pm) { my $l; $l = <$ph> for 1 .. 68; close $ph; if ($l =~ m/'C\*'/) { print STDERR "\n", "# If the next tests give warnings like\n", "# Character in 'C' format wrapped in pack at\n", "# $pm line 68\n", "# Change C* to U* in line 68\n", "# patch -p0 ; s/\bPM\b/$pm/ for @patch; open $ph, ">", "SPE68.diff" or die "SPE68.diff: $!\n"; print $ph @patch; close $ph; } } }; # Tests for empty thingies ok ($xls = ReadData ("files/values.xls"), "True/False values"); ok (my $ss = $xls->[1], "first sheet"); is ($ss->{cell}[1][1], "A1", "unformatted plain text"); is ($ss->{cell}[2][1], " ", "unformatted space"); is ($ss->{cell}[3][1], undef, "unformatted empty"); is ($ss->{cell}[4][1], "0", "unformatted numeric 0"); is ($ss->{cell}[5][1], "1", "unformatted numeric 1"); is ($ss->{cell}[6][1], "", "unformatted a single '"); is ($ss->{A1}, "A1", "formatted plain text"); is ($ss->{B1}, " ", "formatted space"); is ($ss->{C1}, undef, "formatted empty"); is ($ss->{D1}, "0", "formatted numeric 0"); is ($ss->{E1}, "1", "formatted numeric 1"); is ($ss->{F1}, "", "formatted a single '"); __END__ --- PM 2005-09-15 14:16:36.163623616 +0200 +++ PM 2005-09-15 14:11:56.289171000 +0200 @@ -65,7 +65,7 @@ sub new($;%) { sub TextFmt($$;$) { my($oThis, $sTxt, $sCode) =@_; return $sTxt if((! defined($sCode)) || ($sCode eq '_native_')); - return pack('C*', unpack('n*', $sTxt)); + return pack('U*', unpack('n*', $sTxt)); } #------------------------------------------------------------------------------ # FmtStringDef (for Spreadsheet::ParseExcel::FmtDefault) Spreadsheet-Read-0.41/t/11_call.t0000644000031300001440000000157311163710701015622 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; use Test::More; use Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("sc") or plan skip_all => "No SquirelCalc parser found"; plan tests => 81; # Base attributes foreach my $onoff (0, 1) { for ( [ ], [ rc => $onoff ], [ cell => $onoff ], [ rc => 0, cell => $onoff ], [ rc => 1, cell => $onoff ], [ clip => $onoff ], [ cell => 0, clip => $onoff ], [ cell => 1, clip => $onoff ], [ attr => $onoff ], [ cell => 0, attr => $onoff ], ) { my $ref = ReadData ("files/test.sc", @$_); ok ($ref, "Open with options (@$_)"); ok (ref $ref, "Valid ref"); $ref = ReadData ("files/test.sc", { @$_ }); ok ($ref, "Open with options {@$_}"); ok (ref $ref, "Valid ref"); } } # TODO: test and catch unsupported option. # Currently they are silently ignored Spreadsheet-Read-0.41/t/00_pod.t0000644000031300001440000000022410313230744015457 0ustar merijnusers#!/usr/bin/perl use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok (); Spreadsheet-Read-0.41/t/51_sc.t0000644000031300001440000000321111275744765015334 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 26; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("sc") or plan skip_all => "No SquirelCalc parser found"; sub ReadDataStream { my $file = shift; open my $fh, "<", $file or return undef; ReadData ($fh, parser => "sc", @_); } # ReadDataStream { my $ref; $ref = ReadDataStream ("no_such_file.sc"); ok (!defined $ref, "Nonexistent file"); $ref = ReadDataStream ("files/empty.sc"); ok (!defined $ref, "Empty file"); } my $content; { local $/; open my $sc, "<", "files/test.sc" or die "files/test.sc: $!\n"; binmode $sc; $content = <$sc>; close $sc; isnt ($content, undef, "Content is defined"); isnt ($content, "", "Content is filled"); } foreach my $clip (0, 2) { my $sc; ok ($sc = ReadDataStream ("files/test.sc", clip => $clip), "Read/Parse sc file ".($clip?"clipped":"unclipped")); ok (1, "Base values"); is (ref $sc, "ARRAY", "Return type"); is ($sc->[0]{type}, "sc", "Spreadsheet type"); is ($sc->[0]{sheets}, 1, "Sheet count"); is (ref $sc->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$sc->[0]{sheet}}, 1, "Sheet list count"); is ($sc->[0]{version}, $Spreadsheet::Read::VERSION, "Parser version"); is ($sc->[1]{maxcol}, 10 - $clip, "Columns"); is ($sc->[1]{maxrow}, 28 - $clip, "Rows"); is ($sc->[1]{cell}[1][22], " Workspace", "Just checking one cell"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/33_misc.t0000644000031300001440000000127111163712371015646 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 2; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xls") or plan skip_all => "No M\$-Excel parser found"; my $xls; { local *STDERR; # We want the debug activated, but not shown open STDERR, ">", "/dev/null" or die "/dev/null: $!\n"; $xls = ReadData ("files/misc.xls", # All defaults reversed rc => 0, cells => 0, attr => 1, clip => 1, debug => 5, ); } ok ($xls, "Open with options"); is ($xls->[0]{sheets}, 3, "Sheet Count"); unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/60_xlsx.t0000644000031300001440000000534511163650117015716 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 62; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; print STDERR "# Parser: $parser-", $parser->VERSION, "\n"; { my $ref; $ref = ReadData ("no_such_file.xlsx"); ok (!defined $ref, "Nonexistent file"); $ref = ReadData ("empty.xlsx"); ok (!defined $ref, "Empty file"); } my $content; { local $/; open my $xls, "<", "files/test.xlsx" or die "files/test.xlsx: $!"; binmode $xls; $content = <$xls>; close $xls; } my $xls; foreach my $base ( [ "files/test.xlsx", "Read/Parse xlsx file" ], # [ $content, "Parse xlsx data" ], ) { my ($txt, $msg) = @$base; ok ($xls = ReadData ($txt), $msg); ok (1, "Base values"); is (ref $xls, "ARRAY", "Return type"); is ($xls->[0]{type}, "xlsx", "Spreadsheet type"); is ($xls->[0]{sheets}, 2, "Sheet count"); is (ref $xls->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$xls->[0]{sheet}}, 2, "Sheet list count"); cmp_ok ($xls->[0]{version}, ">=", 0.07, "Parser version"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($xls->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($xls->[1]{$cell}, undef, "Formatted cell $cell"); } my @row = Spreadsheet::Read::rows ($xls->[1]); is (scalar @row, 4, "Row'ed rows"); is (scalar @{$row[3]}, 4, "Row'ed columns"); is ($row[0][3], "D1", "Row'ed value D1"); is ($row[3][2], "C4", "Row'ed value C4"); } # Tests for empty thingies ok ($xls = ReadData ("files/values.xlsx"), "True/False values"); ok (my $ss = $xls->[1], "first sheet"); is ($ss->{cell}[1][1], "A1", "unformatted plain text"); is ($ss->{cell}[2][1], " ", "unformatted space"); is ($ss->{cell}[3][1], undef, "unformatted empty"); is ($ss->{cell}[4][1], "0", "unformatted numeric 0"); is ($ss->{cell}[5][1], "1", "unformatted numeric 1"); is ($ss->{cell}[6][1], "", "unformatted a single '"); is ($ss->{A1}, "A1", "formatted plain text"); is ($ss->{B1}, " ", "formatted space"); is ($ss->{C1}, undef, "formatted empty"); is ($ss->{D1}, "0", "formatted numeric 0"); is ($ss->{E1}, "1", "formatted numeric 1"); is ($ss->{F1}, "", "formatted a single '"); unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/24_csv.t0000644000031300001440000000571011311672757015520 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 118; use Test::More; require Test::NoWarnings; use Spreadsheet::Read qw( ReadData cell2cr row cellrow ); my $parser = Spreadsheet::Read::parses ("csv") or plan skip_all => "No CSV parser found"; sub ReadDataCSV { ReadData (@_, parser => "csv"); } # ReadDataCSV { my $ref; $ref = ReadDataCSV ("files/empty.txt"); ok (!defined $ref, "Empty file"); } my $csv; ok ($csv = ReadDataCSV ("files/test.txt"), "Read/Parse csv file"); ok (1, "Base values"); is (ref $csv, "ARRAY", "Return type"); is ($csv->[0]{type}, "csv", "Spreadsheet type"); is ($csv->[0]{sheets}, 1, "Sheet count"); is (ref $csv->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$csv->[0]{sheet}}, 1, "Sheet list count"); cmp_ok ($csv->[0]{version}, ">=", 0.01, "Parser version"); is ($csv->[1]{maxrow}, 5, "Last row"); is ($csv->[1]{maxcol}, 19, "Last column"); is ($csv->[1]{cell}[$csv->[1]{maxcol}][$csv->[1]{maxrow}], "LASTFIELD", "Last field"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } my @row = ("A3", "", "C3", "D3", (undef) x 15); is_deeply ([ row ($csv->[1], 3) ], \@row, "Formatted row 3"); is_deeply ([ cellrow ($csv->[1], 3) ], \@row, "Unformatted row 3"); ok ($csv = ReadDataCSV ("files/test_m.txt"), "Read/Parse M\$ csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } ok ($csv = ReadDataCSV ("files/test_x.txt", sep => "=", quote => "_"), "Read/Parse strange csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/50_sc.t0000644000031300001440000000304211163713072015314 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 48; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("sc") or plan skip_all => "No SquirelCalc parser found"; print STDERR "# Parser: $parser-", $parser->VERSION, "\n"; { my $ref; $ref = ReadData ("no_such_file.sc"); ok (!defined $ref, "Nonexistent file"); $ref = ReadData ("files/empty.sc"); ok (!defined $ref, "Empty file"); } my $content; { local $/; open my $sc, "<", "files/test.sc" or die "files/test.sc: $!\n"; binmode $sc; $content = <$sc>; close $sc; isnt ($content, undef, "Content is defined"); isnt ($content, "", "Content is filled"); } foreach my $txt ("files/test.sc", $content) { foreach my $clip (0, 2) { my $sc; ok ($sc = ReadData ($txt, clip => $clip), "Read/Parse sc file ".($clip?"clipped":"unclipped")); ok (1, "Base values"); is (ref $sc, "ARRAY", "Return type"); is ($sc->[0]{type}, "sc", "Spreadsheet type"); is ($sc->[0]{sheets}, 1, "Sheet count"); is (ref $sc->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$sc->[0]{sheet}}, 1, "Sheet list count"); is ($sc->[0]{version}, $Spreadsheet::Read::VERSION, "Parser version"); is ($sc->[1]{maxcol}, 10 - $clip, "Columns"); is ($sc->[1]{maxrow}, 28 - $clip, "Rows"); is ($sc->[1]{cell}[1][22], " Workspace", "Just checking one cell"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/21_csv.t0000644000031300001440000000171611163711623015506 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 12; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("csv") or plan skip_all => "No CSV parser found"; my $csv; ok ($csv = ReadData ("files/test.csv"), "Read/Parse csv file"); is ($csv->[0]{sepchar}, ",", "{sepchar}"); is ($csv->[0]{quote}, '"', "{quote}"); is ($csv->[1]{C3}, "C3", "cell C3"); ok ($csv = ReadData ("files/test_m.csv"), "Read/Parse csv file (M$)"); is ($csv->[0]{sepchar}, ";", "{sepchar}"); is ($csv->[0]{quote}, '"', "{quote}"); is ($csv->[1]{C3}, "C3", "cell C3"); ok ($csv = ReadData ("files/test_t.csv", quote => "'"), "Read/Parse csv file (tabs)"); is ($csv->[0]{sepchar}, "\t", "{sepchar}"); is ($csv->[0]{quote}, "'", "{quote}"); is ($csv->[1]{C3}, "C3", "cell C3"); unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/64_dates.t0000644000031300001440000000417611211434133016015 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 71; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; BEGIN { delete @ENV{qw( LANG LC_ALL LC_DATE )}; } my $xls; ok ($xls = ReadData ("files/Dates.xlsx", attr => 1, dtfmt => "yyyy-mm-dd"), "Excel Date testcase"); SKIP: { ok (my $ss = $xls->[1], "sheet"); ok (my $attr = $ss->{attr}, "attr"); defined $attr->[2][1]{format} or skip "$xls->[0]{parser} $xls->[0]{version} does not reliably support formats", 68; my @date = (undef, 39668, 39672, 39790, 39673); my @fmt = (undef, undef, "yyyymmdd", "yyyy-mm-dd", "mm/dd/yyyy"); foreach my $r (1 .. 4) { is ($ss->{cell}[$_][$r], $date[$r], "Date value row $r col $_") for 1 .. 4; is ($attr->[$_][$r]{type}, "date", "Date type row $r col $_") for 1 .. 4; is ($attr->[$_][$r]{format}, $fmt[$_], "Date format row $r col $_") for 1 .. 4; } is ($ss->{A1}, "8-Aug", "Cell content A1"); is ($ss->{A2}, "12-Aug", "Cell content A2"); is ($ss->{A3}, "8-Dec", "Cell content A3"); is ($ss->{A4}, "13-Aug", "Cell content A4"); is ($ss->{B1}, 20080808, "Cell content B1"); is ($ss->{B2}, 20080812, "Cell content B2"); is ($ss->{B3}, 20081208, "Cell content B3"); is ($ss->{B4}, 20080813, "Cell content B4"); is ($ss->{C1}, "2008-08-08", "Cell content C1"); is ($ss->{C2}, "2008-08-12", "Cell content C2"); is ($ss->{C3}, "2008-12-08", "Cell content C3"); is ($ss->{C4}, "2008-08-13", "Cell content C4"); is ($ss->{D1}, "08/08/2008", "Cell content D1"); is ($ss->{D2}, "08/12/2008", "Cell content D2"); is ($ss->{D3}, "12/08/2008", "Cell content D3"); is ($ss->{D4}, "08/13/2008", "Cell content D4"); is ($ss->{E1}, "08 Aug 2008", "Cell content E1"); is ($ss->{E2}, "12 Aug 2008", "Cell content E2"); is ($ss->{E3}, "08 Dec 2008", "Cell content E3"); is ($ss->{E4}, "13 Aug 2008", "Cell content E4"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/10_basics.t0000644000031300001440000000724711154323243016157 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; use Test::More tests => 99; use Test::NoWarnings; use Spreadsheet::Read qw(:DEFAULT parses rows ); is (Spreadsheet::Read::Version (), $Spreadsheet::Read::VERSION, "Version check"); is (parses (undef), 0, "No sheet type"); is (parses ("xyzzy"), 0, "Unknown sheet type"); is (parses ("xls"), parses ("excel"), "Excel alias type"); is (parses ("sxc"), parses ("oo"), "OpenOffice alias type 1"); is (parses ("sxc"), parses ("OpenOffice"), "OpenOffice alias type 2"); is (parses ("prl"), parses ("perl"), "Perl alias type"); foreach my $x ([ "A1", 1, 1 ], [ "Z26", 26, 26 ], [ "AB12", 28, 12 ], [ "A", 0, 0 ], [ "19", 0, 0 ], [ "a9", 1, 9 ], [ "aAa9", 703, 9 ], [ "", 0, 0 ], [ undef, 0, 0 ], [ "x444444", 24, 444444 ], [ "xxxxxx4", 296559144, 4 ], ) { my $cell = $x->[0]; my ($c, $r) = cell2cr ($x->[0]); defined $cell or $cell = ""; is ($c, $x->[1], "Col for $cell"); is ($r, $x->[2], "Row for $cell"); } foreach my $x ([ 1, 1, "A1" ], [ 26, 26, "Z26" ], [ 28, 12, "AB12" ], [ 0, 0, "" ], [ -2, 0, "" ], [ 0, -12, "" ], [ 1, -12, "" ], [ undef, 1, "" ], [ 2, undef, "" ], [ 1, 9, "A9" ], [ 703, 9, "AAA9" ], [ 24, 444444, "X444444" ], [ 296559144, 4, "XXXXXX4" ], ) { my $cell = cr2cell ($x->[0], $x->[1]); my ($c, $r) = map { defined $_ ? $_ : "--undef --" } $x->[0], $x->[1]; is ($cell, $x->[2], "Cell for ($c, $r)"); } # Some illegal rows () calls for (undef, "", " ", 0, 1, [], {}) { my @rows = rows ($_); my $arg = defined $_ ? $_ : "-- undef --"; is (scalar @rows, 0, "Illegal rows ($arg)"); } for (undef, "", " ", 0, 1, [], {}) { my @rows = rows ({ cell => $_}); my $arg = defined $_ ? $_ : "-- undef --"; is (scalar @rows, 0, "Illegal rows ({ cell => $arg})"); } for (undef, "", " ", 0, 1, [], {}) { my @rows = rows ({ maxrow => 1, cell => $_}); my $arg = defined $_ ? $_ : "-- undef --"; is (scalar @rows, 0, "Illegal rows ({ maxrow => 1, cell => $arg })"); } for (undef, "", " ", 0, 1, [], {}) { my @rows = rows ({ maxcol => 1, cell => $_}); my $arg = defined $_ ? $_ : "-- undef --"; is (scalar @rows, 0, "Illegal rows ({ maxcol => 1, cell => $arg })"); } # Some illegal ReadData () calls for (undef, "", " ", 0, 1, [], {}) { my $ref = ReadData ($_); my $arg = defined $_ ? $_ : "-- undef --"; is ($ref, undef, "Illegal ReadData ($arg)"); } for (undef, "", " ", 0, 1, [], {}) { my $ref = ReadData ([ $_ ]); my $arg = defined $_ ? $_ : "-- undef --"; is ($ref, undef, "Illegal ReadData ([ $arg ])"); } for (undef, "", " ", 0, 1, [], {}) { my $ref = ReadData ("/dev/null", separator => $_); my $arg = defined $_ ? $_ : "-- undef --"; is ($ref, undef, "Illegal ReadData ({ $arg })"); } for (undef, "", " ", 0, 1, [], {}) { my $ref; eval { $ref = ReadData ("Read.pm", sep => $_); }; my $arg = defined $_ ? $_ : "-- undef --"; is ($ref, undef, "Illegal ReadData ({ $arg })"); } Spreadsheet-Read-0.41/t/31_clr.t0000644000031300001440000000247411163712261015475 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 256; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xls") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/attr.xls", attr => 1), "Excel Attributes testcase"); my $clr = $xls->[$xls->[0]{sheet}{Colours}]; is ($clr->{cell}[1][1], "auto", "Auto"); is ($clr->{attr}[1][1]{fgcolor}, undef, "Unspecified font color"); is ($clr->{attr}[1][1]{bgcolor}, undef, "Unspecified fill color"); my @clr = ( [], [ "auto", undef ], [ "red", "#ff0000" ], [ "green", "#008000" ], [ "blue", "#0000ff" ], [ "white", "#ffffff" ], [ "yellow", "#ffff00" ], [ "lightgreen", "#00ff00" ], [ "lightblue", "#00ccff" ], [ "gray", "#808080" ], ); foreach my $col (1 .. $#clr) { my $bg = $clr[$col][1]; is ($clr->{cell}[$col][1], $clr[$col][0], "Column $col header"); foreach my $row (1 .. $#clr) { my $fg = $clr[$row][1]; is ($clr->{cell}[1][$row], $clr[$row][0], "Row $row header"); is ($clr->{attr}[$col][$row]{fgcolor}, $fg, "FG ($col, $row)"); is ($clr->{attr}[$col][$row]{bgcolor}, $bg, "BG ($col, $row)"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/20_csv.t0000644000031300001440000000544111163711250015500 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 117; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("csv") or plan skip_all => "No CSV parser found"; print STDERR "# Parser: $parser-", $parser->VERSION, "\n"; { my $ref; $ref = ReadData ("no_such_file.csv"); ok (!defined $ref, "Nonexistent file"); $ref = ReadData ("empty.csv"); ok (!defined $ref, "Empty file"); } my $csv; ok ($csv = ReadData ("files/test.csv"), "Read/Parse csv file"); ok (1, "Base values"); is (ref $csv, "ARRAY", "Return type"); is ($csv->[0]{type}, "csv", "Spreadsheet type"); is ($csv->[0]{sheets}, 1, "Sheet count"); is (ref $csv->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$csv->[0]{sheet}}, 1, "Sheet list count"); cmp_ok ($csv->[0]{version}, ">=", 0.01, "Parser version"); is ($csv->[1]{maxrow}, 5, "Last row"); is ($csv->[1]{maxcol}, 19, "Last column"); is ($csv->[1]{cell}[$csv->[1]{maxcol}][$csv->[1]{maxrow}], "LASTFIELD", "Last field"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } ok ($csv = ReadData ("files/test_m.csv"), "Read/Parse M\$ csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } ok ($csv = ReadData ("files/test_x.csv", sep => "=", quote => "_"), "Read/Parse strange csv file"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($csv->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($csv->[1]{cell}[$c][$r], "", "Unformatted cell $cell"); is ($csv->[1]{$cell}, "", "Formatted cell $cell"); } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/40_sxc.t0000644000031300001440000000673511166722704015524 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 301; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("sxc") or plan skip_all => "No SXC parser found"; print STDERR "# Parser: $parser-", $parser->VERSION, "\n"; my $content; { local $/; open my $xml, "<", "files/content.xml" or die "files/content.xml: $!\n"; binmode $xml; $content = <$xml>; close $xml; } { my $ref; $ref = ReadData ("no_such_file.sxc"); ok (!defined $ref, "Nonexistent file"); # Too noisy #eval { $ref = ReadData ("files/empty.sxc") }; #ok (!defined $ref, "Empty file"); #like ($@, qr/too short/); } foreach my $base ( [ "files/test.sxc", "Read/Parse sxc file" ], [ "files/content.xml", "Read/Parse xml file" ], [ $content, "Parse xml data" ], ) { my ($txt, $msg) = @$base; my $sxc; ok ($sxc = ReadData ($txt), $msg); ok (1, "Base values"); is (ref $sxc, "ARRAY", "Return type"); is ($sxc->[0]{type}, "sxc", "Spreadsheet type"); is ($sxc->[0]{sheets}, 2, "Sheet count"); is (ref $sxc->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$sxc->[0]{sheet}}, 2, "Sheet list count"); # This should match the version required in Makefile.PL's PREREQ_PM cmp_ok ($sxc->[0]{version}, ">=", 0.12, "Parser version"); ok (1, "Sheet 1"); # Simple sheet with cells filled with the cell label: # -- -- -- -- # A1 B1 D1 # A2 B2 # A3 C3 D3 # A4 B4 C4 ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Nonexistent fields"); foreach my $cell (qw( A9 X6 B17 AB4 BE33 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[1]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Sheet 2"); # Sheet with merged cells and notes/annotations # x x x # x x # x x x ok (1, "Defined fields"); foreach my $cell (qw( A1 C1 E1 B2 D2 A3 C3 E3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], "x", "Unformatted cell $cell"); is ($sxc->[2]{$cell}, "x", "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B1 D1 A2 C2 E2 B3 D3 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[2]{$cell}, undef, "Formatted cell $cell"); } ok (1, "Nonexistent fields"); foreach my $cell (qw( A9 X6 B17 AB4 BE33 )) { my ($c, $r) = cell2cr ($cell); is ($sxc->[2]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($sxc->[2]{$cell}, undef, "Formatted cell $cell"); } # Sheet order ok (exists $sxc->[0]{sheet}{Sheet1}, "Sheet labels in metadata"); my @sheets = map { $sxc->[$_]{label} } 1 .. $sxc->[0]{sheets}; SKIP: { $sxc->[0]{version} < 0.20 and skip "Not supported", 1; is ("@sheets", "@{['Sheet1','Second Sheet']}", "Sheet order"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/46_clr.t0000644000031300001440000000273511163651103015500 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 256; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser = Spreadsheet::Read::parses ("ods") or plan skip_all => "No OpenOffice ODS parser found"; $parser->VERSION <= 0.20 and plan skip_all => "Spreadsheet::ReadSXC version " . $parser->VERSION . " doesn't support field attributes"; my $ods; ok ($ods = ReadData ("files/attr.ods", attr => 1), "Excel Attributes testcase"); my $clr = $ods->[$ods->[0]{sheet}{Colours}]; is ($clr->{cell}[1][1], "auto", "Auto"); is ($clr->{attr}[1][1]{fgcolor}, undef, "Unspecified font color"); is ($clr->{attr}[1][1]{bgcolor}, undef, "Unspecified fill color"); my @clr = ( [], [ "auto", undef ], [ "red", "#ff0000" ], [ "green", "#008000" ], [ "blue", "#0000ff" ], [ "white", "#ffffff" ], [ "yellow", "#ffff00" ], [ "lightgreen", "#00ff00" ], [ "lightblue", "#00ccff" ], [ "gray", "#808080" ], ); foreach my $col (1 .. $#clr) { my $bg = $clr[$col][1]; is ($clr->{cell}[$col][1], $clr[$col][0], "Column $col header"); foreach my $row (1 .. $#clr) { my $fg = $clr[$row][1]; is ($clr->{cell}[1][$row], $clr[$row][0], "Row $row header"); is ($clr->{attr}[$col][$row]{fgcolor}, $fg, "FG ($col, $row)"); is ($clr->{attr}[$col][$row]{bgcolor}, $bg, "BG ($col, $row)"); } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/61_clr.t0000644000031300001440000000273411211433632015473 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 257; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; my $xls; ok ($xls = ReadData ("files/attr.xlsx", attr => 1), "Excel Attributes testcase"); SKIP: { ok (my $clr = $xls->[$xls->[0]{sheet}{Colours}], "colours"); defined $clr->{attr}[2][2]{fgcolor} or skip "$xls->[0]{parser} $xls->[0]{version} does not reliably support colours yet", 255; is ($clr->{cell}[1][1], "auto", "Auto"); is ($clr->{attr}[1][1]{fgcolor}, undef, "Unspecified font color"); is ($clr->{attr}[1][1]{bgcolor}, undef, "Unspecified fill color"); my @clr = ( [], [ "auto", undef ], [ "red", "#ff0000" ], [ "green", "#008000" ], [ "blue", "#0000ff" ], [ "white", "#ffffff" ], [ "yellow", "#ffff00" ], [ "lightgreen", "#00ff00" ], [ "lightblue", "#00ccff" ], [ "gray", "#808080" ], ); foreach my $col (1 .. $#clr) { my $bg = $clr[$col][1]; is ($clr->{cell}[$col][1], $clr[$col][0], "Column $col header"); foreach my $row (1 .. $#clr) { my $fg = $clr[$row][1]; is ($clr->{cell}[1][$row], $clr[$row][0], "Row $row header"); is ($clr->{attr}[$col][$row]{fgcolor}, $fg, "FG ($col, $row)"); is ($clr->{attr}[$col][$row]{bgcolor}, $bg, "BG ($col, $row)"); } } } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/34_dates.t0000644000031300001440000000433211163712530016012 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 69; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xls") or plan skip_all => "No M\$-Excel parser found"; BEGIN { delete @ENV{qw( LANG LC_ALL LC_DATE )}; } my $xls; ok ($xls = ReadData ("files/Dates.xls", attr => 1, dtfmt => "yyyy-mm-dd"), "Excel Date testcase"); my $ss = $xls->[1]; my $attr = $ss->{attr}; my @date = (undef, 39668, 39672, 39790, 39673); my @fmt = (undef, undef, "yyyymmdd", "yyyy-mm-dd", "mm/dd/yyyy"); foreach my $r (1 .. 4) { is ($ss->{cell}[$_][$r], $date[$r], "Date value row $r col $_") for 1 .. 4; is ($attr->[$_][$r]{type}, "date", "Date type row $r col $_") for 1 .. 4; is ($attr->[$_][$r]{format}, $fmt[$_], "Date format row $r col $_") for 1 .. 4; } is ($ss->{A1}, "8-Aug", "Cell content A1"); is ($ss->{A2}, "12-Aug", "Cell content A2"); is ($ss->{A3}, "8-Dec", "Cell content A3"); is ($ss->{A4}, "13-Aug", "Cell content A4"); is ($ss->{B1}, 20080808, "Cell content B1"); is ($ss->{B2}, 20080812, "Cell content B2"); is ($ss->{B3}, 20081208, "Cell content B3"); is ($ss->{B4}, 20080813, "Cell content B4"); is ($ss->{C1}, "2008-08-08", "Cell content C1"); is ($ss->{C2}, "2008-08-12", "Cell content C2"); is ($ss->{C3}, "2008-12-08", "Cell content C3"); is ($ss->{C4}, "2008-08-13", "Cell content C4"); is ($ss->{D1}, "08/08/2008", "Cell content D1"); is ($ss->{D2}, "08/12/2008", "Cell content D2"); is ($ss->{D3}, "12/08/2008", "Cell content D3"); is ($ss->{D4}, "08/13/2008", "Cell content D4"); is ($ss->{E1}, "08 Aug 2008", "Cell content E1"); is ($ss->{E2}, "12 Aug 2008", "Cell content E2"); is ($ss->{E3}, "08 Dec 2008", "Cell content E3"); is ($ss->{E4}, "13 Aug 2008", "Cell content E4"); # Below can only be checked when SS::PE 0.34 is out #use DDumper; #foreach my $r (1..4,6..7) { # foreach my $c (1..5) { # my $cell = cr2cell ($c, $r); # my $fmt = $ss->{attr}[$c][$r]{format}; # defined $ss->{$cell} or next; # printf STDERR "# attr %s: %-22s %s\n", # $cell, $ss->{$cell}, defined $fmt ? "'$fmt'" : ""; # } # } unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/36_xls.t0000644000031300001440000001204511354634670015534 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; my $parser; if ($parser = Spreadsheet::Read::parses ("xls")) { plan tests => 172; Test::NoWarnings->import; } else { plan skip_all => "No M\$-Excel parser found"; } sub ReadDataStream { my $file = shift; open my $fh, "<", $file or return undef; ReadData ($fh, parser => "xls", @_); } # ReadDataStream { my $ref; $ref = ReadDataStream ("no_such_file.xls"); ok (!defined $ref, "Nonexistent file"); $ref = ReadDataStream ("empty.xls"); ok (!defined $ref, "Empty file"); } my $content; { local $/; open my $xls, "<", "files/test.xls" or die "files/test.xls: $!"; binmode $xls; $content = <$xls>; close $xls; } my $xls; foreach my $base ( [ "files/test.xls", "Read/Parse xls file" ], # [ $content, "Parse xls data" ], ) { my ($txt, $msg) = @$base; ok ($xls = ReadDataStream ($txt), $msg); ok (1, "Base values"); is (ref $xls, "ARRAY", "Return type"); is ($xls->[0]{type}, "xls", "Spreadsheet type"); is ($xls->[0]{sheets}, 2, "Sheet count"); is (ref $xls->[0]{sheet}, "HASH", "Sheet list"); is (scalar keys %{$xls->[0]{sheet}}, 2, "Sheet list count"); cmp_ok ($xls->[0]{version}, ">=", 0.26, "Parser version"); ok (1, "Defined fields"); foreach my $cell (qw( A1 A2 A3 A4 B1 B2 B4 C3 C4 D1 D3 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], $cell, "Unformatted cell $cell"); is ($xls->[1]{$cell}, $cell, "Formatted cell $cell"); } ok (1, "Undefined fields"); foreach my $cell (qw( B3 C1 C2 D2 D4 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], undef, "Unformatted cell $cell"); is ($xls->[1]{$cell}, undef, "Formatted cell $cell"); } my @row = Spreadsheet::Read::rows ($xls->[1]); is (scalar @row, 4, "Row'ed rows"); is (scalar @{$row[3]}, 4, "Row'ed columns"); is ($row[0][3], "D1", "Row'ed value D1"); is ($row[3][2], "C4", "Row'ed value C4"); } # This files is generated under Mac OS/X Tiger ok (1, "XLS File fom Mac OS X"); ok ($xls = ReadDataStream ("files/macosx.xls", clip => 0), "Read/Parse Mac OS X xls file"); ok (1, "Base values"); is ($xls->[0]{sheets}, 3, "Sheet count"); is ($xls->[0]{sheet}{Sheet3}, 3, "Sheet labels"); is ($xls->[1]{maxrow}, 25, "MaxRow"); is ($xls->[1]{maxcol}, 3, "MaxCol"); is ($xls->[2]{label}, "Sheet2", "Sheet label"); is ($xls->[2]{maxrow}, 0, "Empty sheet maxrow"); is ($xls->[2]{maxcol}, 0, "Empty sheet maxcol"); ok (1, "Content"); is ($#{$xls->[1]{cell}[3]}, $xls->[1]{maxrow}, "cell structure"); ok (defined $xls->[1]{cell}[$xls->[1]{maxcol}][$xls->[1]{maxrow}], "last cell"); foreach my $x (1 .. 17) { my $cell = cr2cell (1, $x); is ($xls->[1]{$cell}, $x, "Cell $cell"); is ($xls->[1]{cell}[1][$x], $x, "Cell 1, $x"); } foreach my $x (1 .. 25) { my $cell = cr2cell (3, $x); is ($xls->[1]{$cell}, $x, "Cell $cell"); is ($xls->[1]{cell}[3][$x], $x, "Cell 3, $x"); } foreach my $cell (qw( A18 B1 B6 B20 C26 D14 )) { my ($c, $r) = cell2cr ($cell); is ($xls->[1]{cell}[$c][$r], undef, "Cell $cell"); is ($xls->[1]{$cell}, undef, "Cell $c, $r"); } eval { eval "use ".$parser."::FmtDefault"; my ($pm) = map { $INC{$_} } grep m{FmtDefault.pm$}i => keys %INC; if (open my $ph, "<", $pm) { my $l; $l = <$ph> for 1 .. 68; close $ph; if ($l =~ m/'C\*'/) { print STDERR "\n", "# If the next tests give warnings like\n", "# Character in 'C' format wrapped in pack at\n", "# $pm line 68\n", "# Change C* to U* in line 68\n", "# patch -p0 ; s/\bPM\b/$pm/ for @patch; open $ph, ">", "SPE68.diff" or die "SPE68.diff: $!\n"; print $ph @patch; close $ph; } } }; # Tests for empty thingies ok ($xls = ReadDataStream ("files/values.xls"), "True/False values"); ok (my $ss = $xls->[1], "first sheet"); is ($ss->{cell}[1][1], "A1", "unformatted plain text"); is ($ss->{cell}[2][1], " ", "unformatted space"); is ($ss->{cell}[3][1], undef, "unformatted empty"); is ($ss->{cell}[4][1], "0", "unformatted numeric 0"); is ($ss->{cell}[5][1], "1", "unformatted numeric 1"); is ($ss->{cell}[6][1], "", "unformatted a single '"); is ($ss->{A1}, "A1", "formatted plain text"); is ($ss->{B1}, " ", "formatted space"); is ($ss->{C1}, undef, "formatted empty"); is ($ss->{D1}, "0", "formatted numeric 0"); is ($ss->{E1}, "1", "formatted numeric 1"); is ($ss->{F1}, "", "formatted a single '"); __END__ --- PM 2005-09-15 14:16:36.163623616 +0200 +++ PM 2005-09-15 14:11:56.289171000 +0200 @@ -65,7 +65,7 @@ sub new($;%) { sub TextFmt($$;$) { my($oThis, $sTxt, $sCode) =@_; return $sTxt if((! defined($sCode)) || ($sCode eq '_native_')); - return pack('C*', unpack('n*', $sTxt)); + return pack('U*', unpack('n*', $sTxt)); } #------------------------------------------------------------------------------ # FmtStringDef (for Spreadsheet::ParseExcel::FmtDefault) Spreadsheet-Read-0.41/t/63_misc.t0000644000031300001440000000127311163713166015656 0ustar merijnusers#!/usr/bin/perl use strict; use warnings; my $tests = 2; use Test::More; require Test::NoWarnings; use Spreadsheet::Read; Spreadsheet::Read::parses ("xlsx") or plan skip_all => "No M\$-Excel parser found"; my $xls; { local *STDERR; # We want the debug activated, but not shown open STDERR, ">", "/dev/null" or die "/dev/null: $!\n"; $xls = ReadData ("files/misc.xlsx", # All defaults reversed rc => 0, cells => 0, attr => 1, clip => 1, debug => 5, ); } ok ($xls, "Open with options"); is ($xls->[0]{sheets}, 3, "Sheet Count"); unless ($ENV{AUTOMATED_TESTING}) { Test::NoWarnings::had_no_warnings (); $tests++; } done_testing ($tests); Spreadsheet-Read-0.41/t/01_pod.t0000644000031300001440000000034410313243044015460 0ustar merijnusers#!/usr/bin/perl use Test::More; eval "use Test::Pod::Coverage tests => 1"; plan skip_all => "Test::Pod::Covarage required for testing POD Coverage" if $@; pod_coverage_ok ("Spreadsheet::Read", "Spreadsheet::Read is covered"); Spreadsheet-Read-0.41/Changes0000644000031300001440000001747211453133166015264 0ustar merijnusersRevision history for Spreadsheet::Read 0.41 Wed 06 Oct 2010 - Spell-check - Fixed requiring optional modules (RT#61928 - Roderick Schupp) 0.40 Wed 31 Mar 2010 - Default option for clip fixed (RT#56151 - Alan James) 0.39 Tue 16 Mar 2010 - Doc fix (RT#54507, Patrick Cronin) - Upped Copyright notices to 2010 - Drop YAML version to 1.0 0.38 Tue 15 Dec 2009 - Add row () and cellrow () - Updated META.yml to meet most recent specs (optional_features = map) 0.37 Mon 09 Nov 2009 - IO streams improvements - MANIFEST fix 0.36 Thu 06 Nov 2009 - Add strip option - Spreadsheet::XLSX 0.12 still does not support attributes - Require Text::CSV_XS-0.69 for CSV for auto-detection of \r - New attribute "parser" to force format - Allow CSV streams - Allow SC streams - Allow XLS streams 0.35 Wed 03 Jun 2009 - Add Test::NoWarnings, which is not run in AUTOMATED_TESTING - Switched to Test::More using tests_done () - Text::CSV_XS requires 0.43 or up, as we use ->eof () still prefer a really new release, like 0.65, which is Test::NoWarnings safe - Spreadsheet::XLSX 0.10 still does not support attributes - Added -n to xlscat - XLSX tests skip on feature, not on version 0.34 Tue 27 Jan 2009 - Spreadsheet::XLSX 0.09 still does not support attributes still think it is better to follow closely. 0.09 is much better than 0.08 0.33 Fri 23 Jan 2009 - A few Perl::Critic inspired changes - Modified tests to prevent rounding errors (we were not checking for that) - Added examples/ss-dups-tk.pl 0.32 Tue 06 Jan 2009 - Add basic support for M$ Excel 2007 using Spreadsheet::XLSX - Test suite reports the parsers it found 0.31 Sun 04 Jan 2009 - Upped Copyright notices to 2009 - Detection of percentage type - Even more reliable detection of Date types 0.30 Mon 22 Dec 2008 - Wrong e-mail in META.yml - CSV files from a Mac, with \r as eol, would not parse 0.29 Sun 19 Oct 2008 - Make Read safer for files that do not match extension, like HTML in foo.xls - YAML declared 1.4 (META.yml) instead of 1.1 (YAML) - Bring Makefile.PL in sync with META.yml - Recommend Text-CSV-0.56 0.28 Wed 04 Sep 2008 - More tests on date formats - Declare Spreadsheet::ParseExcel::FmtDefault in META.yml - Add 'size' from Excel font size - Update docs about Excel quirks and CPAN links - Reference to public git repo - Some typo's 0.27 Sun 31 Aug 2008 - Fixed META.yml (the specs are inconsistent) - Added --dtfmt to xlscat 0.26 Fri 29 Aug 2008 - Added examples/xls2csv - Upped copyright to 2008 in examples - Don't ask to install examples under automated testing - die => croak - Added tgzdist target - Added encoding options to examples/xlscat - Added date-type checks for SS:PE > 0.32 0.25 Wed 02 Jan 2008 - Spreadsheet-Read now under git - Upped copyrights to 2008 - Added all prereq's to Makefile.PL, even core mods - Tested under perl-5.10.0 - Text::CSV as of 1.00 is OK 0.24 Thu 05 Oct 2007 - -? and --help in utils moved to Getopt::Long - Adjusted copyright notice in utils - removed prototypes in utils - next is illegal in do {} while (); (Johan Vromans) only happens with old Text::CSV_XS 0.23 Thu 21 Jun 2007 - Use IO::Scalar instead of File::Temp when installed Thanks to David Cantrell for making a OpenBSD test box available! - use binmode () when opening files - Also use 3-arg open in test files - die if test files cannot be opene'ed 0.22 Mon 18 Jun 2007 - 0.21 should already support Text::CSV_PP 1.05 Tested Text::CSV_PP 1.05 on bleadperl. - Better detection of (not) installed modules - Module requires perl 5.6.x 0.21 Mon 18 Jun 2007 - Text::CSV_XS uses keep_meta_info instead of get_flags - Removed always_quote from xlscat's CSV output 0.20 Thu 31 May 2007 - perlcritic OK - CSV parsing now uses getline (), and auto-detects eol Assumes first line does not contain embedded eol. This implies that parsing CSV with embedded eol sequences is now safe. - As I now also maintain Text::CSV_XS, I changed the references - Changed TODO's from Text::CSV to Text::CSV_PP (::CSV is dated 1997) 0.19 Fri 04 May 2007 - Could not retreive '0' fields from OpenOffice (Jim Kelly) 0.18 Fri 27 Apr 2007 - use strict in Makefile.PL - Added test_cover make target - Added "ods" for OpenOffice conversions - Added color tests for ods (but SR::RS doesn't support that yet) - Switched from \d to 0-9 in regexp - Added more test files and tests (increase coverage) 0.17 Tue 04 Jul 2006 - xlscat new option: --ansii to (try to) use the ansi colors for fields - Fixed a color attribute off-by-one error - Added test cases (not yet complete) - Added bold and underline 0.16 Tue 04 Jul 2006 - xlscat new option: --in-sep-char to force-define input sep-char for CSV - More debug lines - Parser name info in $ref->[0] - SquirrelCalc now reports Spreadsheet::Read and its version for parser info - Most of the attributes for Excel now implemented. Tested, but no test case 0.15 Wed 21 Jun 2006 - Small doc change from AnnoCPAN - Sheets with undefined labels might cause havoc - Clip now skips empty xls sheets (TODO: sxc) - xlscat clips by default - xlscat new options -d and --noclip - xlscat usage () from -?/--help to STDOUT from fault to STDERR 0.14 Fri 20 Jan 2006 - maxrow and maxcol were swapped in csv sheets - promoted internal debug flag to option - small doc changes 0.13 Thu 04 Nov 2005 - Control attrib 'cells' was misinterpreted - New option: clip, default is true if {cell} is selected, false otherwise Removes trailing lines and columns in each sheet that have no visible data - new test t/11_call.t for checking options. Not complete yet - Added test_cover target to Makefile.PL 0.12 Mon 31 Oct 2005 - Added ss2tk to examples 0.11 Wed 26 Oct 2005 - Allow ods (OpenOffice 2.0) for sxc - include real ods test files and new test - Check if sc.version is undef, not 0 0.10 Mon 19 Sep 2005 - More test coverage - cr2cell () returns "" for illegal col/row values - cell2cr () returns (0, 0) for illegal cell values - rows () tests even better for valid reference pointer - Renamed the test files 0.09 Sun 18 Sep 2005 - Added Test::Pod - Added Test::Pod::Coverage - Spreadsheet::ReadSXC 0.20 now required (too many tests fail on 0.12) - Small changes to the docs - More secure handling of false values - Mention a bug in Spreadsheet::ParseExcel 0.08 Mon 22 Aug 2005 - Slightly changed the Synopsis 0.07 Wed 06 Jul 2005 - Added function rows () - Added function parses () - Made all modules optional - Prepared for Spreadsheet::Perl - Doc updates 0.06 Wed 22 Jun 2005 - Repaired error in label names in metadata for SXC 0.05 Thu 17 Jun 2005 - Spreadsheet::ReadSXC >= 0.20 supports sheet order - Spreadsheet::ReadSXC has new data structure (we still support the old) - Added "version" to the meta data for parser version - More tests 0.04 Tue 14 Jun 2005 - Changed TODO - Added options "rc", and "cell" - Added CSV - Added CSV options "sep", and "quote" - Support xls from content - Added basic support for SquirrelCalc format - Updated pod - xlscat -R option for row selection was a one-off - xlscat now supports selecting fields with -F 0.03 Thu 19 May 2005 - Expanded xlscat to support -i for index - Optionally install xlscat 0.02 Thu 19 May 2005 - Typoes in the doc - Small change in organization so it actually installs 0.01 Thu 12 May 2005 - Initial CPAN version. A lot can still change Spreadsheet-Read-0.41/examples/0000755000031300001440000000000011453657405015603 5ustar merijnusersSpreadsheet-Read-0.41/examples/ss-dups-tk.pl0000755000031300001440000001653611136426161020157 0ustar merijnusers#!/pro/bin/perl use strict; use warnings; sub usage { my $err = shift and select STDERR; print "usage: $0 [-t] [-S ] [-R ] [-C columns] [-F ]\n", "\t-t Only check on true values\n", "\t-S sheets Check sheet(s). Defaul = 1, 1,3-5,all\n", "\t-R rows Check row(s). Defaul = all, 6,19-66\n", "\t-C columns Check column(s). Defaul = all, 2,5-9\n", "\t-F fields Check field(s). Defaul = all, A1,A2,B15,C23\n"; exit $err; } # usage use Spreadsheet::Read; use Getopt::Long qw(:config bundling nopermute noignorecase); my $opt_v = 0; my $opt_t = 0; # Only check on true values my @opt_S; # Sheets to print my @opt_R; # Rows to print my @opt_C; # Columns to print my @opt_F; GetOptions ( "help|?" => sub { usage (0); }, "S|sheets=s" => \@opt_S, "R|rows=s" => \@opt_R, "C|columns=s" => \@opt_C, "F|fields=s" => \@opt_F, "t|true" => \$opt_t, "v|verbose:1" => \$opt_v, ) or usage (1); @opt_S or @opt_S = (1); use Tk; use Tk::ROText; my $file = shift || (sort { -M $b <=> -M $a } glob "*.xls")[0]; my ($mw, $is, $ss, $dt) = (MainWindow->new, "1.0"); sub ReadFile { $file or return; $dt->delete ("1.0", "end"); unless ($ss = ReadData ($file)) { $dt->insert ("end", "Cannot read $file as spreadsheet\n"); return; } my @ss = map { qq{"$ss->[$_]{label}"} } 1 .. $ss->[0]{sheets}; my @finfo = ( "File: $file", ( map { "Sheet $_: '$ss->[$_]{label}'\t($ss->[$_]{maxcol} x $ss->[$_]{maxrow})" } 1 .. $ss->[0]{sheets} ), "=============================================================="); $dt->insert ("end", join "\n", @finfo, ""); $is = (@finfo + 1).".0"; return $ss; } # ReadFile my $tf = $mw->Frame ()->pack (qw( -side top -anchor nw -expand 1 -fill both )); $tf->Entry ( -textvariable => \$file, -width => 40, -vcmd => \&ReadFile, )->pack (qw(-side left -expand 1 -fill both)); my %ftyp; for ([ xls => [ "Excel Files", [qw( .xls .XLS )] ] ], [ xlsx => [ "Excel Files", [qw( .xlsx .XLSX )] ] ], [ sxc => [ "OpenOffice Files", [qw( .sxc .SXC )] ] ], [ ods => [ "OpenOffice Files", [qw( .ods .ODS )] ] ], [ csv => [ "CSV Files", [qw( .csv .CSV )] ] ], ) { my ($ft, $r) = @$_; Spreadsheet::Read::parses ($ft) or next; push @{$ftyp{$r->[0]}}, @{$r->[1]}; push @{$ftyp{"All spreadsheet types"}}, @{$r->[1]}; } $tf->Button ( -text => "Select file", -command => sub { $ss = undef; $file = $mw->getOpenFile ( -filetypes => [ ( map { [ $_, $ftyp{$_} ] } sort keys %ftyp ), [ "All files", "*" ], ], ); ReadFile (); }, )->pack (qw(-side left -expand 1 -fill both)); $tf->Button ( -text => "Detect", -command => \&Detect, )->pack (qw(-side left -expand 1 -fill both)); $tf->Button ( -text => "Show", -command => \&Show, )->pack (qw(-side left -expand 1 -fill both)); $tf->Button ( -text => "Exit", -command => \&exit, )->pack (qw(-side left -expand 1 -fill both)); my $mf = $mw->Frame ()->pack (qw( -side top -anchor nw -expand 1 -fill both )); my $sw = $mf->Scrolled ("ROText", -scrollbars => "osoe", -height => 40, -width => 85, -foreground => "Black", -background => "White", -highlightthickness => 0, -setgrid => 1)->pack (qw(-expand 1 -fill both)); $dt = $sw->Subwidget ("scrolled"); #$sw->Subwidget ("xscrollbar")->packForget; $dt->configure ( -wrap => "none", -font => "mono 12", ); my $bf = $mw->Frame ()->pack (qw( -side top -anchor nw -expand 1 -fill both )); $bf->Checkbutton ( -variable => \$opt_t, -text => "True values only", )->pack (qw(-side left -expand 1 -fill both)); { my $opt_S = @opt_S ? join ",", @opt_S : 1; $bf->Label ( -text => "Sheet(s)", )->pack (qw(-side left -expand 1 -fill both)); $bf->Entry ( -textvariable => \$opt_S, -width => 10, -validate => "focusout", -vcmd => sub { @opt_S = grep m/\S/, split m/\s*,\s*/ => $opt_S; 1; }, )->pack (qw(-side left -expand 1 -fill both)); } { my $opt_R = join ",", @opt_R; $bf->Label ( -text => "Rows(s)", )->pack (qw(-side left -expand 1 -fill both)); $bf->Entry ( -textvariable => \$opt_R, -width => 10, -validate => "focusout", -vcmd => sub { @opt_R = grep m/\S/, split m/\s*,\s*/ => $opt_R; 1; }, )->pack (qw(-side left -expand 1 -fill both)); } { my $opt_C = join ",", @opt_C; $bf->Label ( -text => "Columns(s)", )->pack (qw(-side left -expand 1 -fill both)); $bf->Entry ( -textvariable => \$opt_C, -width => 10, -validate => "focusout", -vcmd => sub { @opt_C = grep m/\S/, split m/\s*,\s*/ => $opt_C; 1; }, )->pack (qw(-side left -expand 1 -fill both)); } sub ranges (@) { my @g; foreach my $arg (@_) { for (split m/,/, $arg) { if (m/^(\w+)\.\.(\w+)$/) { my ($s, $e) = ($1, $2); $s =~ m/^[1-9]\d*$/ or ($s, $e) = (qq("$s"), qq("$e")); eval "push \@g, $s .. $e"; } else { push @g, $_; } } } $opt_v and print STDERR "( @g )\n"; @g; } # ranges sub Detect { $ss or ReadFile (); $dt->delete ($is, "end"); $dt->insert ("end", join "\n", "", "Shts: @opt_S", "Rows: @opt_R", "Cols: @opt_C", "--------------------------------------------------------------", ""); my %done; my @S = $opt_S[0] eq "all" ? (1 .. $ss->[0]{sheets}) : ranges (@opt_S); my @R = ranges (@opt_R); my @C = ranges (@opt_C); my %f = map { uc $_ => 1 } ("@opt_F" =~ m/(\b[A-Z]\d+\b)/ig); foreach my $s (@S) { my $xls = $ss->[$s] or die "Cannot read sheet $s\n"; my @r = @R ? @R : (1 .. $xls->{maxrow}); my @c = @C ? @C : (1 .. $xls->{maxcol}); foreach my $r (@r) { foreach my $c (@c) { defined $xls->{cell}[$c][$r] or next; my $v = uc $xls->{cell}[$c][$r]; my $cell = cr2cell ($c, $r); @S > 1 and $cell = $xls->{label} . "[$cell]"; $opt_t && !$v and next; @opt_F && !exists $f{$cell} and next; if (exists $done{$v}) { $dt->insert ("end", sprintf "Cell %-5s is dup of %-5s '%s'\n", $cell, $done{$v}, $v); next; } $done{$v} = $cell; } } } } # Detect sub Show { $ss or ReadFile (); $dt->delete ($is, "end"); $dt->insert ("end", join "\n", "", "Shts: @opt_S", "Rows: @opt_R", "Cols: @opt_C"); my @S = $opt_S[0] eq "all" ? (1 .. $ss->[0]{sheets}) : ranges (@opt_S); my @R = ranges (@opt_R); my @C = ranges (@opt_C); my %f = map { uc $_ => 1 } ("@opt_F" =~ m/(\b[A-Z]\d+\b)/ig); foreach my $s (@S) { my $xls = $ss->[$s] or die "Cannot read sheet $s\n"; $dt->insert ("end", "\n--------------------------------------------------------------". "\nSheet $s: '$xls->{label}'\t($xls->{maxcol} x $xls->{maxrow})\n"); my @r = @R ? @R : (1 .. $xls->{maxrow}); my @c = @C ? @C : (1 .. $xls->{maxcol}); $dt->insert ("end", " |"); for (@c) { (my $ch = cr2cell ($_, 1)) =~ s/1$//; $dt->insert ("end", sprintf "%11s |", $ch); } $dt->insert ("end", "\n-----+"); $dt->insert ("end", "------------+") for @c; foreach my $r (@r) { $dt->insert ("end", sprintf "\n%4d |", $r); foreach my $c (@c) { my $cell = cr2cell ($c, $r); my $v = defined $xls->{cell}[$c][$r] ? $xls->{$cell} : "--"; length ($v) < 12 and substr $v, 0, 0, " " x (12 - length $v); $dt->insert ("end", substr ($v, 0, 12). "|"); } } } } # Show MainLoop; Spreadsheet-Read-0.41/examples/xlscat0000755000031300001440000002254511334732464017034 0ustar merijnusers#!/pro/bin/perl # xls2cat: show XLS/SXC file as Text # (m)'09 [13-05-2009] Copyright H.M.Brand 2005-2010 use strict; use warnings; our $VERSION = "1.9"; sub usage { my $err = shift and select STDERR; print "usage: xlscat [-s ] [-L] [-n] [-A] [-u] [ Selection ] file.xls\n", " [-c | -m] [-u] [ Selection ] file.xls\n", " -i [ -S sheets ] file.xls\n", " Generic options:\n", " -v[#] Set verbose level (xlscat)\n", " -d[#] Set debug level (Spreadsheet::Read)\n", " -u Use unformatted values\n", " --noclip Do not strip empty sheets and\n", " trailing empty rows and columns\n", " -e Set encoding for input and output\n", " -b Set encoding for input\n", " -a Set encoding for output\n", " Input CSV:\n", " --in-sep=c Set input sep_char for CSV\n", " Input XLS:\n", " --dtfmt=fmt Specify the default date format to replace 'm-d-yy'\n", " the default replacement is 'yyyy-mm-dd'\n", " Output Text (default):\n", " -s Use separator . Default '|', \\n allowed\n", " -L Line up the columns\n", " -n Number lines (prefix with column number)\n", " -A Show field attributes in ANSI escapes\n", " Output Index only:\n", " -i Show sheet names and size only\n", " Output CSV:\n", " -c Output CSV, separator = ','\n", " -m Output CSV, separator = ';'\n", " Selection:\n", " -S Only print sheets . 'all' is a valid set\n", " Default only prints the first sheet\n", " -R Only print rows . Default is 'all'\n", " -C Only print columns . Default is 'all'\n", " -F Only fields e.g. -FA3,B16\n"; @_ and print join "\n", @_, ""; exit $err; } # usage use Getopt::Long qw(:config bundling nopermute noignorecase); my $opt_c; # Generate CSV my $opt_s; # Text separator my $opt_S; # Sheets to print my $opt_R; # Rows to print my $opt_C; # Columns to print my $dtfmt; # Default date-format for Excel my $opt_F = ""; # Fields to print my $opt_i = 0; # Index my $opt_L = 0; # Auto-size/align columns my $opt_n = 0; # Prefix lines with column number my $opt_u = 0; # Show unformatted values my $opt_v = 0; # Verbosity for xlscat my $opt_d = 0; # Debug level for Spreadsheet::Read my $opt_A = 0; # Show field colors in ANSI escapes my $clip = 1; my $enc_i; # Input encoding my $enc_o; # Output encoding my $sep; # Input field sep for CSV GetOptions ( "help|?" => sub { usage (0); }, # Input CSV "c|csv" => sub { $opt_c = "," }, "m|ms" => sub { $opt_c = ";" }, "insepchar". "|in-sep-char=s" => \$sep, # Input XLS "dtfmt". "|date-format=s" => \$dtfmt, # Output "i|index" => \$opt_i, "s|separator". "|outsepchar". "|out-sep-char=s" => \$opt_s, "S|sheets=s" => \$opt_S, "R|rows=s" => \$opt_R, "C|columns=s" => \$opt_C, "F|fields=s" => \$opt_F, "L|fit|align" => \$opt_L, "n|number" => \$opt_n, "A|ansi" => \$opt_A, "u|unformatted" => \$opt_u, "v|verbose:1" => \$opt_v, "d|debug:1" => \$opt_d, "noclip" => sub { $clip = 0 }, # Encoding "e|encoding=s" => sub { $enc_i = $enc_o = $_[1] }, "b|encoding-in=s" => \$enc_i, "a|encoding-out=s" => \$enc_o, ) or usage 1, "GetOpt: $@"; $opt_i && $opt_L and usage 1, "Options i and L are mutually exclusive"; $opt_i && $opt_s and usage 1, "Options i and s are mutually exclusive"; $opt_i && $opt_c and usage 1, "Options i and c are mutually exclusive"; $opt_i && $opt_u and usage 1, "Options i and u are mutually exclusive"; $opt_i && $opt_S and usage 1, "Options i and S are mutually exclusive"; $opt_i && $opt_R and usage 1, "Options i and R are mutually exclusive"; $opt_i && $opt_C and usage 1, "Options i and C are mutually exclusive"; $opt_i && $opt_F and usage 1, "Options i and F are mutually exclusive"; $opt_c && $opt_s and usage 1, "Options c and s are mutually exclusive"; defined $opt_s or $opt_s = "|"; eval "\$opt_s = qq{$opt_s}"; defined $opt_S or $opt_S = $opt_i ? "all" : "1"; $opt_i && $opt_v < 1 and $opt_v = 1; if ($opt_c) { $opt_L = 0; # Cannot align CSV $opt_c =~ m/^1?$/ and $opt_c = ","; $opt_c = Text::CSV_XS->new ({ binary => 1, sep_char => $opt_c, eol => "\r\n", }); } use Data::Dumper; # I should use Data::Peek instead $Data::Dumper::Sortkeys = 1; $Data::Dumper::Indent = 1; @ARGV or usage 1; my $file = shift; -f $file or usage 1, "the first argument is not a regular file"; -s $file or usage 1, "the file is empty"; use Encode qw( encode decode ); use Spreadsheet::Read; if ($opt_c) { Spreadsheet::Read::parses ("csv") or die "No CSV module found\n"; eval { use Text::CSV_XS }; } my @RDarg = (debug => $opt_d, clip => $clip); $opt_A and push @RDarg, "attr" => 1; defined $sep and push @RDarg, "sep" => $sep; defined $dtfmt and push @RDarg, "dtfmt" => $dtfmt; $opt_v > 4 and print STDERR "ReadData ($file, @RDarg);\n"; my $xls = ReadData ($file, @RDarg) or die "cannot read $file\n"; $opt_v > 7 and print STDERR Dumper ($xls); my $sc = $xls->[0]{sheets} or die "No sheets in $file\n"; $opt_v > 1 and print STDERR "Opened $file with $sc sheets\n"; $opt_S eq "all" and $opt_S = "1..$sc"; # all $opt_S =~ s/-$/-$sc/; # 3,6- $opt_S =~ s/-/../g; my %print; eval "%{\$print{sheet}} = map { \$_ => 1 } $opt_S"; my $v_fmt = $opt_C || $opt_R || $opt_F ? "" : "%6d x %6d%s"; # New style xterm (based on ANSI colors): # 30 Black # 31 Red # 32 Green # 33 Yellow # 34 Blue # 35 Magenta # 36 Cyan # 37 White sub color_reduce { my ($rgb, $base) = @_; defined $rgb or return ""; my ($r, $g, $b) = map { hex >> 7 } ($rgb =~ m/^\s*#?([\da-f]{2})([\da-f]{2})([\da-f]{2})/); $base + 4 * $b + 2 * $g + $r; } # color_reduce sub ansi_color { my ($fg, $bg, $bold, $ul) = @_; #print STDERR "$fg on $bg $bold $ul\n"; my $attr = join ";", 0, grep { /\S/ } $bold ? 1 : "", $ul ? 4 : "", color_reduce ($fg, 30), color_reduce ($bg, 40); "\e[${attr}m"; } # ansi_color binmode STDERR, ":utf8"; $enc_o and binmode STDOUT, ":encoding($enc_o)"; my $name_len = 30; if ($opt_i) { my $nl = 0; foreach my $sn (keys %{$xls->[0]{sheet}}) { length ($sn) > $nl and $nl = length $sn; } $nl and $name_len = $nl; } my @opt_F = split m/[^A-Z\d]+/ => $opt_F; foreach my $si (1 .. $sc) { my @data; exists $print{sheet}{$si} or next; $opt_v > 1 and print STDERR "Opening sheet $si ...\n"; my $s = $xls->[$si] or next; $opt_v > 5 and print STDERR Dumper ($s); my @r = (1, $s->{maxrow}); my @c = (1, $s->{maxcol}); my ($sn, $nr, $nc) = ($s->{label}, $r[-1], $c[-1]); $opt_v and printf STDERR "%s - %02d: [ %-*s ] %3d Cols, %5d Rows\n", $file, $si, $name_len, $sn, $nc, $nr; $opt_i and next; if (@opt_F) { foreach my $fld (@opt_F) { print "$fld:",$s->{$fld},"\n"; } next; } if (my $rows = $opt_R) { $rows eq "all" and $rows = "1..$nr"; # all $rows =~ s/-$/-$nr/; # 3,6- $rows =~ s/-/../g; eval "%{\$print{row}} = map { \$_ => 1 } $rows"; } if (my $cols = $opt_C) { $cols eq "all" and $cols = "1..$nc"; # all $cols =~ s/-$/-$nc/; # 3,6- $cols =~ s/-/../g; eval "\$print{col} = [ map { \$_ - 1 } $cols ]"; $nc = @{$print{col}}; } $opt_v >= 8 and print Dumper (\%print); my $undef = $opt_v > 2 ? "-- undef --" : ""; my ($h, @w) = (0, (0) x $nc); # data height, -width, and default column widths my @align = ("") x $nc; foreach my $r ($r[0] .. $r[1]) { exists $print{row} && !exists $print{row}{$r} and next; my @att; my @row = map { my $cell = cr2cell ($_, $r); my ($uval, $fval) = map { defined $_ ? $enc_i ? decode ($enc_i, $_) : $_ : $undef } $s->{cell}[$_][$r], $s->{$cell}; $opt_v > 2 and print STDERR "$_:$r '$uval' / '$fval'\n"; $opt_A and push @att, [ @{$s->{attr}[$_][$r]}{qw( fgcolor bgcolor bold uline )} ]; defined $s->{cell}[$_][$r] ? $opt_u ? $uval : $fval : ""; } $c[0] .. $c[1]; exists $print{col} and @row = @row[@{$print{col}}]; if ($opt_L) { foreach my $c (0 .. $#row) { my $l = length $row[$c]; $l > $w[$c] and $w[$c] = $l; $row[$c] =~ m/\D/ and $align[$c] = "-"; } } if ($opt_c) { # CSV if ($enc_o) { $_ = encode ($enc_o, $_) for @row; } $opt_c->print (*STDOUT, \@row) or die $opt_c->error_diag; next; } if ($opt_n) { unshift @row, $r; unshift @att, [ "#ffffff", "#000000", 0, 0 ]; } if ($opt_L) { # Autofit / Align push @data, [ [ @row ], [ @att ] ]; next; } if ($opt_A) { foreach my $c (0 .. $#row) { $row[$c] = ansi_color (@{$att[$c]}). $row[$c] . "\e[0m"; } } print join ($opt_s => @row), "\n"; } continue { ++$h % 100 or printf STDERR $v_fmt, $nc, $h, "\r"; } printf STDERR $v_fmt, $nc, $h, "\n"; $opt_L or next; if ($opt_n) { unshift @w, length $data[-1][0][0]; unshift @align, ""; } my $fmt = join ($opt_s => map { my $f = "%$align[$_]$w[$_]s"; $opt_A ? "%s$f%s" : $f } 0 .. $#w)."\n"; for (@data) { my ($row, $att) = @$_; my @row = $opt_A ? map { ( ansi_color (@{$att->[$_]}), $row->[$_], "\e[0m" ) } 0 .. $#$row : @$row; printf $fmt, @row; } } Spreadsheet-Read-0.41/examples/ss2tk0000755000031300001440000000773611334732455016611 0ustar merijnusers#!/pro/bin/perl # ss2tk: show SpreadSheet file in Tk::TableMatrix::Spreadsheet (*) # (m)'07 [26-06-2007] Copyright H.M.Brand 2005-2010 use strict; use warnings; our $VERSION = "2.1"; sub usage { my $err = shift and select STDERR; print "usage: ss2tk [-w ] [X11 options] file.xls []\n", " -w use as default column width (4)\n"; exit $err; } # usage use Getopt::Long qw(:config bundling nopermute passthrough); my $wdt = 4; # Default minimal column width my $unq = 0; # Uniq columns only GetOptions ( "help|?" => sub { usage (0); }, "w=i" => \$wdt, "u" => \$unq, ) or usage (1); use Tk; use Tk::NoteBook; use Tk::TableMatrix::Spreadsheet; # This will allow ~/.Xdefaults to have lines like #ss2tk*font: -misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1 Tk::CmdLine->LoadResources (); # This will allow calls like # ss2tk -fg Blue4 blah.csv Tk::CmdLine->SetArguments (); @ARGV && -f $ARGV[0] or usage (1); my $title = $ARGV[0]; my %unq; use Spreadsheet::Read; my $ref = ReadData (shift) or die "Cannot read $title\n"; $ref->[0]{sheets} or die "No sheets in $title\n"; my $mw = MainWindow->new (-title => $title); my $nb = $mw->NoteBook ()->pack (qw(-side top -expand 1 -fill both )); my @nb; foreach my $sht (1 .. $ref->[0]{sheets}) { my $s = $ref->[$sht]; $title .= " [ " . $s->{label} . " ]"; my $pat = @ARGV ? qr/$ARGV[0]/i : undef; my ($data, @data); my @c = (1, $s->{maxcol}); my ($h, $w, @w) = (0, 1, 0, (0) x $c[1]); # data height, -width, and default column widths foreach my $r (1 .. $s->{maxrow}) { my @row = map { defined $s->{cell}[$_][$r] ? $s->{cell}[$_][$r] : ""; } 1 .. $s->{maxcol}; $pat and "@row" =~ $pat || next; foreach my $c (0 .. $#row) { $row[$c] or next; $c >= $w and $w = $c + 1; $data->{"$h,$c"} = $row[$c]; push @data, "$h,$c"; my $l = length $row[$c]; $l > $w[$c] and $w[$c] = $l; } ++$h % 100 or printf STDERR "%6d x %6d\r", $w, $h; } printf STDERR "%6d x %6d\n", $w, $h; $nb[$sht] = $nb->add ($sht, -label => $s->{label}, -state => "normal", -anchor => "nw"); my $ss = $nb[$sht]->Scrolled ('Spreadsheet', -rows => $h, -cols => $w, -width => 10, -height => 20, -titlerows => 1, -titlecols => 0, -selectmode => "extended", -resizeborders => "both", -justify => "left", -anchor => "w", -variable => $data, )->pack (-expand => 1, -fill => "both", -side => "top", -anchor => "nw"); $ss->Subwidget ("${_}scrollbar")->configure (-width => 6) for qw( x y ); $ss->tagConfigure ("title", -bg => "#ffffe0", -justify => "left"); $ss->tagConfigure ("active", -bg => "#ffff40", -justify => "left"); $ss->tagConfigure ("sel", -bg => "gray95", -justify => "left"); my ($pv, $sv, $si) = ("", "", 0); sub search { $sv or return; $sv eq $pv && !$_[0] and return; $ss->selectionClear ("all"); foreach my $i ($_[0] .. $#data, 0 .. ($_[0] - 1)) { $data->{$data[$i]} =~ m/$sv/i or next; $si = $i; $ss->activate ($data[$si = $i]); $ss->selectionSet ($data[$si]); $ss->see ($data[$si]); $pv = $sv; last; } } # search # Search frame my $sf = $nb[$sht]->Frame ()->pack (-side => "left", -expand => 1, -fill => "both"); my $sl = $sf->Label ( -text => "Search", )->pack (-side => "left", -anchor => "sw"); my $sb = $sf->Entry ( -textvariable => \$sv, )->pack (-side => "left", -anchor => "sw"); $sb->bind ("" => sub { search ($si = 0); }); my $sn = $sf->Button ( -text => "Next", -command => sub { search (++$si) }, )->pack (-side => "left", -anchor => "sw"); # Control frame my $cf = $nb[$sht]->Frame ()->pack (-side => "right", -expand => 1, -fill => "both"); my $ce = $cf->Button ( -text => "Exit", -command => \&exit, )->pack (-side => "right", -anchor => "se"); # autosize columns on data (not on headers) $ss->colWidth (map { $_ => $w[$_] } 0 .. $#w); } MainLoop; Spreadsheet-Read-0.41/examples/xls2csv0000755000031300001440000000156111334732460017131 0ustar merijnusers#!/pro/bin/perl # xls2csv: Convert Microsoft Excel spreadsheet to CSV # (m)'08 [10-03-2008] Copyright H.M.Brand 2008-2010 use strict; use warnings; sub usage { my $err = shift and select STDERR; print "usage: $0 [ -o file.csv ] file.xls\n"; @_ and print join "\n", @_, ""; exit $err; } # usage use Getopt::Long qw( :config bundling nopermute passthrough ); my $csv; my $opt_f; GetOptions ( "help|?" => sub { usage 1; }, "o|c=s" => \$csv, "f" => \$opt_f, ) or usage 1; my $xls = shift or usage 1, "No input file"; -r $xls or usage 1, "Input file unreadable"; -s $xls or usage 1, "Input file empty"; $csv or ($csv = $xls) =~ s/\.xls$/.csv/i; if (-f $csv) { $opt_f or die "$csv already exists\n"; unlink $csv; } print STDERR "Converting $xls to $csv ...\n"; open STDOUT, ">", $csv; exec "xlscat", "-c", $xls; Spreadsheet-Read-0.41/META.yml0000644000031300001440000000417711453657405015247 0ustar merijnusers--- #YAML:1.0 name: Read version: 0.41 abstract: Meta-Wrapper for reading spreadsheet data license: perl author: - H.Merijn Brand generated_by: Author distribution_type: module provides: Spreadsheet::Read: file: Read.pm version: 0.41 requires: perl: 5.006 Exporter: 0 Carp: 0 Data::Dumper: 0 configure_requires: ExtUtils::MakeMaker: 0 build_requires: perl: 5.006 Test::Harness: 0 Test::More: 0.88 Test::NoWarnings: 0 recommends: perl: 5.010001 File::Temp: 0.22 IO::Scalar: 0 Test::More: 0.96 resources: license: http://dev.perl.org/licenses/ repository: http://repo.or.cz/w/Spreadsheet-Read.git meta-spec: version: 1.4 url: http://module-build.sourceforge.net/META-spec-v1.4.html optional_features: opt_csv: description: Provides parsing of CSV streams requires: Text::CSV_XS: 0.69 recommends: Text::CSV: 1.19 Text::CSV_PP: 1.27 Text::CSV_XS: 0.75 opt_excel: description: Provides parsing of Microsoft Excel files requires: Spreadsheet::ParseExcel: 0.26 Spreadsheet::ParseExcel::FmtDefault: 0 recommends: Spreadsheet::ParseExcel: 0.58 opt_excelx: description: Provides parsing of Microsoft Excel 2007 files requires: Spreadsheet::XLSX: 0.13 Spreadsheet::XLSX::Fmt2007: 0 opt_oo: description: Provides parsing of OpenOffice spreadsheets requires: Spreadsheet::ReadSXC: 0.20 opt_tools: description: Spreadsheet tools recommends: Tk: 0 Tk::NoteBook: 0 Tk::TableMatrix::Spreadsheet: 0 Spreadsheet-Read-0.41/Read.pm0000755000031300001440000007051111453133222015167 0ustar merijnusers#!/pro/bin/perl package Spreadsheet::Read; =head1 NAME Spreadsheet::Read - Read the data from a spreadsheet =head1 SYNOPSIS use Spreadsheet::Read; my $ref = ReadData ("test.csv", sep => ";"); my $ref = ReadData ("test.sxc"); my $ref = ReadData ("test.ods"); my $ref = ReadData ("test.xls"); my $ref = ReadData ("test.xlsx"); my $ref = ReadData ($fh, parser => "xls"); my $a3 = $ref->[1]{A3}, "\n"; # content of field A3 of sheet 1 =cut use strict; use warnings; our $VERSION = "0.41"; sub Version { $VERSION } use Carp; use Exporter; our @ISA = qw( Exporter ); our @EXPORT = qw( ReadData cell2cr cr2cell ); our @EXPORT_OK = qw( parses rows cellrow row ); use File::Temp qw( ); use Data::Dumper; my @parsers = ( [ csv => "Text::CSV_XS" ], [ csv => "Text::CSV_PP" ], # Version 1.05 and up [ csv => "Text::CSV" ], # Version 1.00 and up [ ods => "Spreadsheet::ReadSXC" ], [ sxc => "Spreadsheet::ReadSXC" ], [ xls => "Spreadsheet::ParseExcel" ], [ xlsx => "Spreadsheet::XLSX" ], [ prl => "Spreadsheet::Perl" ], # Helper modules [ ios => "IO::Scalar" ], ); my %can = map { $_->[0] => 0 } @parsers; for (@parsers) { my ($flag, $mod) = @$_; $can{$flag} and next; eval "require $mod; \$can{\$flag} = '$mod'"; } $can{sc} = __PACKAGE__; # SquirelCalc is built-in my $debug = 0; my @def_attr = ( type => "text", fgcolor => undef, bgcolor => undef, font => undef, size => undef, format => undef, halign => "left", valign => "top", bold => 0, italic => 0, uline => 0, wrap => 0, merged => 0, hidden => 0, locked => 0, enc => "utf-8", # $ENV{LC_ALL} // $ENV{LANG} // ... ); # Helper functions sub _parser { my $type = shift or return ""; $type = lc $type; # Aliases and fullnames $type eq "excel" and return "xls"; $type eq "excel2007" and return "xlsx"; $type eq "oo" and return "sxc"; $type eq "ods" and return "sxc"; $type eq "openoffice" and return "sxc"; $type eq "perl" and return "prl"; $type eq "squirelcalc" and return "sc"; return exists $can{$type} ? $type : ""; } # _parser # Spreadsheet::Read::parses ("csv") or die "Cannot parse CSV" sub parses { my $type = _parser (shift) or return 0; return $can{$type}; } # parses # cr2cell (4, 18) => "D18" # No prototype to allow 'cr2cell (@rowcol)' sub cr2cell { my ($c, $r) = @_; defined $c && defined $r && $c > 0 && $r > 0 or return ""; my $cell = ""; while ($c) { use integer; substr $cell, 0, 0, chr (--$c % 26 + ord "A"); $c /= 26; } "$cell$r"; } # cr2cell # cell2cr ("D18") => (4, 18) sub cell2cr { my ($cc, $r) = (uc ($_[0]||"") =~ m/^([A-Z]+)([0-9]+)$/) or return (0, 0); my $c = 0; while ($cc =~ s/^([A-Z])//) { $c = 26 * $c + 1 + ord ($1) - ord ("A"); } ($c, $r); } # cell2cr # my @row = cellrow ($ss->[1], 1); sub cellrow { my $sheet = shift or return; ref $sheet eq "HASH" && exists $sheet->{cell} or return; exists $sheet->{maxcol} && exists $sheet->{maxrow} or return; my $row = shift or return; $row > 0 && $row <= $sheet->{maxrow} or return; my $s = $sheet->{cell}; map { $s->[$_][$row] } 1..$sheet->{maxcol}; } # cellrow # my @row = row ($ss->[1], 1); sub row { my $sheet = shift or return; ref $sheet eq "HASH" && exists $sheet->{cell} or return; exists $sheet->{maxcol} && exists $sheet->{maxrow} or return; my $row = shift or return; $row > 0 && $row <= $sheet->{maxrow} or return; map { $sheet->{cr2cell ($_, $row)} } 1..$sheet->{maxcol}; } # row # Convert {cell}'s [column][row] to a [row][column] list # my @rows = rows ($ss->[1]); sub rows { my $sheet = shift or return; ref $sheet eq "HASH" && exists $sheet->{cell} or return; exists $sheet->{maxcol} && exists $sheet->{maxrow} or return; my $s = $sheet->{cell}; map { my $r = $_; [ map { $s->[$_][$r] } 1..$sheet->{maxcol} ]; } 1..$sheet->{maxrow}; } # rows # If option "clip" is set, remove the trailing lines and # columns in each sheet that contain no visible data sub _clipsheets { my ($opt, $ref) = @_; if (my $s = $opt->{strip}) { foreach my $sheet (1 .. $ref->[0]{sheets}) { my $ss = $ref->[$sheet]; foreach my $row (1 .. $ss->{maxrow}) { foreach my $col (1 .. $ss->{maxcol}) { defined $ss->{cell}[$col][$row] or next; $s & 2 && $ss->{cell}[$col][$row] =~ s/\s+$// and $ss->{cr2cell ($col, $row)} =~ s/\s+$//; $s & 1 && $ss->{cell}[$col][$row] =~ s/^\s+// and $ss->{cr2cell ($col, $row)} =~ s/^\s+//; } } } } $opt->{clip} or return $ref; foreach my $sheet (1 .. $ref->[0]{sheets}) { my $ss = $ref->[$sheet]; # Remove trailing empty columns while ($ss->{maxcol} and not ( grep { defined && m/\S/ } @{$ss->{cell}[$ss->{maxcol}]}) ) { (my $col = cr2cell ($ss->{maxcol}, 1)) =~ s/1$//; my $recol = qr{^$col(?=[0-9]+)$}; delete $ss->{$_} for grep m/$recol/, keys %{$ss}; $ss->{maxcol}--; } $ss->{maxcol} or $ss->{maxrow} = 0; # Remove trailing empty lines while ($ss->{maxrow} and not ( grep { defined && m/\S/ } map { $ss->{cell}[$_][$ss->{maxrow}] } 1 .. $ss->{maxcol} )) { my $rerow = qr{^[A-Z]+$ss->{maxrow}$}; delete $ss->{$_} for grep m/$rerow/, keys %{$ss}; $ss->{maxrow}--; } $ss->{maxrow} or $ss->{maxcol} = 0; } $ref; } # _clipsheets sub _xls_color { my ($clr, @clr) = @_; defined $clr or return undef; @clr == 0 && $clr == 32767 and return undef; # Default fg color @clr == 2 && $clr == 0 and return undef; # No fill bg color @clr == 2 && $clr == 1 and ($clr, @clr) = ($clr[0]); @clr and return undef; # Don't know what to do with this "#" . lc Spreadsheet::ParseExcel->ColorIdxToRGB ($clr); } # _xls_color sub ReadData { my $txt = shift or return; my %opt; if (@_) { if (ref $_[0] eq "HASH") { %opt = %{shift @_} } elsif (@_ % 2 == 0) { %opt = @_ } } defined $opt{rc} or $opt{rc} = 1; defined $opt{cells} or $opt{cells} = 1; defined $opt{attr} or $opt{attr} = 0; defined $opt{clip} or $opt{clip} = $opt{cells}; defined $opt{strip} or $opt{strip} = 0; defined $opt{dtfmt} or $opt{dtfmt} = "yyyy-mm-dd"; # Format 14 # $debug = $opt{debug} // 0; $debug = defined $opt{debug} ? $opt{debug} : 0; $debug > 4 and print STDERR Data::Dumper->Dump ([\%opt],["Options"]); my $io_ref = ref ($txt) =~ m/GLOB|IO/ ? $txt : undef; my $io_fil = $io_ref ? 0 : do { no warnings "newline"; -f $txt ? 1 : 0 }; my $io_txt = $io_ref || $io_fil ? 0 : 1; $io_fil && ! -s $txt and return; $io_ref && eof ($txt) and return; if ($opt{parser} ? _parser ($opt{parser}) eq "csv" : ($io_fil && $txt =~ m/\.(csv)$/i)) { $can{csv} or croak "CSV parser not installed"; my $label = $io_fil ? $txt : "IO"; $debug and print STDERR "Opening CSV $label\n"; my $csv; my @data = ( { type => "csv", parser => $can{csv}, version => $can{csv}->VERSION, quote => '"', sepchar => ',', sheets => 1, sheet => { $label => 1 }, }, { label => $label, maxrow => 0, maxcol => 0, cell => [], attr => [], }, ); my ($sep, $quo, $in) = (",", '"'); defined $opt{sep} and $sep = $opt{sep}; defined $opt{quote} and $quo = $opt{quote}; if ($io_fil) { unless (defined $opt{quote} && defined $opt{sep}) { local $/ = $/; open $in, "<", $txt or return; $_ = <$in>; $quo = defined $opt{quote} ? $opt{quote} : '"'; $sep = # If explicitly set, use it defined $opt{sep} ? $opt{sep} : # otherwise start auto-detect with quoted strings m/["0-9];["0-9;]/ ? ";" : m/["0-9],["0-9,]/ ? "," : m/["0-9]\t["0-9,]/ ? "\t" : # If neither, then for unquoted strings m/\w;[\w;]/ ? ";" : m/\w,[\w,]/ ? "," : m/\w\t[\w,]/ ? "\t" : "," ; close $in; } open $in, "<", $txt or return; } else { $in = $txt; # Now pray ... } $debug > 1 and print STDERR "CSV sep_char '$sep', quote_char '$quo'\n"; $csv = $can{csv}->new ({ sep_char => ($data[0]{sepchar} = $sep), quote_char => ($data[0]{quote} = $quo), keep_meta_info => 1, binary => 1, }) or croak "Cannot create a csv ('$sep', '$quo') parser!"; while (my $row = $csv->getline ($in)) { my @row = @$row or last; my $r = ++$data[1]{maxrow}; @row > $data[1]{maxcol} and $data[1]{maxcol} = @row; foreach my $c (0 .. $#row) { my $val = $row[$c]; my $cell = cr2cell ($c + 1, $r); $opt{rc} and $data[1]{cell}[$c + 1][$r] = $val; $opt{cells} and $data[1]{$cell} = $val; $opt{attr} and $data[1]{attr}[$c + 1][$r] = { @def_attr }; } } $csv->eof () or $csv->error_diag; close $in; for (@{$data[1]{cell}}) { defined $_ or $_ = []; } return _clipsheets \%opt, [ @data ]; } # From /etc/magic: Microsoft Office Document if ($io_txt && _parser ($opt{parser}) !~ m/^xlsx?$/ && $txt =~ m/^(\376\067\0\043 |\320\317\021\340\241\261\032\341 |\333\245-\0\0\0)/x) { $can{xls} or croak "Spreadsheet::ParseExcel not installed"; my $tmpfile; if ($can{ios}) { # Do not use a temp file if IO::Scalar is available $tmpfile = \$txt; } else { $tmpfile = File::Temp->new (SUFFIX => ".xls", UNLINK => 1); binmode $tmpfile; print $tmpfile $txt; close $tmpfile; } open $io_ref, "<", $tmpfile or return; $io_txt = 0; $opt{parser} = "xls"; } my $_parser; if ($opt{parser} ? ($_parser = _parser ($opt{parser})) =~ m/^xlsx?$/ : ($io_fil && $txt =~ m/\.(xlsx?)$/i && ($_parser = $1))) { my $parse_type = $_parser =~ m/x$/i ? "XLSX" : "XLS"; $can{lc $parse_type} or croak "Parser for $parse_type is not installed"; my $oBook; $debug and print STDERR "Opening $parse_type \$txt\n"; if ($io_ref) { $oBook = $parse_type eq "XLSX" ? Spreadsheet::XLSX::Workbook->Parse ($io_ref) : Spreadsheet::ParseExcel::Workbook->Parse ($io_ref); } else { $oBook = $parse_type eq "XLSX" ? Spreadsheet::XLSX->new ($txt) : Spreadsheet::ParseExcel::Workbook->Parse ($txt); } $oBook or return; $debug > 8 and print STDERR Data::Dumper->Dump ([$oBook],["oBook"]); my @data = ( { type => lc $parse_type, parser => $can{lc $parse_type}, version => $parse_type eq "XLSX" ? $Spreadsheet::XLSX::VERSION : $Spreadsheet::ParseExcel::VERSION, sheets => $oBook->{SheetCount} || 0, sheet => {}, } ); # Overrule the default date format strings my %def_fmt = ( 0x0E => lc $opt{dtfmt}, # m-d-yy 0x0F => "d-mmm-yyyy", # d-mmm-yy 0x11 => "mmm-yyyy", # mmm-yy 0x16 => "yyyy-mm-dd hh:mm", # m-d-yy h:mm ); $oBook->{FormatStr}{$_} = $def_fmt{$_} for keys %def_fmt; my $oFmt = $parse_type eq "XLSX" ? Spreadsheet::XLSX::Fmt2007->new : Spreadsheet::ParseExcel::FmtDefault->new; $debug and print STDERR "\t$data[0]{sheets} sheets\n"; foreach my $oWkS (@{$oBook->{Worksheet}}) { $opt{clip} and !defined $oWkS->{Cells} and next; # Skip empty sheets my %sheet = ( label => $oWkS->{Name}, maxrow => 0, maxcol => 0, cell => [], attr => [], ); defined $sheet{label} or $sheet{label} = "-- unlabeled --"; exists $oWkS->{MaxRow} and $sheet{maxrow} = $oWkS->{MaxRow} + 1; exists $oWkS->{MaxCol} and $sheet{maxcol} = $oWkS->{MaxCol} + 1; my $sheet_idx = 1 + @data; $debug and print STDERR "\tSheet $sheet_idx '$sheet{label}' $sheet{maxrow} x $sheet{maxcol}\n"; if (exists $oWkS->{MinRow}) { foreach my $r ($oWkS->{MinRow} .. $sheet{maxrow}) { foreach my $c ($oWkS->{MinCol} .. $sheet{maxcol}) { my $oWkC = $oWkS->{Cells}[$r][$c] or next; defined (my $val = $oWkC->{Val}) or next; my $cell = cr2cell ($c + 1, $r + 1); $opt{rc} and $sheet{cell}[$c + 1][$r + 1] = $val; # Original my $fmt; my $FmT = $oWkC->{Format}; if ($FmT) { unless (ref $FmT) { $fmt = $FmT; $FmT = {}; } } else { $FmT = {}; } foreach my $attr (qw( AlignH AlignV FmtIdx Hidden Lock Wrap )) { exists $FmT->{$attr} or $FmT->{$attr} = 0; } exists $FmT->{Fill} or $FmT->{Fill} = [ 0 ]; exists $FmT->{Font} or $FmT->{Font} = undef; unless (defined $fmt) { $fmt = $FmT->{FmtIdx} ? $oBook->{FormatStr}{$FmT->{FmtIdx}} : undef; } if ($oWkC->{Type} eq "Numeric") { # Fixed in 0.33 and up # see Spreadsheet/ParseExcel/FmtDefault.pm $FmT->{FmtIdx} == 0x0e || $FmT->{FmtIdx} == 0x0f || $FmT->{FmtIdx} == 0x10 || $FmT->{FmtIdx} == 0x11 || $FmT->{FmtIdx} == 0x16 || (defined $fmt && $fmt =~ m{^[dmy][-\\/dmy]*$}) and $oWkC->{Type} = "Date"; $FmT->{FmtIdx} == 0x09 || $FmT->{FmtIdx} == 0x0a || (defined $fmt && $fmt =~ m{^0+\.0+%$}) and $oWkC->{Type} = "Percentage"; } defined $fmt and $fmt =~ s/\\//g; $opt{cells} and # Formatted value $sheet{$cell} = $FmT && exists $def_fmt{$FmT->{FmtIdx}} ? $oFmt->ValFmt ($oWkC, $oBook) : $oWkC->Value; if ($opt{attr}) { my $FnT = $FmT->{Font}; my $fmi = $FmT->{FmtIdx} ? $oBook->{FormatStr}{$FmT->{FmtIdx}} : undef; $fmi and $fmi =~ s/\\//g; $sheet{attr}[$c + 1][$r + 1] = { @def_attr, type => lc $oWkC->{Type}, enc => $oWkC->{Code}, merged => $oWkC->{Merged} || 0, hidden => $FmT->{Hidden}, locked => $FmT->{Lock}, format => $fmi, halign => [ undef, qw( left center right fill justify ), undef, "equal_space" ]->[$FmT->{AlignH}], valign => [ qw( top center bottom justify equal_space )]->[$FmT->{AlignV}], wrap => $FmT->{Wrap}, font => $FnT->{Name}, size => $FnT->{Height}, bold => $FnT->{Bold}, italic => $FnT->{Italic}, uline => $FnT->{Underline}, fgcolor => _xls_color ($FnT->{Color}), bgcolor => _xls_color (@{$FmT->{Fill}}), }; } } } } for (@{$sheet{cell}}) { defined $_ or $_ = []; } push @data, { %sheet }; # $data[0]{sheets}++; if ($sheet{label} eq "-- unlabeled --") { $sheet{label} = ""; } else { $data[0]{sheet}{$sheet{label}} = $#data; } } return _clipsheets \%opt, [ @data ]; } if ($opt{parser} ? _parser ($opt{parser}) eq "sc" : $io_fil ? $txt =~ m/\.sc$/ : $txt =~ m/^# .*SquirrelCalc/) { if ($io_ref) { local $/; my $x = <$txt>; $txt = $x; } elsif ($io_fil) { local $/; open my $sc, "<", $txt or return; $txt = <$sc>; close $sc; } $txt =~ m/\S/ or return; my @data = ( { type => "sc", parser => "Spreadsheet::Read", version => $VERSION, sheets => 1, sheet => { sheet => 1 }, }, { label => "sheet", maxrow => 0, maxcol => 0, cell => [], attr => [], }, ); for (split m/\s*[\r\n]\s*/, $txt) { if (m/^dimension.*of ([0-9]+) rows.*of ([0-9]+) columns/i) { @{$data[1]}{qw(maxrow maxcol)} = ($1, $2); next; } s/^r([0-9]+)c([0-9]+)\s*=\s*// or next; my ($c, $r) = map { $_ + 1 } $2, $1; if (m/.* {(.*)}$/ or m/"(.*)"/) { my $cell = cr2cell ($c, $r); $opt{rc} and $data[1]{cell}[$c][$r] = $1; $opt{cells} and $data[1]{$cell} = $1; $opt{attr} and $data[1]{attr}[$c + 1][$r] = { @def_attr }; next; } # Now only formula's remain. Ignore for now # r67c7 = [P2L] 2*(1000*r67c5-60) } for (@{$data[1]{cell}}) { defined $_ or $_ = []; } return _clipsheets \%opt, [ @data ]; } if ($opt{parser} ? _parser ($opt{parser}) eq "sxc" : ($txt =~ m/^<\?xml/ or -f $txt)) { $can{sxc} or croak "Spreadsheet::ReadSXC not installed"; my $sxc_options = { OrderBySheet => 1 }; # New interface 0.20 and up my $sxc; if ($txt =~ m/\.(sxc|ods)$/i) { $debug and print STDERR "Opening \U$1\E $txt\n"; $sxc = Spreadsheet::ReadSXC::read_sxc ($txt, $sxc_options) or return; } elsif ($txt =~ m/\.xml$/i) { $debug and print STDERR "Opening XML $txt\n"; $sxc = Spreadsheet::ReadSXC::read_xml_file ($txt, $sxc_options) or return; } # need to test on pattern to prevent stat warning # on filename with newline elsif ($txt !~ m/^<\?xml/i and -f $txt) { $debug and print STDERR "Opening XML $txt\n"; open my $f, "<", $txt or return; local $/; $txt = <$f>; close $f; } !$sxc && $txt =~ m/^<\?xml/i and $sxc = Spreadsheet::ReadSXC::read_xml_string ($txt, $sxc_options); $debug > 8 and print STDERR Data::Dumper->Dump ([$sxc],["sxc"]); if ($sxc) { my @data = ( { type => "sxc", parser => "Spreadsheet::ReadSXC", version => $Spreadsheet::ReadSXC::VERSION, sheets => 0, sheet => {}, } ); my @sheets = ref $sxc eq "HASH" # < 0.20 ? map { { label => $_, data => $sxc->{$_}, } } keys %$sxc : @{$sxc}; foreach my $sheet (@sheets) { my @sheet = @{$sheet->{data}}; my %sheet = ( label => $sheet->{label}, maxrow => scalar @sheet, maxcol => 0, cell => [], attr => [], ); my $sheet_idx = 1 + @data; $debug and print STDERR "\tSheet $sheet_idx '$sheet{label}' $sheet{maxrow} rows\n"; foreach my $r (0 .. $#sheet) { my @row = @{$sheet[$r]} or next; foreach my $c (0 .. $#row) { defined (my $val = $row[$c]) or next; my $C = $c + 1; $C > $sheet{maxcol} and $sheet{maxcol} = $C; my $cell = cr2cell ($C, $r + 1); $opt{rc} and $sheet{cell}[$C][$r + 1] = $val; $opt{cells} and $sheet{$cell} = $val; $opt{attr} and $sheet{attr}[$C][$r + 1] = { @def_attr }; } } for (@{$sheet{cell}}) { defined $_ or $_ = []; } $debug and print STDERR "\tSheet $sheet_idx '$sheet{label}' $sheet{maxrow} x $sheet{maxcol}\n"; push @data, { %sheet }; $data[0]{sheets}++; $data[0]{sheet}{$sheet->{label}} = $#data; } return _clipsheets \%opt, [ @data ]; } } return; } # ReadData 1; =head1 DESCRIPTION Spreadsheet::Read tries to transparently read *any* spreadsheet and return its content in a universal manner independent of the parsing module that does the actual spreadsheet scanning. For OpenOffice this module uses Spreadsheet::ReadSXC For Microsoft Excel this module uses Spreadsheet::ParseExcel or Spreadsheet::XLSX For CSV this module uses Text::CSV_XS (0.29 or up required, 0.73 or up preferred) or Text::CSV_PP (1.05 or up required). For SquirrelCalc there is a very simplistic built-in parser =head2 Data structure The data is returned as an array reference: $ref = [ # Entry 0 is the overall control hash { sheets => 2, sheet => { "Sheet 1" => 1, "Sheet 2" => 2, }, type => "xls", parser => "Spreadsheet::ParseExcel", version => 0.26, }, # Entry 1 is the first sheet { label => "Sheet 1", maxrow => 2, maxcol => 4, cell => [ undef, [ undef, 1 ], [ undef, undef, undef, undef, undef, "Nugget" ], ], A1 => 1, B5 => "Nugget", }, # Entry 2 is the second sheet { label => "Sheet 2", : : To keep as close contact to spreadsheet users, row and column 1 have index 1 too in the C element of the sheet hash, so cell "A1" is the same as C [1, 1] (column first). To switch between the two, there are two helper functions available: C and C. The C hash entry contains unformatted data, while the hash entries with the traditional labels contain the formatted values (if applicable). The control hash (the first entry in the returned array ref), contains some spreadsheet meta-data. The entry C is there to be able to find the sheets when accessing them by name: my %sheet2 = %{$ref->[$ref->[0]{sheet}{"Sheet 2"}]}; =head2 Functions =over 2 =item my $ref = ReadData ($source [, option => value [, ... ]]); =item my $ref = ReadData ("file.csv", sep => ',', quote => '"'); =item my $ref = ReadData ("file.xls", dtfmt => "yyyy-mm-dd"); =item my $ref = ReadData ("file.ods"); =item my $ref = ReadData ("file.sxc"); =item my $ref = ReadData ("content.xml"); =item my $ref = ReadData ($content); =item my $ref = ReadData ($fh, parser => "xls"); Tries to convert the given file, string, or stream to the data structure described above. Processing Excel data from a stream or content is supported through a File::Temp temporary file or IO::Scalar when available. ReadSXC does preserve sheet order as of version 0.20. Currently supported options are: =over 2 =item parser Force the data to be parsed by a specific format. Possible values are C, C (or C), C (or C), C (or C, C, C) C (or C), and C (or C). When parsing streams, instead of files, it is highly recommended to pass this option. =item cells Control the generation of named cells ("A1" etc). Default is true. =item rc Control the generation of the {cell}[c][r] entries. Default is true. =item attr Control the generation of the {attr}[c][r] entries. Default is false. See L below. =item clip If set, C will remove all trailing lines and columns per sheet that have no visual data. This option is only valid if C is true. The default value is true if C is true, and false otherwise. =item strip If set, C will remove trailing- and/or leading-whitespace from every field. strip leading strailing ----- ------- --------- 0 n/a n/a 1 strip n/a 2 n/a strip 3 strip strip =item sep Set separator for CSV. Default is comma C<,>. =item quote Set quote character for CSV. Default is C<">. =item dtfmt Set the format for M$Excel date fields that are set to use the default date format. The default format in Excel is 'm-d-yy', which is both not year 2000 safe, nor very useful. The default is now 'yyyy-mm-dd', which is more ISO-like. Note that date formatting in M$Excel is not reliable at all, as it will store/replace/change the date field separator in already stored formats if you change your locale settings. So the above mentioned default can be either "m-d-yy" OR "m/d/yy" depending on what that specific character happened to be at the time the user saved the file. =item debug Enable some diagnostic messages to STDERR. The value determines how much diagnostics are dumped (using Data::Dumper). A value of 9 and higher will dump the entire structure from the back-end parser. =back =back =head2 Using CSV In case of CSV parsing, C will use the first line of the file to auto-detect the separation character if the first argument is a file and both C and C are not passed as attributes. Text::CSV_XS (or Text::CSV_PP) is able to automatically detect and use C<\r> line endings). CSV can parse streams too, but be sure to pass C and/or C if these do not match the default C<,> and C<">. =head2 Functions =over 4 =item my $cell = cr2cell (col, row) C converts a C<(column, row)> pair (1 based) to the traditional cell notation: my $cell = cr2cell ( 4, 14); # $cell now "D14" my $cell = cr2cell (28, 4); # $cell now "AB4" =item my ($col, $row) = cell2cr ($cell) C converts traditional cell notation to a C<(column, row)> pair (1 based): my ($col, $row) = cell2cr ("D14"); # returns ( 4, 14) my ($col, $row) = cell2cr ("AB4"); # returns (28, 4) =item my @row = row ($ref, $row) =item my @row = Spreadsheet::Read::row ($ss->[1], 3) Get full row of formatted values (like C<< $ss->{A3} .. $ss->{G3} >>) Note that the indexes in the returned list are 0-based. C is not imported by default, so either specify it in the use argument list, or call it fully qualified. =item my @row = cellrow ($ref, $row) =item my @row = Spreadsheet::Read::cellrow ($ss->[1], 3) Get full row of unformatted values (like C<< $ss->{cell}[1][3] .. $ss->{cell}[7][3] >>) Note that the indexes in the returned list are 0-based. C is not imported by default, so either specify it in the use argument list, or call it fully qualified. =item my @rows = rows ($ref) =item my @rows = Spreadsheet::Read::rows ($ss->[1]) Convert C<{cell}>'s C<[column][row]> to a C<[row][column]> list. Note that the indexes in the returned list are 0-based, where the index in the C<{cell}> entry is 1-based. C is not imported by default, so either specify it in the use argument list, or call it fully qualified. =item parses ($format) =item Spreadsheet::Read::parses ("CSV") C returns Spreadsheet::Read's capability to parse the required format. C is not imported by default, so either specify it in the use argument list, or call it fully qualified. =item my $rs_version = Version () =item my $v = Spreadsheet::Read::Version () Returns the current version of Spreadsheet::Read. C is not imported by default, so either specify it in the use argument list, or call it fully qualified. =back =head2 Cell Attributes If the constructor was called with C having a true value, effort is made to analyze and store field attributes like this: { label => "Sheet 1", maxrow => 5, maxcol => 2, cell => [ undef, [ undef, 1 ], [ undef, undef, undef, undef, undef, "Nugget" ], ], attr => [ undef, [ undef, { type => "numeric", fgcolor => "#ff0000", bgcolor => undef, font => "Arial", size => undef, format => "## ##0.00", halign => "right", valign => "top", uline => 0, bold => 0, italic => 0, wrap => 0, merged => 0, hidden => 0, locked => 0, enc => "utf-8", }, ] [ undef, undef, undef, undef, undef, { type => "text", fgcolor => "#e2e2e2", bgcolor => undef, font => "Letter Gothic", size => 15, format => undef, halign => "left", valign => "top", uline => 0, bold => 0, italic => 0, wrap => 0, merged => 0, hidden => 0, locked => 0, enc => "iso8859-1", }, ] A1 => 1, B5 => "Nugget", }, This has now been partially implemented, mainly for Excel, as the other parsers do not (yet) support all of that. YMMV. =head1 TODO =over 4 =item Options =over 2 =item Module Options New Spreadsheet::Read options are bound to happen. I'm thinking of an option that disables the reading of the data entirely to speed up an index request (how many sheets/fields/columns). See C. =item Parser options Try to transparently support as many options as the encapsulated modules support regarding (un)formatted values, (date) formats, hidden columns rows or fields etc. These could be implemented like C above but names C, or just be new values in the C hashes. =back =item Other spreadsheet formats I consider adding any spreadsheet interface that offers a usable API. =item Add an OO interface Consider making the ref an object, though I currently don't see the big advantage (yet). Maybe I'll make it so that it is a hybrid functional / OO interface. =back =head1 SEE ALSO =over 2 =item Text::CSV_XS, Text::CSV_PP http://search.cpan.org/dist/Text-CSV_XS , http://search.cpan.org/dist/Text-CSV_PP , and http://search.cpan.org/dist/Text-CSV . Text::CSV is a wrapper over Text::CSV_XS (the fast XS version) and/or Text::CSV_PP (the pure perl version) =item Spreadsheet::ParseExcel http://search.cpan.org/dist/Spreadsheet-ParseExcel =item Spreadsheet::XLSX http://search.cpan.org/dist/Spreadsheet-XLSX =item Spreadsheet::ReadSXC http://search.cpan.org/dist/Spreadsheet-ReadSXC =item Spreadsheet::BasicRead http://search.cpan.org/dist/Spreadsheet-BasicRead for xlscat likewise functionality (Excel only) =item Spreadsheet::ConvertAA http://search.cpan.org/dist/Spreadsheet-ConvertAA for an alternative set of cell2cr () / cr2cell () pair =item Spreadsheet::Perl http://search.cpan.org/dist/Spreadsheet-Perl offers a Pure Perl implementation of a spreadsheet engine. Users that want this format to be supported in Spreadsheet::Read are hereby motivated to offer patches. It's not high on my TODO-list. =item xls2csv http://search.cpan.org/dist/xls2csv offers an alternative for my C, in the xls2csv tool, but this tool focuses on character encoding transparency, and requires some other modules. =back =head1 AUTHOR H.Merijn Brand, =head1 COPYRIGHT AND LICENSE Copyright (C) 2005-2010 H.Merijn Brand This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Spreadsheet-Read-0.41/MANIFEST0000644000031300001440000000203111453657405015112 0ustar merijnusersChanges examples/ss2tk examples/ss-dups-tk.pl examples/xlscat examples/xls2csv files/attr.ods files/attr.xls files/attr.xlsx files/content.xml files/Dates.xls files/Dates.xlsx files/empty.csv files/empty.ods files/empty.sc files/empty.sxc files/empty.txt files/empty.xls files/empty.xlsx files/macosx.csv files/macosx.xls files/misc.xls files/misc.xlsx files/perc.xls files/perc.xlsx files/test.csv files/test_m.csv files/test_m.txt files/test.ods files/test.sc files/test.sxc files/test.txt files/test_t.csv files/test_t.txt files/test_x.csv files/test_x.txt files/test.xls files/test.xlsx files/values.xls files/values.xlsx Makefile.PL MANIFEST README Read.pm t/00_pod.t t/01_pod.t t/10_basics.t t/11_call.t t/20_csv.t t/21_csv.t t/22_csv.t t/23_csv.t t/24_csv.t t/30_xls.t t/31_clr.t t/33_misc.t t/32_fmt.t t/34_dates.t t/35_perc.t t/36_xls.t t/40_sxc.t t/45_ods.t t/46_clr.t t/50_sc.t t/51_sc.t t/60_xlsx.t t/61_clr.t t/62_fmt.t t/63_misc.t t/64_dates.t t/65_perc.t META.yml Module meta-data (added by MakeMaker) Spreadsheet-Read-0.41/files/0000755000031300001440000000000011453657405015067 5ustar merijnusersSpreadsheet-Read-0.41/files/test.txt0000644000031300001440000000010211275744145016600 0ustar merijnusersA1,B1,,D1 A2,B2,, A3,,C3,D3 A4,B4,C4, ,,,,,,,,,,,,,,,,,,LASTFIELD Spreadsheet-Read-0.41/files/test.sxc0000644000031300001440000001241710313232324016551 0ustar merijnusersPK\2Emimetypeapplication/vnd.sun.xml.calcPK\2 content.xmlX[o0~߯7c.2Z&ыD+m&1`5#wbBhJU˱%oMۢ]=ozGO×?w͘C.w" 9bY{,xDH"弌p,F{*qS0$H ?~< <d9}[W.(ͷ Rhc䠧kX= >k9%Ҷf܀fgަ2@D0-@\HZƭ^Y:c}4Ӏ @7VL-.i@D"AgA"~wx+󓄬?vW^vj ВP8) M)H8bo)1C+*o_v+pDU8b1 F료$E*PHSehˮdMU$ƔApgkOb6k@bV=D( "E&aPC,i%p+4eV놃NTavjTOwrn_ZgHs {Zow/vJ;R3y(]kbg?:'G1N1TpZp|/"n:8%VRyZW.,/3n>(h%H<{=ɎZe- wǻ Xd<,!a¾o^^ţx O0N&(άY)f5"v˻K<_,0l6F ne37R3`Vƞ.6݃x(?AT`>[#Jx(nxxvD#ttr?pʗGJA^-,OX {$jm>mrAb?G%9ps#,_W5}"TAa .su[8dl-ZbgșUeeqPBS{#%2HU+̺5ZyRi}Mvb̰ v$;JBd Hx#ӢJ uuL]S $ THRla["(5̴ 9lv8(#uCh`8Zo$/*O{"p I&SEDǦܔQ{QUV&q C  =*A.>'|fȑbe)Du){digڥJ_+TU/ZZL?ғy}m(\8}M(VuEP=ئ-gϴa&AiuYH>[DsՋXYTyҔ!pZy<@Ksk#(͟p6XIF=m?/t5+f;"%AU1'g!0j,饵략$Dy6́:qj4B8zzdkҀ-X+Ns~Dk3Y357_8S:$QYXpA*:xߘ^ۀRnٖ[Գ OpenOffice.org 1.1.3 (Linux)H.Merijn Brand2005-05-12T13:31:18H.Merijn Brand2005-05-12T13:36:16en-US4PT4M58SPK\2 settings.xmlmw8pyC3AjѶ Jڐp ڝ2X=;{!7{?7Dž dQrOJJ/uU|qg}yAG6:@V""ZB)-|!?"WxZZٛކh쭍\ٶ"".B7 FhFW6&`uT\09Z\YT14d*ЏMPB߃Pl1 qʺ#!S#9Gr24D0wԅA(cC&s(z*UL|htqFxs=JZBP57+ZQ H( G9 ȿ' YՋeہ_d5iS;{/ Qm2{vDoINK:eFcgg;buuO?)M)(92g9,܃Oš-1ՠx+gJ֧ z^i.C}bҨ +q)4wC(0"?my\ ,j.`zXY ×y0!㝙w4~m/. ~N:u>E?#(As ,\p(OK !~bg[D >Kz?ADEFGH  \pH.Merijn Brand Ba=@=Z?N*8X"1Arial1Arial1Arial1Arial1Arial#,##0\ "$";\-#,##0\ "$"!#,##0\ "$";[Red]\-#,##0\ "$""#,##0.00\ "$";\-#,##0.00\ "$"'"#,##0.00\ "$";[Red]\-#,##0.00\ "$";*6_-* #,##0\ "$"_-;\-* #,##0\ "$"_-;_-* "-"\ "$"_-;_-@_-8)3_-* #,##0\ _$_-;\-* #,##0\ _$_-;_-* "-"\ _$_-;_-@_-C,>_-* #,##0.00\ "$"_-;\-* #,##0.00\ "$"_-;_-* "-"??\ "$"_-;_-@_-@+;_-* #,##0.00\ _$_-;\-* #,##0.00\ _$_-;_-* "-"??\ _$_-;_-@_- GENERAL                + ) , *   83ffff̙̙3f3fff3f3f33333f33333`Sheet1G Second SheetbZ 3  @@  _A1B1D1A2B2A3C3D3A4B4C4xxxxxxxx 0   dMbP?*+_%$!&C&"Times New Roman,Regular"&12&A)&&C&"Times New Roman,Regular"&12Page &P&333333?'333333?(333333?)333333?"d,,>>?>>?U}             PH0(  >@   dMbP?*+_%$!&C&"Times New Roman,Regular"&12&A)&&C&"Times New Roman,Regular"&12Page &P&333333?'333333?(333333?)333333?"d,,>>?>>?U}          (  x  6XPP? i&] <Note 1<xx  6XPP? i&] <Note 2 Note 2 Note 2<xx  6XPP? i&] <Note 3 Note 3<HMBHMBHMB>@  FMicrosoft Excel 97-TabelleBiff8Oh+'0  p x 4@1@0:@xV@GVH.Merijn BrandH.Merijn BrandRoot EntryF0Pd@WorkbookCompObj@IOle B_SX_DB_CURSummaryInformation(CPSpreadsheet-Read-0.41/files/empty.sc0000644000031300001440000000000010313232324016521 0ustar merijnusersSpreadsheet-Read-0.41/files/empty.csv0000644000031300001440000000000010701240352016710 0ustar merijnusersSpreadsheet-Read-0.41/files/test_m.txt0000644000031300001440000000005011275744475017124 0ustar merijnusersA1;B1;;D1 A2;B2;; A3;;"C3";D3 A4;B4;C4; Spreadsheet-Read-0.41/files/values.xls0000644000031300001440000003300010313232324017071 0ustar merijnusersࡱ>  0@\ppc16 Ba==hKL;#8X@"1Arial1Arial1Arial1Arial7" "\ #,##0_-;" "\ #,##0\-A" "\ #,##0_-;[Red]" "\ #,##0\-C" "\ #,##0.00_-;" "\ #,##0.00\-M$" "\ #,##0.00_-;[Red]" "\ #,##0.00\-q*6_-" "\ * #,##0_-;_-" "\ * #,##0\-;_-" "\ * "-"_-;_-@_-,)'_-* #,##0_-;_-* #,##0\-;_-* "-"_-;_-@_-,>_-" "\ * #,##0.00_-;_-" "\ * #,##0.00\-;_-" "\ * "-"??_-;_-@_-4+/_-* #,##0.00_-;_-* #,##0.00\-;_-* "-"??_-;_-@_-                + )  , *  ` Blad1`i@ A1 labelspaceemptynulonequoteu < 0@ W  dMbP?_*+%"??U  ?       @>@7 Oh+'0@HXh pc16fpc16fMicrosoft Excel@2 L@N9L՜.+,0 PXp x  PROCURA B.V.We Blad1  Werkbladen Root Entry FWorkbookSummaryInformation(DocumentSummaryInformation8Spreadsheet-Read-0.41/files/empty.ods0000644000031300001440000001315510327656236016741 0ustar merijnusersPKTZ3l9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKTZ3Configurations2/PKTZ3 Pictures/PKTZ3 content.xmlVMs0W0ziPۙtzJNi;b1胑q}%pô2^iYz8A:n$U9ut>l>TQ0 Yh-@ZDodtZff2ILU ,Fgm1Om`=v%[p5i=֙ 5|0ʹ.*bٙgeVM̚LL{\Ukޢr/f|6GKXdk%onw'bDOzyĖ#wraxz<͂Sky*Y5̀J^'wn,N)w\K9;~f|4gZ '0{4HL{ts\p@'*f ߇_:ƬH~&3f&nx:H*e^4jTR7{h)')MS_ځD^rDJc0t a9/܃ݙRD!JRπka&v)& ՊO d3F~bCB֩5O0kY;}b:\\~Hk3 B<:Wi2*0/GT' P~RSynYB>Vy])*s. Q±RW?zݿNgKfݔ#ULU#Ozg FEN!N}s;.&VW1L7fv(a=/ >[}J}R8P?$rCބ<'pzかLgV77eB]Dc[h8!~ҽev_i Sx#s~ImtB5(lUHd{zܙoUW0.<_lV3®cz40]RZ OpenOffice.org/2.0$Linux OpenOffice.org_project/680m3$Build-8968H.Merijn Brand2005-10-26T12:37:22H.Merijn Brand2005-10-26T12:37:57en-US2PT35SPKTZ3Thumbnails/thumbnail.png sb``p @ H1}e``ltq #'ρ-O94!uC^c3w 2hxZw֚atsYPK-jPKTZ3 settings.xml[SJϯzJ1 x[IҒLjfB_"[%.p\t$g>9srT:tzڷ?g ;p@)qSHϵCE>t,x; /'e((:jGOK]KP'PվRWJJIuJ$#D {ꘪN]d`*wHI) iEK58^7~e-j7[㹟\J-eq`MZ䡫C{kkvLTպ>j s塇cUx^\;;nۡ~s|7}CttbӾ~kFwC]"Nbad/:O'rdVߺ"payn:;YHG9Ÿnt5pjh/ ц牅<,@3'a~P0!CB BT9+f:@PR1Za,rCfq_W)`'PKpMWPKTZ3META-INF/manifest.xmln0<{춧" T-¡G7Ky޾)@E.3fgOwe[h')Rޒ>,^-X)IuZ~O\eirgs"[g{<¯q(kʃwhP9]*U&58Rc2bgpi,$Q0:} )mkM) G/qi! ?C`mjڤ\ry''bW*gRϷCW&oH1 <"-H6qXE몡 DqOՎՆN~PKЃ99PKTZ3l9..mimetypePKTZ3TConfigurations2/PKTZ3 Pictures/PKTZ3 content.xmlPKTZ3u_b  styles.xmlPKTZ3t meta.xmlPKTZ3-j Thumbnails/thumbnail.pngPKTZ3pMW ?settings.xmlPKTZ3Ѓ99META-INF/manifest.xmlPK BSpreadsheet-Read-0.41/files/test_t.csv0000644000031300001440000000005010614363313017067 0ustar merijnusersA1 B1 D1 A2 B2 A3 'C3' D3 A4 B4 C4 Spreadsheet-Read-0.41/files/macosx.xls0000644000031300001440000002000010313232324017060 0ustar merijnusersࡱ>   R F+%Tk WorkbookSummaryInformation(DocumentSummaryInformation8  K(\p Abe Timmerman Ba===480@"1Verdana1Verdana1Verdana1Verdana1Verdana1 Verdana1$Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)                + ) , *     ` Sheet1Sheet2Sheet3ail#ly+x眿 )\m\mz`Upt0, `C+)`t0+*R@J~)D`+/`` `Chigo])h~)DD$"+0<x2`xDy uBH- \@yĿ0P]+&ܿP#lllzy&8^\#^H6lnzy&8^\zy&8^\^p͘lsqxDrpuBHy+x眿 t0]&$yy+$`y&@p<luBHCy+pt0\,RCrc[`},;@$luBHTy+hPM- lh0$$pt0xD]Zy uBH'uBHz`P@y+ (KKpK͘lt0 K͘ K(  #  dMbP?_*+%"??U HBCn` A<#ЅC @ C   0  DCE<@  , ~ ?~ ?~ @~ @~ @~ @~ @~ @~ @~ @~ @~ @~ @~ @~  @~  @~ "@~ "@~ $@~ $@~ &@~ &@~ (@~ (@~ *@~ *@~ ,@~ ,@~ .@~ .@~ 0@~ 0@~ 1@~ 1@~ 2@~ 3@~ 4@~ 5@~ 6@~ 7@~ 8@~ 9@6@>@ K( B  dMbP?_*+%"??U >@ K( ?  dMbP?_*+%"??U >@   Oh+'08@Xp 'Abe TimmermanxAbe TimmermanxMicrosoft Excel@Ck ՜.+,0 PXh px 'ztreeth Sheet1Sheet2Sheet3  Worksheets FMicrosoft Excel Worksheet8FIBExcel.Sheet.8CompObj XSpreadsheet-Read-0.41/files/attr.xlsx0000644000031300001440000003244211130422501016741 0ustar merijnusersPK!sA[Content_Types].xml (Un0W?DV@8ql`X$](}7ᡶ ^%gfgǛ,hm͜6vkADHjU8 X~*<`Ļ-"'RbC0v,P*0^e35me,U6c8!YRޓHY[z_PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK![axl/_rels/workbook.xml.rels (j0E}-IR"gS ٶ{ d4ӇM1f{}vxGG5 (&Ec*{ Hˮjnz^Ő;MIi]ٗΏBFi}{翵mY69>C,uGًjW!+-dybaZ;,^i:kK„&:%$ l!Zaa9%?%Rl%&LuZO cȾPK!Poxl/workbook.xmlRn0W?X7<@W^٦$5ԓ̘TI MBJ@e U$s:8ZAB`&Y>$P6s*lVBDנpkS1)[`ܖAbBўaeá\d𬳦z9oKQ[s!a;"YOɬ{O KŸiFH? pY# W< h/ ׭bZ)iApWx{ a3.^G0kݓ1ʧ"JJy㑧÷ݫИ_({ [XtuvfNt<_ƽJPK!3 xl/worksheets/sheet4.xml[s:;\ow0n:Yh ן- ROҗGko-ퟪD#'p}:9ϑkfN:'%iv_]A@PwSl= Z aۊ؞i)þ*jgPضh³biiI.g'ZzwvK7F ?9%7>BGKIID`y1-Ip݋kkԢC)>{΅^JOT1T?za(]]8I;2yNꇂ Jcw\.VJVx +^JV \o@X?زR"j]%J$\=<$D5D~-(˄ r;z=B2w/o}0`lBM(0*-L  B+:*(4O9W ˷N`UwP "J44Ȇ 2,TCSl â dXEk䮴aO}5_Y(VPB,tP,*(QC3>A'>->]sic&^CF ,(VP*%2R`)$_J[54ӸTܕ>)|Ґ @o,(Q6R`A )TAƏi = [K9唆9XAtwuʆil蠡il(UPxf7j7ҩip`9 9&XP!nJI44M o5ChLSD9 M3`L'^a:Eoxc^] 9ӏ=C%=}9av77`/̑\_0S0|,TBP_xhPC~aAaxμe0|3w4-aJmY9< iH& բEPK!,B#xl/worksheets/_rels/sheet4.xml.relsj0D{$;P%_J!&E^ۢJh%؄Bc0]Yc" n@!4D,|>X< ~IлKZ9fVBlaopqSFdLeRcLOhvM7ܝS 0N\8ƀ)Hτ%`9H=U˄bAGw swPK!;m2KB#xl/worksheets/_rels/sheet1.xml.rels0ECx{օ CS7"Ubۗ{ep6<f,Ժch{-A8 -Iy0Ьjm_/N,}W:=RY}H9EbAwk}m PK!2v=xl/worksheets/sheet2.xmlTM W@$NQ&=TVmFk $E0a~;r%sLbJ,U%d_?w_d:%yNOҏ`&*L򞙉ZY&2r8G=zUע䷪\ZOy,oZ1Z+k!yӛdMRk'[y5&q[( xrA38Ra42wn?4xSǯ\4FE I/(ٓEe[-&,͗Oʽ? ǧAE*(— XO@ޅ"?< wtL"Xچn'>_uR%>vޓ6 ^ql`hc(2j%7#b0^Jkw! x 21Z `ĪɃn؂sxɵR<NsA:{aۓ #<PK!Zxl/worksheets/sheet3.xmlQo0';X~_mJTMh{TM`3$xV)}h sk۠%<,Ĉ\W)s#/H#8M.)9E֔* \V[k9R% ^*]OI1M0Û%c?!ʒt+}K2"=me:` )V8Ȓ!oFyFȳ/z[$mh%ЦI1 g4%w`G-ɾQ?+eU`PR.?jZbHtdpx8R.hGEG B#- "uy8B8Vs}K-3ٵNSdcSfkDS0\L^GÐ:L]caS֖7nIq,7nxœ1xqW>[L0q0=l-[fRЫKOZZs-:2`6̇8KǓn;omI6˼gX&#0_e"&mjށ[>[Gy^z+d}hy 〴n۫7  ]eۛGY4b_wv bH<^ o<^,I q$GAy#oIH|I $KH$%!LVr NO:5'd"("qhyQĥɑx<#{$>-H$),լFY†g$lJ:Z K3#hyFH|ZI@3R" iYdr'YLf¦I8<#-H6ZG3GHZ #eȝf50e(lZC3"qiyFRhyF/ZZ=NiyF $-H$odȝf50eʾb6-HġI<#g$G'B3R hyFJ$!-#@d5)sViyF$-Hĥɐx<#9gd$)&B3R" iYdr'YL1 g$AH\Z G3#iyFHZIH3RNEV wH96Fa$HZK3!hyFr$>-I@3R iyF\2foa>!ZKd֪DIF,?Vn'6 #Ѫ>+uy33I)4INO1paTְզ>F/ Z_K4,sPK!> [Tzxl/sharedStrings.xmllN0 HC;64L8m{u[Cja阐Pc~?q|Y#J&SJ>_Zy1T+}M!J"c @R Gdw`*Hgt:UɁd0 6Wr?EȥpPyv9^Q(G f%gObh_e, qƙs,&KUёE{uRFkcC3ՁpXPo8h "+K.lJ0yN;C|6YcF.N5.Yd 3R2rwt+Y.?RO]?PK!eK xl/styles.xmlĜn6EDj; mkO{=՞deF_dHe[$"5~ |QĉCӾ蘆'녳i$bhDb^~a+_΅H BМgJ&s8E!2Ic=WlC{O"? /tœ  S'Uj2ߨ6 SB^!+0m<_9 $"}Ga[O_ne#D%}i*bSν.Fm9&kz׀xc|$Ecέ&y3;V;}T+QMS*V,Mj45,YMS*f,Mj4IP=|UJK*~up:V4urZ4BhWԭKOwexkaەTHS>EMi1/S~#_.¼D= )F&twO`~6wuCBZd޳Yse:ݯ/a &Օm&uFMFE[R"QSqn;S!x. !w6Y(j44%l.OGiz, 6zr3Ӕ рKBIf>H>elC`i]֦,ꆎ9z@=(DQ,9lbUFa,, Dm4p} sDߗX7=1_foC+uPh<#UW<*O̯qI*K-6 ?%_^bAԪ͘{+䫫#N:1ZƖ=[|YFfECVˉ]s;T2^z~ꅛa۵guTkΘޤ%׹m*"q\1u~zqhn[t^{Rrѝ[uPK!iRVxl/theme/theme1.xmlYMoE#F{oc'vGuر[HF[x=ޝfvg53NjHH q Jĥ@wfv;&%!>Ǽ3zA/DҐi;I1f<%`FdpmwM O&nRʊ a<#)p`"Z | |Z$JqloO&4$4Kl{ $JꅐfMr]*΅"g:¬1?*@ K/A|+x3'bj mo>9]N0>\52E4*֕0z^g8 TKgQ<+ uw֬5\|ڂέNlXd67 o.nwů/WZ o@1ZϹ g7 orP1Zl Eɰ)RLpyHP%M+oR(0$CA30Ĝ߫߾zz᳓?̏U}ӏPBs^|gO^|<UCnct8՜(1uO 3C\=|XLHލ9puUpF~bZ`|ũ4Y$nL5tU(CB<ݣ |=:z]2#'D7hqlP;ٻ:!G. 3C7^S!NX7}Jf"zRA#8ꍉ>}C})=9"wa7IhWCHQ[!ӥK7;4rT'~3:ЩϚ1Ѝmm`&_I8ՂwO}onjv`fLNO@)͠,aaQ3")MY _" \}@U%}aV.˒LFUԕU{DŐꦛmNW(CNޜm^S4 |l1<gW{Ow(UV^o9Z۱,^mA-r ?Q2bXoC~  d%;x 'hYY棓vR)gks:\qN-^s;kK] =]4)N2&0懭oO|twSI&aI`=DCPK!\ҍ'xl/printerSettings/printerSettings1.bin`He(bg` 00a8a G $UݙdZ' }2춫$ (L)5 ~akoxTaBNnAiGEHmSY_ ?P[UJ“ Y}pF0%w37 E`Ζi%ƿ?6 dn^xe)41WB`* H> w<IE''JXXtv=] qr<;՜ϻXLۀ$SĭB Z 7c⎡q ɇ1'Mk鮬I/N _eSFP#> a]SmC7 [Tz,xl/sharedStrings.xmlPK-!eK xl/styles.xmlPK-!iRV"xl/theme/theme1.xmlPK-!\ҍ'n)xl/printerSettings/printerSettings1.binPK-!\ҍ'@*xl/printerSettings/printerSettings2.binPK-!6K/|GV+docProps/core.xmlPK-!^q-docProps/app.xmlPKn0Spreadsheet-Read-0.41/files/values.xlsx0000644000031300001440000001655611130422501017276 0ustar merijnusersPK!zғb[Content_Types].xml (TN0#(q!ԴG|7UǶ=VJ${24.[CB|)Hdu0/Jߊ Iy\P-M//&oRDNJ54 *FJ/ht#urj1t5Ug08Is\0*Fg"V.aCUY &U\Evբ d* W;Qaz8]g >~PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!>xl/_rels/workbook.xml.rels (J0nӮ""Ej}Lm2㟾ۅef2k&WP%&w ޚ[= &$W4KH"xR㣔dNҨ9ɨAw(7ey/O ނhm| }Dg"$4FY.2#59鳔Y]bd @%s"ݚ0tB)[ȓPK!]kHxl/workbook.xmlQN0#itSJ zA=xXiI8l':/`:) alZ֞AB"_T MJ4TSk\ 1h%q<4-KY-& DWoJ0(b_&Lq (2Qi[pMki<(7*JfIovV$QWQa du)!%- g*dWqG#G^Nq1;u>n-)q{w㫂t_LE=/PK!UU_xl/sharedStrings.xmldJC1EfoB$)"/L̤ؿ7-%.{gk?)V,l7(9/>?AxZ|̄ȰwwYT[XENkWL7 wKT ~'| Psn$^@5 džoΈ{-苺?gVzBpjpۈ p#T?ےƮ->Ӌ%ΐ ?ggɬӲQ>mzs̄bXoA'kA'Vt@'NjZl n͜OnxM=v9KzmjkoPK!iRVxl/theme/theme1.xmlYMoE#F{oc'vGuر[HF[x=ޝfvg53NjHH q Jĥ@wfv;&%!>Ǽ3zA/DҐi;I1f<%`FdpmwM O&nRʊ a<#)p`"Z | |Z$JqloO&4$4Kl{ $JꅐfMr]*΅"g:¬1?*@ K/A|+x3'bj mo>9]N0>\52E4*֕0z^g8 TKgQ<+ uw֬5\|ڂέNlXd67 o.nwů/WZ o@1ZϹ g7 orP1Zl Eɰ)RLpyHP%M+oR(0$CA30Ĝ߫߾zz᳓?̏U}ӏPBs^|gO^|<UCnct8՜(1uO 3C\=|XLHލ9puUpF~bZ`|ũ4Y$nL5tU(CB<ݣ |=:z]2#'D7hqlP;ٻ:!G. 3C7^S!NX7}Jf"zRA#8ꍉ>}C})=9"wa7IhWCHQ[!ӥK7;4rT'~3:ЩϚ1Ѝmm`&_I8ՂwO}onjv`fLNO@)͠,aaQ3")MY _" \}@U%}aV.˒LFUԕU{DŐꦛmNW(CNޜm^S4 |l1<gW{Ow(UV^o9Z۱,^mA-r ?Q2bXoC~  d%;x 'hYY棓vR)gks:\qN-^s;kK] =]4)N2&0懭oO|twSI&aI`=DCPK!3xl/worksheets/sheet1.xmlSn0#ﬓnUm$T$ҿgoCB9pͼfήyeMUʴ9|wřGij?7ɺG #s![!|A/`i%յd=Zd#z [?iT{[=`08ɿyՊs&ݖk.lT~Pp3Cy *Yh`cHDe;:Q# I_q_O#C]./&{Ȝ=1 9 NR E,4{,LI:cs,]b_w1WnGIi= r7Y cxmSp;>,Xb9YbwsrEM^&,6g>tQUg<7vgU ҵx!$,xA;#NcM .; CR?!M{w%)^b7A\=>,7mU۸ ^b}P*~= 5dyPnnXv9GMZPK-!zғb[Content_Types].xmlPK-!U0#L o_rels/.relsPK-!>[xl/_rels/workbook.xml.relsPK-!]kHxl/workbook.xmlPK-!UU_ xl/sharedStrings.xmlPK-!{  xl/styles.xmlPK-!iRV xl/theme/theme1.xmlPK-!3xl/worksheets/sheet1.xmlPK-!4GVdocProps/core.xmlPK-!H뤖 docProps/app.xmlPK Spreadsheet-Read-0.41/files/test.sc0000644000031300001440000000771010332420104016355 0ustar merijnusers# This model file is a sample of a SquirrelCalc Spreadsheet. # # (c) 1986 Minihouse Research dimension 28 {of 28 rows} 10 {of 10 columns} global frame 2 global display 2 global format [F2L] width c1 16 width c2 2 width c3 9 width c4 4 width c5 23 width c6 2 text na "N/A" r0c0 = "sample1.sc" lock r0c0 lock r0c1 lock r0c2 r0c3 = "Maximum Loan Amount Table" lock r0c3 lock r0c4 lock r0c5 r0c6 = date(today) lock r0c6 lock r0c7 r1c0 = [G2*] "-" lock r1c0 r1c1 = [G2*] "-" lock r1c1 r1c2 = [G2*] "-" lock r1c2 r1c3 = [G2*] "-" lock r1c3 r1c4 = [G2*] "-" lock r1c4 r1c5 = [G2*] "-" lock r1c5 r1c6 = [G2*] "-" lock r1c6 r1c7 = [G2*] "-" lock r1c7 r2c0 = " Assumptions" lock r2c0 lock r2c1 lock r2c2 lock r2c3 lock r2c4 r2c5 = " Results" lock r2c5 lock r2c6 lock r2c7 r3c0 = [G2*] "-" lock r3c0 r3c1 = [G2*] "-" lock r3c1 r3c2 = [G2*] "-" lock r3c2 r3c3 = [G2*] "-" lock r3c3 r3c4 = [G2*] "-" lock r3c4 r3c5 = [G2*] "-" lock r3c5 r3c6 = [G2*] "-" lock r3c6 r3c7 = [G2*] "-" lock r3c7 r4c0 = "Monthly Income" lock r4c0 lock r4c1 r4c2 = ":" lock r4c2 r4c3 = [$2L] 3500 lock r4c4 r4c5 = "Maximum Loan Amount" lock r4c5 r4c6 = ":" lock r4c6 r4c7 = r25c1 lock r4c7 lock r5c0 lock r5c1 lock r5c2 lock r5c3 lock r5c4 lock r5c5 lock r5c6 lock r5c7 r6c0 = "% of Income towards Repay" lock r6c0 lock r6c1 r6c2 = ":" lock r6c2 r6c3 = [%1L] 0.3 lock r6c4 r6c5 = "Affordable House" lock r6c5 r6c6 = ":" lock r6c6 r6c7 = r4c7+r15c3 lock r6c7 lock r7c0 lock r7c1 lock r7c2 lock r7c3 lock r7c4 lock r7c5 lock r7c6 lock r7c7 r8c0 = "Percentage of Loan Payment" lock r8c0 lock r8c1 lock r8c2 lock r8c3 lock r8c4 r8c5 = "Required Down Payment" lock r8c5 r8c6 = ":" lock r8c6 r8c7 = r6c7*r17c3 lock r8c7 r9c0 = "towards Tax, Ins, Assmnts" lock r9c0 lock r9c1 r9c2 = ":" lock r9c2 r9c3 = [%1L] 0.35 lock r9c4 lock r9c5 lock r9c6 lock r9c7 lock r10c0 lock r10c1 lock r10c2 lock r10c3 lock r10c4 r10c5 = "Maximum Monthly Paymnt" lock r10c5 r10c6 = ":" lock r10c6 r10c7 = r4c3*r6c3 lock r10c7 r11c0 = "Term of the Loan in Years" lock r11c0 lock r11c1 r11c2 = ":" lock r11c2 r11c3 = [I2L] 29 lock r11c4 lock r11c5 lock r11c6 lock r11c7 lock r12c0 lock r12c1 lock r12c2 lock r12c3 lock r12c4 r12c5 = "Max. Loan Paymnt/Month" lock r12c5 r12c6 = ":" lock r12c6 r12c7 = r10c7/(1+r9c3) lock r12c7 r13c0 = "Interest of the Loan" lock r13c0 lock r13c1 r13c2 = ":" lock r13c2 r13c3 = [%2L] 0.1475 lock r13c4 lock r13c5 lock r13c6 lock r13c7 lock r14c0 lock r14c1 lock r14c2 lock r14c3 lock r14c4 lock r14c5 lock r14c6 lock r14c7 r15c0 = "Available for Down Payment" lock r15c0 lock r15c1 r15c2 = ":" lock r15c2 r15c3 = [$2L] 25000 lock r15c4 lock r15c5 lock r15c6 lock r15c7 lock r16c0 lock r16c1 lock r16c2 lock r16c3 lock r16c4 lock r16c5 lock r16c6 lock r16c7 r17c0 = "Required down Payment" lock r17c0 lock r17c1 r17c2 = ":" lock r17c2 r17c3 = [%1L] 0.1 lock r17c4 r17c5 = "Adapted from: \"VisiCalc Home and" lock r17c5 lock r17c6 lock r17c7 lock r18c0 lock r18c1 lock r18c2 lock r18c3 lock r18c4 r18c5 = " Office Companion\"" lock r18c5 lock r18c6 lock r18c7 r19c0 = "Payments per Year" lock r19c0 lock r19c1 r19c2 = ":" lock r19c2 r19c3 = [I2L] 12 lock r19c4 r19c5 = date(31320,"Date created: %d-%h-%Y") lock r19c5 lock r19c6 lock r19c7 lock r20c0 lock r20c1 lock r20c2 lock r20c3 lock r20c4 lock r20c5 lock r20c6 lock r20c7 r21c0 = " Workspace" lock r21c0 lock r21c1 lock r21c2 lock r21c3 lock r21c4 lock r21c5 lock r21c6 lock r21c7 r22c0 = "Calc 1:" lock r22c0 r22c1 = r4c3*r6c3/(1+r9c3)*r19c3 lock r22c1 lock r22c2 lock r22c3 lock r22c4 lock r22c5 lock r22c6 lock r22c7 r23c0 = "Calc 2:" lock r23c0 r23c1 = 1/(r13c3/r19c3+1)^(r11c3*r19c3) lock r23c1 lock r23c2 lock r23c3 lock r23c4 lock r23c5 lock r23c6 lock r23c7 r24c0 = "Calc 3:" lock r24c0 r24c1 = 1-r23c1 lock r24c1 lock r24c2 lock r24c3 lock r24c4 lock r24c5 lock r24c6 lock r24c7 r25c0 = "Calc 4:" lock r25c0 r25c1 = r22c1/r13c3*r24c1 lock r25c1 lock r25c2 lock r25c3 lock r25c4 lock r25c5 lock r25c6 lock r25c7 r26c0 = "" r26c1 = " " r27c0 = " " r27c1 = "" goto r0c0 model on Spreadsheet-Read-0.41/files/empty.sxc0000644000031300001440000000000010313232324016711 0ustar merijnusersSpreadsheet-Read-0.41/files/attr.xls0000644000031300001440000005700010452463445016570 0ustar merijnusersࡱ> -, 0@\ppc09 Ba==xKB}(8X@"1Arial1Arial1Arial1Arial1 Arial1Arial1 Arial1 Arial1 Arial1 Arial1(Arial1Arial10Arial Unicode MS1* Letter Gothic1,LettrGoth12 BT1,Lucida Console16Lucida Sans Unicode1Arial10Arial Unicode MS1* Letter Gothic1,LettrGoth12 BT1,Lucida Console16Lucida Sans Unicode1Arial10Arial Unicode MS1* Letter Gothic1,LettrGoth12 BT1,Lucida Console16Lucida Sans Unicode1Arial10Arial Unicode MS1* Letter Gothic1,LettrGoth12 BT1,Lucida Console16Lucida Sans Unicode1Arial10Arial Unicode MS1* Letter Gothic1,LettrGoth12 BT1,Lucida Console16Lucida Sans Unicode1xArial10xArial Unicode MS1*x Letter Gothic1,xLettrGoth12 BT1,xLucida Console16xLucida Sans Unicode1hArial10hArial Unicode MS1*h Letter Gothic1,hLettrGoth12 BT1,hLucida Console16hLucida Sans Unicode7" "\ #,##0_-;" "\ #,##0\-A" "\ #,##0_-;[Red]" "\ #,##0\-C" "\ #,##0.00_-;" "\ #,##0.00\-M$" "\ #,##0.00_-;[Red]" "\ #,##0.00\-q*6_-" "\ * #,##0_-;_-" "\ * #,##0\-;_-" "\ * "-"_-;_-@_-,)'_-* #,##0_-;_-* #,##0\-;_-* "-"_-;_-@_-,>_-" "\ * #,##0.00_-;_-" "\ * #,##0.00\-;_-" "\ * "-"??_-;_-@_-4+/_-* #,##0.00_-;_-* #,##0.00\-;_-* "-"??_-;_-@_-#" "\ #,##0.00_-d/m h:mm 00.00.00.000**\ #,###,#00,000.00,**                + )  , *                      @  H  H  H  H   H   H   H   H  @  H  H  H  H   H   H   H   H  @  H  H  H  H   H   H   H   H  @  H  H  H  H   H   H   H   H  @  H  H  H  H   H   H   H   H  @  H  H  H  H   H   H   H   H  @(  H(  H(  H(  H(   H(   H(   H(   H(  @  H  H  H  H   H   H   H   H ! " #         0 1 2 3 $   4                                           !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /  0  1  2  3  4  5      ,               1         `xColourse)Formatz, Alignment i/Fonts`iLredgreenbluewhiteyellow lightgreen lightblueautograyleftmiddlerighttopbottomjustifyfillArialArial Unicode MS Letter GothicLettrGoth12 BTLucida ConsoleLucida Sans Unicodebolditalic bold italic underline6 point18 pointmergedunlockedhidden"  PR 0@  #)  dMbP?_*+%MxeroxS 4dXXA4PRIV0''''P4(/h " dXX??U             & / 8 A J S \   ' 0 9 B K T ]   ( 1 : C L U ^    ) 2 ; D M V _  ! * 3 < E N W `  " + 4 = F O X a  # , 5 > G P Y b  $ - 6 ? H Q Z c  % . 7 @ I R [ d"~~~~~~~~>@7 0@  !*,  dMbP?_*+%"??U}     ~ @~ @ ~ @ ~ @ ~ @~ @~ @~ @~ @~ @~ @~ @&>@ 7 0@ 6- /  dMbP?_*+%"??U}  @@@@@  e f g t h i j k u l m n o v  e f g t p q r s wPFFFF>@7 0@ 37  dMbP?_*+%MxeroxS 4dXXA4PRIV0''''P4(/h " dXX??U} } } I} m} }  } m$  }       }      x ~      y       z       {       |      :xbbbbbb>@  7 Oh+'0@HXh pc09fpc09fMicrosoft Excel@($F@*A@j՜.+,0 PXp x  PROCURA B.V.lig ColoursFormat AlignmentFonts  Werkbladen  !"#%&'()*+Root Entry FWorkbook7SummaryInformation(DocumentSummaryInformation8$Spreadsheet-Read-0.41/files/test_x.csv0000644000031300001440000000005010313232324017064 0ustar merijnusersA1=B1==D1 A2=_B2_== A3==C3=D3 A4=B4=C4= Spreadsheet-Read-0.41/files/perc.xlsx0000644000031300001440000001710611130422501016720 0ustar merijnusersPK!~N[Content_Types].xml (N0EH-ݲ@5(`Ic/y="JEU6"k9s=mchcX8aYSur1@w|6,v Qu;)Q MW~R&Wj z4:T 56W<+O>rd!5cAzwUJjUs kj0Q=y^Sb90eP[DШ+qK6'LAڄG;=[^ٰPh{J @܀IB.vkD{4@ Cg>0PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!p-xl/_rels/workbook.xml.rels (j0E}=v ٔB!Ėf_@H6s$mw?NNCY_U} At;|N* TܢbS`NB~ #Z{Q"%ec~<X~'I֊/5Ao>jj34fl&ƋVPK!< ; xl/styles.xmlTM0Fvnwe[0ڲ*[#Їw${m'eB/Ɍ4<͌ȭF8$q]&tFSͨ4x?od{}Wnc:1VQm,̅$%6InB"ӽ*w6P|ƛ ?`4}1 jI6IäȔ_d "sБJHBTF1MbiPr& Au{nu K Ƹ+ѭCJ EVˠkǣ" !{oe7 &hk4`pEVs)wa;:5T"9%/IIvJУ9^G)Z:kW Y9腱:SsL Ċp|Vɴ#פ@ѫ2njX?V>k, c yo %X\t ae⭧B"+zoPK!iRVxl/theme/theme1.xmlYMoE#F{oc'vGuر[HF[x=ޝfvg53NjHH q Jĥ@wfv;&%!>Ǽ3zA/DҐi;I1f<%`FdpmwM O&nRʊ a<#)p`"Z | |Z$JqloO&4$4Kl{ $JꅐfMr]*΅"g:¬1?*@ K/A|+x3'bj mo>9]N0>\52E4*֕0z^g8 TKgQ<+ uw֬5\|ڂέNlXd67 o.nwů/WZ o@1ZϹ g7 orP1Zl Eɰ)RLpyHP%M+oR(0$CA30Ĝ߫߾zz᳓?̏U}ӏPBs^|gO^|<UCnct8՜(1uO 3C\=|XLHލ9puUpF~bZ`|ũ4Y$nL5tU(CB<ݣ |=:z]2#'D7hqlP;ٻ:!G. 3C7^S!NX7}Jf"zRA#8ꍉ>}C})=9"wa7IhWCHQ[!ӥK7;4rT'~3:ЩϚ1Ѝmm`&_I8ՂwO}onjv`fLNO@)͠,aaQ3")MY _" \}@U%}aV.˒LFUԕU{DŐꦛmNW(CNޜm^S4 |l1<gW{Ow(UV^o9Z۱,^mA-r ?Q2bXoC~  d%;x 'hYY棓vR)gks:\qN-^s;kK] =]4)N2&0懭oO|twSI&aI`=DCPK!a~ xl/worksheets/sheet1.xmln0+,g$ݍQ{Q)]PSpvӷgսHx fyV 6ՊEHRͫxvMIx公Ċ-[<̈́PV͔oM3Qv!kQM6&,( /nYCvy*dZJ"(,[^nsH#v+znvCҠZD[%zgR/(%["E D $ @Y/h![㯅.EULe99%%3Ve.ŗQLɳhc)I_[%˧.Jbz#VkݞSa0\ PvEӆbyyp:j]90hgsz5wCFG6j ;.=ZZAs`pO7{VU٪û.N5b#ue՞7˻97&=oTgpt DYoc˰(Qv ,ݳExl D[̱m:.{A6|s/OgnIuNp 746+vSFbВk{o/9{Cs Kqm{bzgNp+C'faYyCfv:oy =*m{pBlst>k@x9%9 n~dhWнVu[N'?cvw3֬gNp٫`Vy NVJOo u%Yuj_yϫb^Cഈ7JڬɳT0 fl,T ڣyHx﫧\eEOzb&?PK!2'CXdocProps/core.xml (AK0ߡަYv-$o[ICMY;1=R>:$Eh w%zE3-Xj(ZU7lkz . $(7%{o(ƎA1mkhw0vizx&gf"R i>l3Ѐ& ?YV?/ YRI4a-؜'`uI 0j,u+*X <+kqs.`=@Dߝ^*\)Ӭ&% gg{N/$dIs2#~/T_PK!H뤖docProps/app.xml (Mo0  k90 M7Aѳ*ӉPY$HGp=M'%Eq}llBLƻeയۗlue JvĮ/b}RF.'}Fʎ*BJ6~m!wGWAu hM+;ۜKq5Z!R1:k~5XEAtkЯIOS’elς mLLRhAY2ils=NZrHX]ې |lUNpj>NcM .; CR?!M{w%)^b7A\=>,7mU۸ ^b}P*~= 5dyPnnXv9GMZPK-!~N[Content_Types].xmlPK-!U0#L ^_rels/.relsPK-!p-Jxl/_rels/workbook.xml.relsPK-!R'Fjxl/workbook.xmlPK-!< ; xl/styles.xmlPK-!iRV! xl/theme/theme1.xmlPK-!a~ xl/worksheets/sheet1.xmlPK-!2'CXdocProps/core.xmlPK-!H뤖&docProps/app.xmlPK >Spreadsheet-Read-0.41/files/test_x.txt0000644000031300001440000000005011275744471017133 0ustar merijnusersA1=B1==D1 A2=_B2_== A3==C3=D3 A4=B4=C4= Spreadsheet-Read-0.41/files/test.ods0000644000031300001440000001562510327656236016566 0ustar merijnusersPKyTZ3l9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKyTZ3Configurations2/PKyTZ3 Pictures/PKyTZ3 content.xmlZo6_!xhYv^{+hJ@R~GRi[r$"H}xw zfg# >D |ff˭HF,)׈g\w>(% qS5d& kY[6-nW`de c} 'Fe(x6Z0\d(*ihä,*&!ͨ1h56`}x/QVwE<:BCR,{׆wO$esӎ܄v v/TD1ڗB4wA*t=$|-҃p3D\mA\GSM@q Xŝ{ )̾F+Ln.*l 4O`BQLIr>$VZRQU4k|β|.Q0M8d ܕX{'e]`?g #k ɪ[̤9J7Jz?9Or+AVOsCC5*픆y9Ԓ>Ԍ %ZRИ5V5M/^s7ǀ{XRJ_ '`H8C%nf5+2g"ʟJ\Ġ)H/G$.RF_Ͼ7fSop hfAx+!^)ű:}G LYx)Zep!DbbPMicp#- UkRhm!=>JqS81{DMQ6YCq 2IVa}:Z%jPᑱ l^\`٥Cp TAZvD&ҩ*Ev^ Lf4*eJpl>0%-zS2JSi}V~$]̣R;]&T[FfR\pVyQPvQqza8WFF7kpۼoez{t@lh^ݑI3F:mRuSG;c)n .i)zq&^MwQ ܡȅd\^y[5l}JE KL[\ynUB'v稜 CFn6€kUC-&*qk8+n @& ]΀_:6~_U߆7Լ ~|N^4ʮa uUj&C _.nc2#Xi!޿ φCI/ƣ5hy4/ *EqpGiO⣀]o,8woqjG*i~{*Gaۮ&+17Y ?I|izflmDZ~^PKR5_ PKyTZ3 styles.xmlYn6S*PdI&n`0"-춠%J&JII/<{=I,n+It~ȹ-B~|gk_ :9I*i]b((3klő$rPJ+^a*qe%\uj+|*klOm{6v&~]U4yBEqK JU0ق"///CN5, 1ڙ E+47>rljB]1"v5ٵae{uuK9_P Kc{TTi]}ι U+j]FO}'{Axz":y9F2 ][I{G8pJerekˉ=9Z/J`TzcwZ|I*._u|TDD_~x::%`koo.^rSKw37myFI&fX(X'q`V8umQMZn4/H1~ ?JyКJI`S*$P!PjEpΫ #R!8*˃nC5Qs5*` 3#Hy͔-}xDlXkE1pX[:X׭۱l;̘NH+tKgÒ#{ y* Sp` шMg#QnU=q YYJ1pWn8m9QӅvdExfw?Ӽued]}fOջ)_az|i_+]_kKO*w@XFvDžzv6l<+9/7d8Ӻ%U{8UӼC(I[{\ x -FrJ ȞdzpESbcRla:=ZrbO~T^~H~ĜhBHLk[\Nn[Wi20/GT{Z'P~0SP{e*!u{}V)r, (m1k S%\!- ӛ7qD'B"G؀Y5cK9"oygËc,l>w'vkiFѬңx\?_ŀРQ͡F>M'9r:* }ox8aD3b$ X8y >nREo8c^8P$ ф ܟ8"DLgE*ُE|*n,kɣ4ߎƊjdoM/pjJ$ yьP[:5Euj'WC۪-[pr}}} IuQu]#17Zj7z+̓ڎI!z !xoqIbbSX"v!逇#0E -Ρg~GB6`>^W zzo%]yK./@+J/?PK#}LUPKyTZ30W+  meta.xml OpenOffice.org/2.0$Linux OpenOffice.org_project/680m3$Build-8968H.Merijn Brand2005-05-12T13:31:18H.Merijn Brand2005-05-12T13:36:16en-US4PT4M58SPKyTZ3Thumbnails/thumbnail.png sb``p @ H1}e`` tq C"~߶UEUs>[Pm7??4}/._{IjqG{{>7||jkz[վ^[|=WM6|]=oo\{m^/mYԗ?-sδ~?=1(kmۮ;{ZxR{{/YW֫v&oe^+N=z͍S JN<-;A8˪p ӓ7/eĄy6\};Ykvx_v~i~Gmjy3v2eO^lx!01xsJhPKg3xPKyTZ3 settings.xmlZr8}߯`L&S S \Kxmk%$cG0xpق`]iK"_>. ㈒t*H"2QVJZ뚾"V\>$C!^ $7JHxp*4d3vteE1""QGs&ŒUfC+J~KE)IOHYizQLwKSݬkЏצnMQ$ee`sՔm l Ee)DD(U+ȧ8e`Do+rW3gp4j.`ݔ\0J5,}4eSzP> !u(GBQ%GehI`$ ӛQvC&s,󘾵# M@&˳ lY6foPkTxKNJ)#~R> I@N HV*wuWYMFڔac4UgϕS['#ӨzOg_ hd>0W?)|R Qs?2gDű c:Ŕ1OPI,kڗ\ĤQ WG!Y#s(0"myA.$= ,^-X)IuZ~O\eirgs"[g{<¯q(kʃwhP9]*U&58Rc2bgpi,$Q0:} )mkM) G/qi! ?C`mjڤ\ry''bW*gRϷCW&oH1 <"-H6qXE몡 DqOՎՆN~PKЃ99PKyTZ3l9..mimetypePKyTZ3TConfigurations2/PKyTZ3 Pictures/PKyTZ3R5_ content.xmlPKyTZ3#}LU styles.xmlPKyTZ30W+  3 meta.xmlPKyTZ3g3xeThumbnails/thumbnail.pngPKyTZ3 ϭ #settings.xmlPKyTZ3Ѓ99META-INF/manifest.xmlPK jSpreadsheet-Read-0.41/files/test_t.txt0000644000031300001440000000005011275744454017130 0ustar merijnusersA1 B1 D1 A2 B2 A3 'C3' D3 A4 B4 C4 Spreadsheet-Read-0.41/files/test.xlsx0000644000031300001440000002421011130422501016740 0ustar merijnusersPK!·[Content_Types].xml (TN0#(qBiP4V򺯿g PHUDQ3;"ځGmMɈE`UڬSzXA% k eG@6LWGQ!GQP LC2Kӯr#'=0!MH UsŠ;e¹BKH95Y%(+%q%5]%p,S ,e^@&E@c/k̄*1{do͵]IJM+49z,WbGg]zd8yСc6ё{+= (mY-+^Ϙ =xRy3O)z<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!JaGxl/_rels/workbook.xml.rels (j0 ѽqP:{)0Mlc?y6У$41f9#u)(ڛε ^OW 3H./6kNOd@"8R`ÃT[4e>KAsc+EY5iQw~ om4]~ ɉ -i^Yy\YD>qW$KS3b2k T>:3[/%s* }+4?rV PK!5$4H,xl/workbook.xmlQMO1eE$5r1$"k;6tۦ-.{%(<ͼyofC78/pS!׻ %>0-2*zOͬ7ne̎mC,󼅎1ױm3o0[Щq1IaaFrx6|߁'߷zZ`}ڈ0kYs%"dQ{ۧT1[cտK.ZBFjazdMz3zDЧFqǣQyܶdVم|IGgDM%:n!Qт$k"a+_:M/ʇLG?PK!P xl/styles.xmlSMk0@KX.{ ,PH {D#Ї!v{ٽoF73oFYv1%/i FN)VZ## $#B^;H՞N TAΊb(ϫۅΣQR] .҃ӣ3U3i%,rTe :l›%u׼B󋬾PK! 1#xl/worksheets/_rels/sheet2.xml.relsj1 E>Lx lC<סv Mw.::hY9V780x=@Ih \Y`=>l"k&7'\PK!j%mП˓9%ڰ`Bg"!IkC "y AH)U U;pEB?[3D_8dY2ohMO@0u;MӸن2 ZON&{),p]$Է_E (Vw05-1=x+wW Nثg̰4VrGG1; :C߹ .1e4b/ 8@-ͯ=hPfKCqzb'7VjeK^͎S} 9vG!ҿ~ V &ܶ"9da !jmq uoLUD@d6.FOÛ;UټָL'f1ǟORal:fۑX\nIe㆒%"xB>ax> qo&xqS .XˢrO龬'jvV6| V0Ek{b 6Nٍ#{a4P9Sl!Q/KPK!D xl/theme/theme1.xmlYOo6w toc'vuر-MniPFI|úa0l+t&[HJkf%~||~|8:$BR՚H&aۻ;_YT8 0 i{S"sD)/-IS11V(¥@#Zmu)4Pc{g<>Ebo#c!QRwL h\ppP9]&!fmhH ^6/lS Ɩ_6.,"JFV!zn^3T;Fe@9/[k.$enέNlesB 6sjcs7f WkՆ7`g ȘJj|h(KD- ?dXiJ؇8x$(:7˗s]Zj{rb&^=^=rO=:y IXO#ӯ_>/_>B f'>{O~q|SQ>169B<ø3'#qSg@v螊)fUqwO{ToN8sDbh(vѺJNZqVqmooAؾg{ X$! wݧԱ.|}:VdHGN m2Z3ڱ=j[EBB`V1!aoq!Y෰&9 I )ޒw0Vw4vBу*0e?F8NDe{B= ~Bwߣq. )DK`jc3 llc&lMU)}Ļ'Xx.yw<.峲`{u` cS&Nj1elܒP[}Ǧ4f.،ANȮ{ZH(3ѡD)p3ݕ5 ueφM}j ^cAsE+ZY\˄²DY]OfjmŒKšP (^ʫpJתp x"]$#Gz>'b v*|OzZI[K} mgqRY]c{of+_uv["RmaY U,њ`֋Z7?6 Z2_]Ѷ"bGh&buz*z0~4mm%,WXg1K#ѭN<-q1Trfq_I ZJ9gK >\ t=.Tā҈}2!ZB^CP/ȡos0i >OC$(G*-{zwY,d"4]i!aĆzoPn$;sAP9|s8,+&' |l2>MAۿbŮjǛ{geV# PV ZYڿιZƚ[r3xq~YD) >#&:6ha6Wl4ANYJ'mο߅S3;i8s9x,-45xtB8?ǘ[oO|wfFL{I&:"ox M3=X!:P$@o^TCT7 7!0[8[q7E6Lzx]j*\v*G/vbY"G%^|&A/ %jK)<&,v2H); lc ʢq$ڝ#LT݁1g4ŰA {/i}my >*󠝒7Fycm(Җj,Xrmox86th˂ r`PK!Ikixl/worksheets/sheet1.xmlMs0ScvU f2ۜeX@."x̴>xVZ«b{0V* D#mqfQTP˯ƒ6϶@F xX/<&t LR 5gk"uI?J!+*,̿h, t+VĀHB֖a*5b_՘{q蜿K83C} BJ Vf h݂FQ$(HxLz8smZqoX )\j$S,5L>^#|Ї[yDWE}`/*֢~SI(5~YpV}6G^UCv.sg㎝^h'z%:eM٪Ϧ;3lQ3u.l~Ζ}:נ=ZU\V)Lgq3Podm5.߀՘fg/2mL7pWLFo&,4n"^kFHlga-{JەFWAkZV'zLzk]P2$/kGRUA}t)0`~Cc?:Ͷwb/ /Ʈ{IPK!)? xl/drawings/vmlDrawing1.vmlV[k0~?/Nc;uۨvSVEXcluwd9Kaek |wCIB64\2dPЦP7=~Lf֦}h3 I9+b+XPњ\Nm Kv.{>&I\U)w7Qy$x-ڇAwA%FLW+Uъ>9d*XRfk!\fSȼb\ mRaz@kgUxZ׳SJ(8{+%qTB-Mٴ4Uj.@8Ks 4vGMNcTBsCBRsҰZNfEsɹGd&@AzR= ow[3I8V̖6}84~nۍ6{ᑀG* uμfϺA .ZL$\6oU sMmӎ&.6t.i镲3I>NpwdoBW4PvEYr\$I$əOF>9ŗ> o [>fVݿRZڸl]xӸ!lQ.Fj$k~MB653R U K ?_P,ZGp7,*uKDt—&8')ÈQB7EI j"k[#Z-c&LMʤwLNTyI}^wc PK! xl/comments1.xmlJ1}.& EAŃ>@؝gno&_~I@;W˒3t ㌢r2ޡG$Ţi"dH!ѥJU1a4T ҎF}i rRu:ES$,`/,?w2!54DlL_!I[bVjsbu17Hn 򛣾.GU,<\W檋DVM4Y9#PK!QA2docProps/core.xml (|N O;4ܷF.&j̹pSa\і@뾽SƘp|lʭsS342X|j}##~CTr,(MDCj5!ݛ@+ 54`c`K7lL:i>[8?],3zF͍R@R+MA,wTSA֋yٹGԛ ۮ: Bqr$P]OVd -BM)kA (YVU\{HJ>?Vf<Ŏ+ FUron߉y朝rVGwPK!c"docProps/app.xml (Ak0{V% !!P:yb"$wl7PN3oO#lzU}J<W_E ]rQw"ab4L{:MS'Y>q隄S3JdzćO'5>=zy#g"g }8M 9>ƜR_?5eva;@fawn,H@Rx`}eIiCDq,xYt"07;;]9ɲNGv3eυhJkp6ԇSJw 4s6 |z{66$w&wݕ8]UKg X 4?-{%Zx.'/'60N0-"Oe <.Y4K AcN^9ćw~qL_Hªg,}o5p*MS gBvڴ_ςo\sz?0G?JUU[k ozj{|iB@AqiR׷5)C}rx&Y"%%78D# iu˭g'|}~ZނS4`/#aUl wY̗R!LmåoO?hy ˱A]X\w6 e)52;2y Z;lFf'/눍J'qoNYn<6v`Sb|{0Yw~ 9ݖsևd8sn^Mܨ1s997iF3ϹKn:lt8sn֖s6+9sQ]3vЭVzqI2Iƚ̆ ˛t+'0O q&@7rܾY;AyMnдyMdoxq&7sMZrAruٖ.t2"#yqFl) ts/Tyux* : 'z'6ȚvI:~yg准&d,zM!@Yg9rYPe!QO0>fUq@QM|]=yqw뚆Qy۾Xޙ{o&> Ϲb$:W=R$%o*},Qnv`pג`&(-C"D&8)8h|n,!$r4rx+n$ˈn:>K +fW-s\+- dRY:^ph9 =e>aEX;)E7w҇ÛYw+IYOWZkw4 |b@44TE=D1\N{Cz((u:(*QtRI#v=(*n}(O4L?MNu3N:]Us Vg+>ZD'0-,$IQ ˴ʤːHQ,,C3EZReHJ8S!ɨzL2%Xb`+eZSeH/ yǽTh v1˴ڗXE=%X־tcjQO /sL }阫,SeK\,Ӣ,k_:`aYq1qqRX: kq'{p ]Caօ1.WX?UN1|&r#W^Mw(L}m|W>g]&py$ʅH6KF>3$> qЈ&rƋlmsbAש+ND;[p ԛcKVߍs?9.*Kz(Y: ᬜhF@̜ju.okgW"NWꊵHWRu:_e:%rsЏ'ʧujZ͚VX:62EaݬQe9#кu[enrBE'V C7 =-^ZEsmU|J{&A[t-߮u3F+F|b-)$.e[THM?MLztkd;O}@y%< -]V'@$~8DN # &SkdBnLOߞ~@!$(e^I›RTB!oJ?Iݼdk)y'7ն1Y!pqI.Ȟu>H: fc]{4yXȃynh5M˞{u9:4|'N72_/ezk:s&џi2aIoVa.=-%&4@=klоC68 dSF\`Y=Huocf4b'1{":R \ibןqP|`hf4"EDHnB7]17ni'p3BJx9o|F-rpb5+^Ed ,2h=PfXmaJ%&"$E" UXhh6+$,b!a1 mZHhwMr4EJ[e0.0p[8`#Xâp`1)  fÕQlXBB‚`a m [HhXBBEh ,T6Q* ,xaٰ7/,,~aa &wa$XlWX$Äa rh#XTÄ"&P!a它z`*YevHr GCA8B@p9$i#!!rDw@Z ]jBW0FЅ 1,MK`wK )t]*W9ݾTo累iY_Nf4-;}>`.AAmWbpOiS>ظ7c; l\t|ܶx%{(& |3 p`$x[xoko_}Ey1GM PK"PKp4 styles.xml][s~pݙRH.٤aĻ}$DaB>W/]DٴL6s'S!92T6vP.߾h3v^#.l> ѝ#5ERTc,0P8AhQ^љls!\lMmeKmB!`+ۘ2LXSikE-<T7 ]nx\v.RC"z&C dED@Aͫѣ+͈G{47pٽcG޽ctⓙ~*ſ@|ٱl *PDc$TkDO N-A)n~hLԙ9MU% !b6h{&V^$ P&#oݍB,U BXJT-\@V>v d&OR~9^c9@`%F1[5@EQ$տ=@l}}UA HqA~% a6%4ً{("jFO9OF@+$UѶҸg;ݷ&eI{xls`kTy{uOHlNasto,޶,I&54zNfCS3}خ F>`4ZnXlpj(]šsz;a^k@e06JAjkO T!8Y]eSվkzi}2M+oI4 /y2,G ]A. ,5aDŽ=i(Ӹx eE=͜Wu'WI9Jcuvպǡ/ pLmcஇzm?|aq,2t|b+~K\ahk%bU,2aj }'g^uιi̺'eN }1bvR!L/L~bqoʬ0b~#L]14? <ǔ$Xmr [-9[Sy@9EG0!ѕw+S3{0cJՒo#ydJag+9o}]ksoZ=]묹;Z;,m|ɵ2ʮZSH2$ B0r>0r>09j9=a20/`J[Ș&}zV:/)ae{ْq!{YK5NfjmdvP 0?;sНb=7-Awsi!kY]=K`YzG^-LKŠ*PsԲ ؖ}WKh妤{lBYM*5! BV l \s$D"EO5J#a+CFKeͅ4cZqS`q͘Ƅ^{jWQ2˜,&WM)bRx۵ϋIًPqϟZ3˼b߮U%+bM|Wzc %tQ,Re&&oE GV5w ,n>Dۙ~zsV7OVPKD aPKp4r7-(77meta.xml OpenOffice.org/2.0$Linux OpenOffice.org_project/680$Build-8825pc092006-07-04T10:45:04H.Merijn Brand2006-07-04T16:04:452006-07-04T16:01:26en-US2PT3M19SPKp4Thumbnails/thumbnail.png헇3C Q#",у艶X5Doj=z Dh,Q6Jz*o~3?μw3s9ߙ;Q'{޽{dT ;ѿKqkW vWJl_I3/]F"B<(NiCn /YRSՎ)ufeJ!&Tiލ (f~m19RPRI "/h~ƽO퍛-J;$B|{$K}u /o+'pxa|KmvwW(C&W.wR~ݤl%5=mnw8oUH1##r=hoW6h`EsE[`g.+ZF|Z6k{%bdNE TvhsC; 4A8돛λW `AlbW]+\Ȯtl%BZ4{yN^rgBY'G|,6?_{|nApyrW^@k̏1GА"j ֦ w@-5 L@~~zs/x5 LMCX"?QXyx,Y}!_?V~] 4C3:Bfo`ͦ:/_? VF`4 w_AP LbG~͉>F<.&UB;mJ! W5>ڑwk$-1Yi+8 em8xuo=־U˦h~>x> Tu[߫CxeO /vefs ᾨ gk+Fx_*ݳw=PpPS^sXw犆#h_p3 V _Dm:g&zh1AC -r™\XRF[ޱ:w:Cؼ\hKH hvt*Zm gh{;i<_|̽eI{ fՠEwcbxg,ݍPi QOHQ;Iţ+&&ȕzbD ħF,Jޏڮ@C$;$#0JRG.h@hw.vҡdzO:X$:,Ր+!HN%[~ޮ˞/JmJ$fbRJ}vKUգkj֋rm+eX!*w``B}[P6]X{YmU6WNfR/'&-G. ݀nIV7t՛wלpH ;<+ICRuS77]OY*[nYdcE(穴H(y\ZIْ,;J+O㴵f[Ue=n-dKuH̏/[vU%9 M> (S%zvȥ8Y|P{B`Mԩ"m+HAf/P'"(>ÂȂsR/Z:]q?zkPgKZyGHꆿIKʴ0z/=%~& wRd,MIzUL^90ֹ*Xv~=0`hXh~V3o͝lPڻJ7"CV191-pKG;+A`rT7@65YDLم2jZ1N Hk >^MAx4Q7gp̿߂L%Ŏ~nٟ5 ܑQ43kx[}#oZ' ٛVYD-$mS"l޳jca,ڬ!ef2c1_04MnqNBG8 \mb3J^[oIU>%eTwߚ-%}aIOq/L,is`\Ϣ=H}1s= p,_h_GKkp=mDk|k{~SbHb em6~p.d&KCˎ{ wD"kdJwe 8l1iߺCae}~B̈ENףyN珝'^Ŷ}} ;j[U)ZtY ;qʪZ9l*yՔF*`󰧏If~S 0(ާX\$yz ĊyWPYNcI]Lr`_^Sw^SoQOcΟ8+꾭.WU)&*vd;?LX:X@"siAZѽ-#X,{=f,*N AxVkfQ骒1R%CCI%w+򀑛F/ 3zZJ޸%Fۣop J1F/=&-e/qLԳд6A|HRBqVȒE8NDT.ۊnsSOOwW,|gM,0w'}tut4Xh҈ԁU7W@}xft^28Ci V3_ P |Gd+R'yHá+60HG \ K;iQǚӥ>Q8v)#pQ>&{Swe? _v}͢jY_68n5*l19iMq٬7NH^*W3)j<9p 1 _%OX/R'$_wp3jn9{7Wxz aaTvP*~R և )OncVuATEN]01@ rOJDd##|O0!|f{<yZij)Eܺvbkٲ÷*O~]eˠM9hF4KO%y\HZaoUkV=i[ڂ q1~l`@iJOuX¤ ?StjrG] (,ZҾ:TqZAxY|ȐonDԔoWWYKz(>s_]=,?roܦƻ-;Tw2K=[Y܍sXh 0>y>x2'N0訓tbahmu铻n| 5_=f8 %[A`@ek ݲU%6VJ>t̅չc6 O}W;$UmTldCSC&fH{!GqΘ2<'S+1[]S!":,M\x D/c vɇluu}ylV:^F֖42.CԷL*ӇKfԨg(LуIu#1,_[C~OC3^dl_I6rogCWwD 2f.%"ќ*0';&Գɮ}CŮ;%œG؂ '.f=-ՆzDFUgrAg`h²B?ݔ8{ s$88 IK71uJWyƵ+xcp;翧H1+,Lc;Σ jn> b |iK$ Ru\e{J(9C|yeY.sp,uiàx9/oC-±S=ʌJz[2pWW:ܲ7^ciٿF|9q>AtE>e3U^uSLd+XZ"wWp\\1oq{NRxDcˀd=KIR:PVv֢ qz qƤCO(0кbAi-\q(i_os-JԳu|́炩(1gӹc@ҰR.c!t)򟚽UtϾ'cF.4k󐔜x`2|`xF,Cr^#4Ac_0cEkJʬ\HٕԼzYZ"|".|O5HK0cP.uurTʕРNR!}opG$g#˅5kGCUsg@M1ǸqUVwiu})oV}ȍtITBާ\!%3`Gx{ I2cƆ\6^e{eOvhF$[w9.䣔GЌj<"fW_^~zwWqڤr>Πe|Q׃}-hD0Ic0Y9EXxbKϐ 3;GA7~Uڥ8CAIl(AFc)sTd,/:_wSh$r/cƎhq/xa݅NJVDEdNQջΟ[Ȍ &u,FY Iw\Ҝ zCWt${d9N}cO{7v}j ,RW&Ovϳz=I$EJbwNKݗl24īOgB,IU qPـ Fْ, [:[ZdA[w_]54<]O0DWY6lL;78OVlH1l+i?kfΤȴHejXHŔhl<-^@[`{'%w1VPfP55%g!~I[Ψ~ 9Ne%J]0y ૵h.rL{s 5 QͶGrmp{ m0&L+ޤ,i4'ⶺ373 iB/i2 Tj s9T30! HK&re_9ޓr.+'@Yl/$$xC.72:+qIw3R\1#`v9֨ J f8}PBBb`xM&, ]Pܝ%,8A J+2sq*0MgqH`;\)4y@ 1x/lx|;qNDVTF`\Qi\q11f7S}D԰VpU~$YIFCxU(ᚓǨ w)jqmLmd3G~~vQ~YeJSƙ>c`0/54ܛ̈K~X+B[$W?,f\73Q},zblɑ,e!-;5Pw% EJ'r~2TU+:0!Pm09W,o~gȜJVV&b! 7F) uY͎4Dt {#ɟV }d b3VXI$@J'bwgţvp&ښt"C{I{#>t=Q<Y9.\~%o)ˁ[:*JVaPK+\dPKp4 settings.xmlZ[SJ~?)J VEmdt2\ Td._wf#{S3zP9NNlH=<` "t*qpZgH`QQv@oGDsBaIzaѻj3'G{MY+B|(niuX~E@%x4GhJd}!|]5mռsFX` -;WJQ<.|%< bGKowꕣ)}LMZQ( aIh)$W5җ4@zZ)~AF .aKwֻn/#ga?3*+@r\Ʒ0rۻBOh\,;7l@7Y7cZšXeKl |dR2 +?ub)ΆAj9 3 gB3Ü?ro0¾L @r #u݋ɦ(ڼVO 3B,Vʾ1c@d 3h1 DOS]F #x@D@z1clX'@` k&w8Y9B<MXEa\VR= n]f]3S=чdLDH"L$$$7: ϊ3 & _$n ,O8Z3,sjQ )(eBgrzqCQ_yǍYܸi;H3Ua򐔇?#$NHBoIUǵXs3 \9oXHa)sa ؞^5O4 | 5+_ GMp謹YoZ9GC{4* rU[>lss}Yfpza]=ԯFJ9.g]"W0a+ʳf-*V{T߆~#A1lfH͹"les-DW785F& Њb&4QFO"L"Ig<3BAJ":8gV QR*S;y{X>WXcPK "y.")PKp4META-INF/manifest.xmln0wTY*! ,%g+>#x,m_;]۰-t: tbu=d4/gjZ@/j:c7Ƕ@۰b/Զ Rx;X J{X^PK&.PKp4l9..mimetypePKp4TConfigurations2/PKp4" content.xmlPKp4D a styles.xmlPKp4r7-(77)meta.xmlPKp4+\d"Thumbnails/thumbnail.pngPKp4 "y.") 0Asettings.xmlPKp4&.FMETA-INF/manifest.xmlPKwGSpreadsheet-Read-0.41/files/test_m.csv0000644000031300001440000000005010614362642017064 0ustar merijnusersA1;B1;;D1 A2;B2;; A3;;"C3";D3 A4;B4;C4; Spreadsheet-Read-0.41/files/misc.xlsx0000644000031300001440000001755511130422501016732 0ustar merijnusersPK!XVƏ`[Content_Types].xml (̔MN0H!%nJ?Kؓƪc[gJD5f|MقM KJ]u޲Jg`@_^䫃Lb(+f΃҅ZD k܈5drålLc ZA!>|Hj=+l &7ZHΪo+K-A9+kŮ!ƃm>PXdJ51yz 3ʶ}avL]ؼ9k* s-MoGN TIBpbM ގyu5NC zr\o/xvB8ޝgx_PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!DGxl/_rels/workbook.xml.rels (j0{Ӗ"R !$} n\E3^}PY Y"[ % #1z#g],khE˖Édva0ehЛdBgIdοqtOöK+d9M/K8T~W6Ͳ QltQ(y'47]b[5QNp_y}ġQX 6l$AT2ĝ$:ZU•Bk2.^C,0 ʘt2NE!%%<=f0PK!iRVxl/theme/theme1.xmlYMoE#F{oc'vGuر[HF[x=ޝfvg53NjHH q Jĥ@wfv;&%!>Ǽ3zA/DҐi;I1f<%`FdpmwM O&nRʊ a<#)p`"Z | |Z$JqloO&4$4Kl{ $JꅐfMr]*΅"g:¬1?*@ K/A|+x3'bj mo>9]N0>\52E4*֕0z^g8 TKgQ<+ uw֬5\|ڂέNlXd67 o.nwů/WZ o@1ZϹ g7 orP1Zl Eɰ)RLpyHP%M+oR(0$CA30Ĝ߫߾zz᳓?̏U}ӏPBs^|gO^|<UCnct8՜(1uO 3C\=|XLHލ9puUpF~bZ`|ũ4Y$nL5tU(CB<ݣ |=:z]2#'D7hqlP;ٻ:!G. 3C7^S!NX7}Jf"zRA#8ꍉ>}C})=9"wa7IhWCHQ[!ӥK7;4rT'~3:ЩϚ1Ѝmm`&_I8ՂwO}onjv`fLNO@)͠,aaQ3")MY _" \}@U%}aV.˒LFUԕU{DŐꦛmNW(CNޜm^S4 |l1<gW{Ow(UV^o9Z۱,^mA-r ?Q2bXoC~  d%;x 'hYY棓vR)gks:\qN-^s;kK] =]4)N2&0懭oO|twSI&aI`=DCPK!Lɑ- xl/styles.xml=k0B( 4v(PH ]H09=َcOXu+ٷFA9jMg'-Su:<> v[ۘ7RXlUb!xs7ŒYڋIcJVq/D!y4(d@ho]x+3=37!jtS]{f:L{PK!k3q]Dxl/worksheets/sheet3.xmlQj0BZvJۡ4P(b-[+M}v ؗffgw߉h2KR)UX[}uu/E$jݡB Eyy1l .R2똠ǝCЪzwj aMc+Xb>2-DTe>~Z_X#ns]tUfWAmGobf͙`Iym2lj(2ߕ׹1SŏOwoj5h%XnEֺ(:hXP:aR7%~TF"% 7tJsƢНmݗ%sd9ytPK!^)2Cxl/worksheets/sheet2.xmlMk0 F2Vv}DM)I[fYzwdWrRoFDʷʡJ!E}~V0n *im@R(Ih)a0>n$jZz!X/z#A-d6K[am[ȏ̓A ~j8X)Xx r{UV` و p3e|BߌszQCMoϒ֊T{<?c"c)Ude>Y TǯOSx9+k4Y\pdu[m0а4~R7%nTE"ǰIgAS˜Sm3^ etk4u,)PK!UgdocProps/core.xml (|N0EHC}⸥/+I%A v=m#lCۿIڐ 3w;r<:*rDE\s9ϔ`V8,no2n(6`}. $(79{o(ƎA2 ͭ;l`;4b nGO[1 AyIBփρ3PʟLt;d 5{Up8$qk#'mF+܊*2)ŦV;J[-(kM8q* .jC-څt^ǫr XLcBѬ$cz7d켚olvy1d])II&hH(PK!=E=docProps/app.xml (Ao0  0 bH;avgV$OzOgVw&WfV J_-" "\ * #,##0.00_-;_-" "\ * #,##0.00\-;_-" "\ * "-"??_-;_-@_-4+/_-* #,##0.00_-;_-* #,##0.00\-;_-* "-"??_-;_-@_-"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)72_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).)_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)61_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)"F"\ #,##0_-;"F"\ #,##0\-#"F"\ #,##0_-;[Red]"F"\ #,##0\-$"F"\ #,##0.00_-;"F"\ #,##0.00\-)$"F"\ #,##0.00_-;[Red]"F"\ #,##0.00\-;6_-"F"\ * #,##0_-;_-"F"\ * #,##0\-;_-"F"\ * "-"_-;_-@_-C>_-"F"\ * #,##0.00_-;_-"F"\ * #,##0.00\-;_-"F"\ * "-"??_-;_-@_-                + )    ` * misc a  h foo8 1@   dMbP?_*+%"??U~ ?">@7 1@   dMbP?_*+%"??U>@7 1@ $ ^  dMbP?_*+%"??U~ @">@7 Oh+'0@Hhx Microsoft Corporationpc09Microsoft Excel@&\iܻ@ш՜.+,0 PXd lt| " misc foo  Werkbladen Root Entry FWorkbookSummaryInformation(DocumentSummaryInformation8Spreadsheet-Read-0.41/files/empty.txt0000644000031300001440000000000011275744326016755 0ustar merijnusersSpreadsheet-Read-0.41/files/Dates.xls0000644000031300001440000004000011057177657016657 0ustar merijnusersࡱ>  ^@\p H.M. Brand Ba==<F!8X@"1,LettrGoth12 BT1,LettrGoth12 BT1,LettrGoth12 BT1,LettrGoth12 BT1,LettrGoth12 BT1,LettrGoth12 BT1,LettrGoth12 BT3" "\ #,##0;\-" "\ #,##0=" "\ #,##0;[Red]\-" "\ #,##0?" "\ #,##0.00;\-" "\ #,##0.00I"" "\ #,##0.00;[Red]\-" "\ #,##0.00q*6_-" "\ * #,##0_-;\-" "\ * #,##0_-;_-" "\ * "-"_-;_-@_-,)'_-* #,##0_-;\-* #,##0_-;_-* "-"_-;_-@_-,>_-" "\ * #,##0.00_-;\-" "\ * #,##0.00_-;_-" "\ * "-"??_-;_-@_-4+/_-* #,##0.00_-;\-* #,##0.00_-;_-* "-"??_-;_-@_- yyyymmdd mm\/dd\/yyyyddd\,\ dd\ mmm\ yyyy m/d/yy                + ) , *     ! " #      1 2 3        ` DateTest`i 08 Aug 2008 12 Aug 2008 08 Dec 2008 13 Aug 2008Locale settings on this PCShort: dd-MM-yyyyLong: ddd, dd MMM yyyyDefault format 0x0E * ^@ &  dMbP?_*+%,M \\dc242\Hold S odXXLetterPRIV0''''`4 \KhCbP`SMTJPDocuColor 242-252-260 PSResolution600dpiEFMMInUseFalseEFMMInsTypeNoneEFMMCoverPrintFrontEFMMTabShiftFalseEFColorModeEFColorModeDEFEFRGBOverrideEFRGBOverrideDEFEFRGBOtherWtPtEFRGBOtherWtPtDEFEFRGBOtherGammaEFRGBOtherGammaDEFEFRGBOtherPhosEFRGBOtherPhosDEFEFColorRendDictEFColorRendDictDEFEFRGBSepEFRGBSepDEFEFSimulationEFSimulationDEFEFSimSpeedEFSimSpeedDEFEFOutProfileEFOutProfileDEFEFSpotColorsEFSpotColorsDEFEFPureBlackEFPureBlackDEFEFBlkOvpCtrlEFBlkOvpCtrlDEFEFCompOverprintFalseEFKOnlyGrayCMYKEFKOnlyGrayCMYKDEFEFKOnlyGrayRGBEFKOnlyGrayRGBDEFEFSubstColorsFalseEFSeparationsFalseEFTrappingFalseEFSortCollateEFStaplerFalseEFOutputBinAutoSelectEFImageAlignFalseEFImageUnitInchesEFFoldFalseEFImageFlagFalseEFOffsetJobsEFOffsetJobsDEFEFPunchEdgeNoneEFPunchHoleTypeNoneEFFaceDownEFFaceDownDEFEFImageSmoothFalseEFBrightness00.00EFImageEnhanceEFImageEnhanceDEFEFCompressionNormalQualityEFCopierModeEFCopierModeDEFEFGlossAdjustFalseEFTextGfxQualNormalEFRasterFalseEFDuplexFalseEFUserRotate180FalseEFRIPBookletFalseEFBookCoverTrayEFBookCoverTrayDEFEFBookFrCoverNoneEFBookBkCoverNoneEFCopierBookletFalseEFCenteringMiddleEFBookletCreepFalseEFBookletReduceTrueEFManualDuplexFalseEFMediaTypeAnyInputSlotAutoSelectEFTrayAlignmentFalseEFSlipsheetFalseEFSlipsheetSizeLetterEFSlipsheetTrayTray5EFMediaInterlvFalseEFInterlvTrayTray5EFMedQualCoatd1EFMedQualCoatd1DEFEFMedQualCust1EFMediaQualityCustom1DEFEFMedQualCust2EFMedQualCust2DEFEFMedQualCust3EFMedQualCust3DEFEFMedQualCust4EFMedQualCust4DEFEFMedQualCust5EFMedQualCust5DEFEFMedQualHeavy1EFMedQualHeavy1DEFEFMedQualHeavy2EFMedQualHeavy2DEFEFMedQualPlainEFMedQualPlainDEFEFMedQualRcycldEFMedQualRcycldDEFEFPrintSizeEFPrintSizeDEFEFCreateMasterNoneEFUseMasterNoneEFPPTSlideFalseEFPrintMasterEFPrintMasterDEFPageSizeLetterPageRegionLeadingEdgeIIFE2IFE" dX??U} X@X@X@X@X@X@X@^@^@ ^@!^@ "_@_@_@_@ "m@m@m@m@ " _@ _@ _@ _@ " ## $ $ $ _@% _@& _@x0000*>@ 7 Oh+'0@H`t H.Merijn Brand H.M. BrandaMicrosoft Excel@S} @v ՜.+,0 PXp x  PROCURA B.V.eTe2  DateTest  Worksheets Root Entry F T WorkbookSSummaryInformation( DocumentSummaryInformation8Spreadsheet-Read-0.41/files/perc.xls0000644000031300001440000003300011131150660016524 0ustar merijnusersࡱ>  F\pH.Merijn Brand Ba==xUn78X@"1Arial1Arial1Arial1Arial1Arial "?"#,##0_);\("?"#,##0\)% "?"#,##0_);[Red]\("?"#,##0\)&!"?"#,##0.00_);\("?"#,##0.00\)+&"?"#,##0.00_);[Red]\("?"#,##0.00\)=*8_("?"* #,##0_);_("?"* \(#,##0\);_("?"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)E,@_("?"* #,##0.00_);_("?"* \(#,##0.00\);_("?"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_) "€"#,##0_);\("€"#,##0\)% "€"#,##0_);[Red]\("€"#,##0\)&!"€"#,##0.00_);\("€"#,##0.00\)+&"€"#,##0.00_);[Red]\("€"#,##0.00\)=8_("€"* #,##0_);_("€"* \(#,##0\);_("€"* "-"_);_(@_)E@_("€"* #,##0.00_);_("€"* \(#,##0.00\);_("€"* "-"??_);_(@_) 0.0% 0.000%                + )     A A  ` <Blad1Tcc F   dMbP?_*+%"??U} I      @@$@$@y@@@i@@@Y@??D@D@D@4@4@4@$@$@$@@@@@@@ ???~ D@ Mbp? Mbp?~ 4@ Mb`? Mb`?~ $@ MbP? MbP?~ @ -C6:? -C6:?~ @-C6*?-C6*?~ ?-C6?-C6?Mbp?h㈵?h㈵?Mb`?h㈵>h㈵>MbP?h㈵>h㈵>*bh22222266>@7  Oh+'0@HXp merijnH.Merijn BrandMicrosoft Excel@x2m@xp ՜.+,0 PXp x  PROCURA B.V.WoA Blad1  Worksheets Root Entry FWorkbookSummaryInformation(DocumentSummaryInformation8Spreadsheet-Read-0.41/files/test.csv0000644000031300001440000000010210701240203016527 0ustar merijnusersA1,B1,,D1 A2,B2,, A3,,C3,D3 A4,B4,C4, ,,,,,,,,,,,,,,,,,,LASTFIELD Spreadsheet-Read-0.41/files/content.xml0000644000031300001440000001063410313232324017246 0ustar merijnusers A1B1D1A2B2A3C3D3A4B4C4xxxNote 1xxxNote 2Note 2Note 2Note 3Note 3xxSpreadsheet-Read-0.41/files/Dates.xlsx0000644000031300001440000002311511130422501017024 0ustar merijnusersPK!ȣ4v[Content_Types].xml (Tn0W?DVCUU]-LT b4T4DÌqDl ?t4*f;+@{졗Fio{SmAg`2k? Ly&`Cwvݙ|^zv*uJw}\Y%ACB$qskMmQ6-<+ց_ݥ㸋G|g6 PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK!>xl/_rels/workbook.xml.rels (J0nӮ""Ej}Lm2㟾ۅef2k&WP%&w ޚ[= &$W4KH"xR㣔dNҨ9ɨAw(7ey/O ނhm| }Dg"$4FY.2#59鳔Y]bd @%s"ݚ0tB)[ȓPK!bLGxl/workbook.xmlQN0#ijJT5 ġgoi@qڧ3U Fb`+#>{yȁ9ϵh,j0ỉv4w(rU-w3ӡIml="A8^D-K SײXT}AU][}VwYH9f? wOT4?"-X^ɛɯtasb/qpƒR 3@^|A)|C8ygSY$"Aچ{ܑ:'RRb" ÊԌ!,c7PK!%xl/sharedStrings.xmltj0 yF(KiSm`b51$r)}1(קɮ}?8rLT(@SԔmV(`|KuBVk`2K\VdXiuyrHc%cynҘH 4*L'rtV)`35jqVi+ejm.OE @𾽶h(+aVUS}欇*5Ã:˫"?~PK!;m2KB#xl/worksheets/_rels/sheet1.xml.rels0ECx{օ CS7"Ubۗ{ep6<f,Ժch{-A8 -Iy0Ьjm_/N,}W:=RY}H9EbAwk}m PK!iRVxl/theme/theme1.xmlYMoE#F{oc'vGuر[HF[x=ޝfvg53NjHH q Jĥ@wfv;&%!>Ǽ3zA/DҐi;I1f<%`FdpmwM O&nRʊ a<#)p`"Z | |Z$JqloO&4$4Kl{ $JꅐfMr]*΅"g:¬1?*@ K/A|+x3'bj mo>9]N0>\52E4*֕0z^g8 TKgQ<+ uw֬5\|ڂέNlXd67 o.nwů/WZ o@1ZϹ g7 orP1Zl Eɰ)RLpyHP%M+oR(0$CA30Ĝ߫߾zz᳓?̏U}ӏPBs^|gO^|<UCnct8՜(1uO 3C\=|XLHލ9puUpF~bZ`|ũ4Y$nL5tU(CB<ݣ |=:z]2#'D7hqlP;ٻ:!G. 3C7^S!NX7}Jf"zRA#8ꍉ>}C})=9"wa7IhWCHQ[!ӥK7;4rT'~3:ЩϚ1Ѝmm`&_I8ՂwO}onjv`fLNO@)͠,aaQ3")MY _" \}@U%}aV.˒LFUԕU{DŐꦛmNW(CNޜm^S4 |l1<gW{Ow(UV^o9Z۱,^mA-r ?Q2bXoC~  d%;x 'hYY棓vR)gks:\qN-^s;kK] =]4)N2&0懭oO|twSI&aI`=DCPK!z7 xl/styles.xmlWK0#,47J"E7vZ#?6]!7<<'K)3*FLr5O%F%KU:{*JcR|EU`Tt|)̣4 IGHpZNPkeS|ڼB .O:.RmzO(Ӿo<i4 y֗=NK,K YR="ؓ" |vǩ 9h6+ʖyr^A$䉂 m6:w $ĽȒXˌU ١ _U~ݎsCV#yY2ӆؤf ë, ou ϙVKPNZh#TY3!QE'a7:]!0q]݅EˢQГՈ#Rb3f&@v:GAeԠs%$.\d3E m#8m8df[|=Ͷp9_˞i?j@=\ru8vT9?"4@/uv0v^%)֖V; 8#uZӭġt%=I⅗a8\2mQ?;MnmUຓ;$6%f5m;\˶g\F]7( cWFy-UA[v|Z{wU7 PK!s 2xl/worksheets/sheet1.xmlU]o0}`}$H "@>Lm}vXM6ݯߵE/s?]^ Q)B(/D&ſ~}HiKNSF>ZjJ5\ֺ[*j5TBDPnIJJm( %ca!'*VЕ(-!W5Ζ%BV)/ U:F<=ІcOB<=LQYH v4MyV Ά=rKd9sKx?+^]Bu1CcP\}7O1ǗI:HA8/5;S(gS| `-oxw媲-[*ĖÎRg1[ڂxrWCԬ^ ]k@E.xEM9Ȇ~#røB @&%pҕ{7Т3IhH# WB@C|`Ax :m)Ԓ0 BYu,h>I4*L/mpwV m#uinPK!" 'xl/printerSettings/printerSettings1.binUrDm'[*ȑ#7NPN6˖z-$/,U9ڌ5(ĜA/8rH*8`4_tRX)s A}G䏇^>?G)Sxup㫃C|?: ^xû&Q<ό/@>:{a-xc:uSz/?}ryI6vT'st;޻GgE59nRoOgU}}LCt4 sn%%( ART:9<"Q8N% |[\η2@qr*kÚd-7 j*S(D3t2lF\}#Mz1lXapebRt-h>^XkXam*LFa2)8OUfjJGJ.3Ah@mUHmH2E[@@+Xe 7%2\r+ _U[C/¼-!nJLS&+_kXQd 4F1}DB`#9҃,J˄ n 3ٰ*L#zg&b)miW ,=[.K6n((]7K)xCCCNSknI6R굏`Z,G#Ck/hmhPZq|!Նo*&2Ev 7k8,/7UzxyOjg%fn%|Xa}xU,5뾗Ɠh o SplC"QEQ$X;w]>9FI3Ԝ(K-yZaF窢NY[ٔ3ȷ3fgf\/(׼{/I9Z*X?v%n' ?,0tRtP YԿؖ,{=N:,%6HAlF+x2PνZkc05b`|l6ċ908@Xawã]]q{˾\I?};_>w(GX1/xHs Y<*}e^o؀IPK-!ȣ4v[Content_Types].xmlPK-!U0#L _rels/.relsPK-!>pxl/_rels/workbook.xml.relsPK-!bLGxl/workbook.xmlPK-!% xl/sharedStrings.xmlPK-!;m2KB#? xl/worksheets/_rels/sheet1.xml.relsPK-!iRVA xl/theme/theme1.xmlPK-!z7 xl/styles.xmlPK-!s 2#xl/worksheets/sheet1.xmlPK-!" 'fxl/printerSettings/printerSettings1.binPK-! O`docProps/core.xmlPK-!S`E docProps/app.xmlPK &#Spreadsheet-Read-0.41/files/macosx.csv0000644000031300001440000000164311123134730017063 0ustar merijnusers"'\'\\'\\\'""\""\\""\\\""",,,,,,,,,,,,,, Exported 12/16/2008 10:30 AM,,,,,,Category,Category name,,,,,Category name 2,, Username,Last Name,First Name M.,Section/Group,Status,Notes,Assignment,Category name 1,Category name 2,Category name 3,woot!,dqwdqwd,Category name 2 1,Total Score,Class Grade ,,,,,,Grading scale,Points,Points,Points,Points,Points,Points,, ,,,,,,Points possible,11,11,11,11,11,11,, dcwalker,,,,Dropped,,,1,34,1,,,,109, jdr99,,,devs,Active,"qwd qwd qwd",,12,0,1,,,,39, jlaney,,,devs,Active,,,,2,23,,,,114, mcrawfor,,,devs,Active,"line 1 line 2 line 3 XX fwe and so on yea!",,,,,,,,, ,,,,,,,,,,,,,, ,,,,,,Mean,6.5,12.0,8.33,#DIV/0!,#DIV/0!,#DIV/0!,87.33, ,,,,,,Median,6.5,2.0,1.0,#NUM!,#NUM!,#NUM!,109.0, ,,,,,,Mode,#N/A,#N/A,1.0,#N/A,#N/A,#N/A,#N/A, ,,,,,,Min,1.0,0.0,1.0,0.0,0.0,0.0,39.0, ,,,,,,Max,12.0,34.0,23.0,0.0,0.0,0.0,114.0, ,,,,,,Std. Dev.,7.78,19.08,12.7,#DIV/0!,#DIV/0!,#DIV/0!,41.93,Spreadsheet-Read-0.41/Makefile.PL0000644000031300001440000000472511430446007015734 0ustar merijnusersuse strict; require 5.006; use ExtUtils::MakeMaker; my @exe; unless (exists $ENV{AUTOMATED_TESTING} and $ENV{AUTOMATED_TESTING} == 1) { for ( [ "xlscat", "Convert Spreadsheet to plain text or CSV" ], [ "ss2tk", "Show a Spreadsheet in Perl/Tk" ], [ "xls2csv", "Wrapper around xlscat for easy XLS => CSV" ], ) { prompt ("Do you want to install '$_->[0]' ($_->[1]) ? ", "n") =~ m/[Yy]/ and push @exe, "examples/$_->[0]"; } } my %wm = ( NAME => "Spreadsheet::Read", ABSTRACT => "Read the data from a spreadsheet", AUTHOR => "H.Merijn Brand ", VERSION_FROM => "Read.pm", EXE_FILES => [ @exe ], PREREQ_FATAL => 0, PREREQ_PM => { # Core modules "Exporter" => 0.00, "Carp" => 0.00, "Data::Dumper" => 0.00, "File::Temp" => 0.22, "IO::Scalar" => 0.00, # Optional # Backend parsers, all optional "Text::CSV" => 1.15, "Text::CSV_XS" => 0.69, "Text::CSV_PP" => 1.23, "Spreadsheet::ReadSXC" => 0.20, "Spreadsheet::ParseExcel" => 0.26, "Spreadsheet::ParseExcel::FmtDefault" => 0, # "Spreadsheet::Perl" => 0.00, # Not yet # For testing "Test::More" => 0.88, "Test::NoWarnings" => 0.00, # for ss2tk # "Tk" => 804.027, # "Tk::NoteBook" => 4.009, # "Tk::TableMatrix::Spreadsheet" => 1.2, }, ); $ExtUtils::MakeMaker::VERSION > 6.30 and $wm{LICENSE} = "perl"; my $rv = WriteMakefile (%wm); package MY; sub postamble { my $valgrind = join " ", qw( PERL_DESTRUCT_LEVEL=2 PERL_DL_NONLAZY=1 valgrind --suppressions=sandbox/perl.supp --leak-check=yes --leak-resolution=high --show-reachable=yes --num-callers=50 --log-fd=3 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES) 3>valgrind.log ); join "\n" => 'cover test_cover:', ' ccache -C', ' cover -test', '', 'leakcheck:', " $valgrind", ' -@tail -5 valgrind.log', '', 'leaktest:', q{ sandbox/leaktest $(FULLPERLRUN) "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)}, '', 'spellcheck:', ' pod-spell-check --aspell', '', 'checkmeta: spellcheck', ' perl sandbox/genMETA.pl -c', '', 'fixmeta: distmeta', ' perl sandbox/genMETA.pl', ' ls -l */META.yml', '', 'tgzdist: checkmeta fixmeta $(DISTVNAME).tar.gz distcheck', ' -@mv -f $(DISTVNAME).tar.gz $(DISTVNAME).tgz', ' -@cpants_lint.pl $(DISTVNAME).tgz', ' -@rm -f Debian_CPANTS.txt', ''; } # postamble 1;