summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes7
-rw-r--r--lib/Spreadsheet/ParseXLSX.pm67
-rw-r--r--t/bug-38.t11
-rw-r--r--t/data/bug-38.xlsxbin0 -> 12338 bytes
-rw-r--r--t/data/hidden-row-and-column.xlsxbin0 -> 7467 bytes
-rw-r--r--t/data/hidden-sheet.xlsxbin0 -> 7397 bytes
-rw-r--r--t/data/target-abspath.xlsxbin0 -> 6927 bytes
-rw-r--r--t/hidden-row-and-column.t17
-rw-r--r--t/hidden-sheet.t15
-rw-r--r--t/target-abspath.t11
10 files changed, 107 insertions, 21 deletions
diff --git a/Changes b/Changes
index 0f4ec79..0857e9a 100644
--- a/Changes
+++ b/Changes
@@ -1,6 +1,13 @@
Revision history for Spreadsheet-ParseXLSX
{{$NEXT}}
+
+0.18 2015-09-19
+ - Fix 5.8 support (rjbs, #39)
+ - Fix parsing of files which have empty worksheets (for instance,
+ worksheets that are only charts) (Stuart Watt, #43)
+
+0.17 2015-03-25
- Fix using_1904_date (f20, #31)
- Add support for get_header, get_footer, get_margin_*, get_print_scale,
get_paper, is_portrait, and get_start_page, and also fill in the
diff --git a/lib/Spreadsheet/ParseXLSX.pm b/lib/Spreadsheet/ParseXLSX.pm
index dca3c7c..4c446c9 100644
--- a/lib/Spreadsheet/ParseXLSX.pm
+++ b/lib/Spreadsheet/ParseXLSX.pm
@@ -1,7 +1,7 @@
package Spreadsheet::ParseXLSX;
use strict;
use warnings;
-use 5.010;
+use 5.008;
# ABSTRACT: parse XLSX files
use Archive::Zip;
@@ -178,13 +178,18 @@ sub _parse_workbook {
my @sheets = map {
my $idx = $_->att('r:id');
- my $sheet = Spreadsheet::ParseExcel::Worksheet->new(
- Name => $_->att('name'),
- _Book => $workbook,
- _SheetNo => $idx,
- );
- $self->_parse_sheet($sheet, $files->{sheets}{$idx});
- $sheet
+ if ($files->{sheets}{$idx}) {
+ my $sheet = Spreadsheet::ParseExcel::Worksheet->new(
+ Name => $_->att('name'),
+ _Book => $workbook,
+ _SheetNo => $idx,
+ );
+ $sheet->{SheetHidden} = 1 if defined $_->att('state') and $_->att('state') eq 'hidden';
+ $self->_parse_sheet($sheet, $files->{sheets}{$idx});
+ ($sheet)
+ } else {
+ ()
+ }
} $files->{workbook}->find_nodes('//sheets/sheet');
$workbook->{Worksheet} = \@sheets;
@@ -211,7 +216,9 @@ sub _parse_sheet {
my @column_formats;
my @column_widths;
+ my @columns_hidden;
my @row_heights;
+ my @rows_hidden;
my $default_row_height = 15;
my $default_column_width = 10;
@@ -252,7 +259,8 @@ sub _parse_sheet {
my ($twig, $margin) = @_;
map {
my $key = "\u${_}Margin";
- $sheet->{$key} = $margin->att($_) // 0
+ $sheet->{$key} = defined $margin->att($_)
+ ? $margin->att($_) : 0
} qw(left right top bottom header footer);
$twig->purge;
@@ -260,9 +268,13 @@ sub _parse_sheet {
'pageSetup' => sub {
my ($twig, $setup) = @_;
- $sheet->{Scale} = $setup->att('scale') // 100;
- $sheet->{Landscape} = ($setup->att('orientation') // '') ne 'landscape';
- $sheet->{PaperSize} = $setup->att('paperSize') // 1;
+ $sheet->{Scale} = defined $setup->att('scale')
+ ? $setup->att('scale')
+ : 100;
+ $sheet->{Landscape} = ($setup->att('orientation') || '') ne 'landscape';
+ $sheet->{PaperSize} = defined $setup->att('paperSize')
+ ? $setup->att('paperSize')
+ : 1;
$sheet->{PageStart} = $setup->att('firstPageNumber');
$sheet->{UsePage} = $self->_xml_boolean($setup->att('useFirstPageNumber'));
$sheet->{HorizontalDPI} = $setup->att('horizontalDpi');
@@ -297,8 +309,10 @@ sub _parse_sheet {
'sheetFormatPr' => sub {
my ( $twig, $format ) = @_;
- $default_row_height //= $format->att('defaultRowHeight');
- $default_column_width //= $format->att('baseColWidth');
+ $default_row_height = $format->att('defaultRowHeight')
+ unless defined $default_row_height;
+ $default_column_width = $format->att('baseColWidth')
+ unless defined $default_column_width;
$twig->purge;
},
@@ -309,6 +323,7 @@ sub _parse_sheet {
for my $colnum ($col->att('min')..$col->att('max')) {
$column_widths[$colnum - 1] = $col->att('width');
$column_formats[$colnum - 1] = $col->att('style');
+ $columns_hidden[$colnum - 1] = $col->att('hidden');
}
$twig->purge;
@@ -318,6 +333,7 @@ sub _parse_sheet {
my ( $twig, $row ) = @_;
$row_heights[ $row->att('r') - 1 ] = $row->att('ht');
+ $rows_hidden[ $row->att('r') - 1 ] = $row->att('hidden');
$twig->purge;
},
@@ -452,10 +468,12 @@ sub _parse_sheet {
$sheet->{RowHeight} = [
map { defined $_ ? 0+$_ : 0+$default_row_height } @row_heights
];
+ $sheet->{RowHidden} = \@rows_hidden;
$sheet->{ColWidth} = [
map { defined $_ ? 0+$_ : 0+$default_column_width } @column_widths
];
$sheet->{ColFmtNo} = \@column_formats;
+ $sheet->{ColHidden} = \@columns_hidden;
}
@@ -771,6 +789,7 @@ sub _extract_files {
my $wb_name = ($rels->find_nodes(
qq<//Relationship[\@Type="$type_base/officeDocument"]>
))[0]->att('Target');
+ $wb_name =~ s{^/}{};
my $wb_xml = $self->_parse_xml($zip, $wb_name);
my $path_base = $self->_base_path_for($wb_name);
@@ -779,25 +798,33 @@ sub _extract_files {
$self->_rels_for($wb_name)
);
+ my $get_path = sub {
+ my ($p) = @_;
+
+ return $p =~ s{^/}{}
+ ? $p
+ : $path_base . $p;
+ };
+
my ($strings_xml) = map {
- $zip->memberNamed($path_base . $_->att('Target'))->contents
+ $zip->memberNamed($get_path->($_->att('Target')))->contents
} $wb_rels->find_nodes(qq<//Relationship[\@Type="$type_base/sharedStrings"]>);
my $styles_xml = $self->_parse_xml(
$zip,
- $path_base . ($wb_rels->find_nodes(
+ $get_path->(($wb_rels->find_nodes(
qq<//Relationship[\@Type="$type_base/styles"]>
- ))[0]->att('Target')
+ ))[0]->att('Target'))
);
my %worksheet_xml = map {
- if ( my $sheetfile = $zip->memberNamed($path_base . $_->att('Target'))->contents ) {
+ if ( my $sheetfile = $zip->memberNamed($get_path->($_->att('Target')))->contents ) {
( $_->att('Id') => $sheetfile );
}
} $wb_rels->find_nodes(qq<//Relationship[\@Type="$type_base/worksheet"]>);
my %themes_xml = map {
- $_->att('Id') => $self->_parse_xml($zip, $path_base . $_->att('Target'))
+ $_->att('Id') => $self->_parse_xml($zip, $get_path->($_->att('Target')))
} $wb_rels->find_nodes(qq<//Relationship[\@Type="$type_base/theme"]>);
return {
@@ -1394,8 +1421,6 @@ although this may have other consequences such as memory leaks.
=item Intra-cell formatting is discarded
-=item Diagonal border styles are ignored
-
=back
In addition, there are still a few areas which are not yet implemented (the
diff --git a/t/bug-38.t b/t/bug-38.t
new file mode 100644
index 0000000..fa61176
--- /dev/null
+++ b/t/bug-38.t
@@ -0,0 +1,11 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+use Spreadsheet::ParseXLSX;
+
+my $wb = Spreadsheet::ParseXLSX->new->parse('t/data/bug-38.xlsx');
+pass('it parses successfully');
+
+done_testing;
diff --git a/t/data/bug-38.xlsx b/t/data/bug-38.xlsx
new file mode 100644
index 0000000..be360b4
--- /dev/null
+++ b/t/data/bug-38.xlsx
Binary files differ
diff --git a/t/data/hidden-row-and-column.xlsx b/t/data/hidden-row-and-column.xlsx
new file mode 100644
index 0000000..4d4bac4
--- /dev/null
+++ b/t/data/hidden-row-and-column.xlsx
Binary files differ
diff --git a/t/data/hidden-sheet.xlsx b/t/data/hidden-sheet.xlsx
new file mode 100644
index 0000000..d29cafb
--- /dev/null
+++ b/t/data/hidden-sheet.xlsx
Binary files differ
diff --git a/t/data/target-abspath.xlsx b/t/data/target-abspath.xlsx
new file mode 100644
index 0000000..2ca7970
--- /dev/null
+++ b/t/data/target-abspath.xlsx
Binary files differ
diff --git a/t/hidden-row-and-column.t b/t/hidden-row-and-column.t
new file mode 100644
index 0000000..cd18c70
--- /dev/null
+++ b/t/hidden-row-and-column.t
@@ -0,0 +1,17 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+use Spreadsheet::ParseXLSX;
+
+my $wb = Spreadsheet::ParseXLSX->new->parse('t/data/hidden-row-and-column.xlsx');
+my $ws = $wb->worksheet(0);
+
+ok(!$ws->is_row_hidden(0), 'Regular row is not hidden');
+ok( $ws->is_row_hidden(1), 'Hidden row is hidden');
+
+ok(!$ws->is_col_hidden(0), 'Regular column is not hidden');
+ok( $ws->is_col_hidden(1), 'Hidden column is hidden');
+
+done_testing;
diff --git a/t/hidden-sheet.t b/t/hidden-sheet.t
new file mode 100644
index 0000000..09d4402
--- /dev/null
+++ b/t/hidden-sheet.t
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+use Spreadsheet::ParseXLSX;
+
+my $wb = Spreadsheet::ParseXLSX->new->parse('t/data/hidden-sheet.xlsx');
+my $ws1 = $wb->worksheet(0);
+ok(!$ws1->is_sheet_hidden(), 'Regular worksheet is not hidden');
+
+my $ws2 = $wb->worksheet(1);
+ok($ws2->is_sheet_hidden(), 'Hidden worksheet is hidden');
+
+done_testing;
diff --git a/t/target-abspath.t b/t/target-abspath.t
new file mode 100644
index 0000000..9e9786c
--- /dev/null
+++ b/t/target-abspath.t
@@ -0,0 +1,11 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+use Spreadsheet::ParseXLSX;
+
+my $wb = Spreadsheet::ParseXLSX->new->parse('t/data/target-abspath.xlsx');
+is($wb->worksheet(0)->get_cell(1, 0)->value, '10213.576');
+
+done_testing;