From 6739d8c87dda4f543400305d5a06c128ab87492d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 30 Apr 2013 16:19:37 -0500 Subject: start sketching out the template generator --- bin/generate_template | 9 +++ lib/Spreadsheet/Template/Generator.pm | 28 +++++++ lib/Spreadsheet/Template/Generator/Parser.pm | 8 ++ lib/Spreadsheet/Template/Generator/Parser/XLSX.pm | 89 +++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 bin/generate_template create mode 100644 lib/Spreadsheet/Template/Generator.pm create mode 100644 lib/Spreadsheet/Template/Generator/Parser.pm create mode 100644 lib/Spreadsheet/Template/Generator/Parser/XLSX.pm diff --git a/bin/generate_template b/bin/generate_template new file mode 100644 index 0000000..e94848f --- /dev/null +++ b/bin/generate_template @@ -0,0 +1,9 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use Spreadsheet::Template::Generator; + +my $generator = Spreadsheet::Template::Generator->new; +open my $fh, '>:encoding(utf8)', 'out.json'; +$fh->print($generator->generate($ARGV[0])); diff --git a/lib/Spreadsheet/Template/Generator.pm b/lib/Spreadsheet/Template/Generator.pm new file mode 100644 index 0000000..aa5e0e0 --- /dev/null +++ b/lib/Spreadsheet/Template/Generator.pm @@ -0,0 +1,28 @@ +package Spreadsheet::Template::Generator; +use Moose; + +use Class::Load 'load_class'; +use JSON; + +sub generate { + my $self = shift; + my ($filename) = @_; + (my $ext = $filename) =~ s/.*\.//; + my $class = $self->parser_classes->{$ext}; + load_class($class); + my $parser = $class->new; + my $data = $parser->parse($filename); + return JSON->new->pretty->encode($data); +} + +sub parser_classes { + +{ + 'xls' => 'Spreadsheet::Template::Generator::Parser::XLS', + 'xlsx' => 'Spreadsheet::Template::Generator::Parser::XLSX', + } +} + +__PACKAGE__->meta->make_immutable; +no Moose; + +1; diff --git a/lib/Spreadsheet/Template/Generator/Parser.pm b/lib/Spreadsheet/Template/Generator/Parser.pm new file mode 100644 index 0000000..a2cfd25 --- /dev/null +++ b/lib/Spreadsheet/Template/Generator/Parser.pm @@ -0,0 +1,8 @@ +package Spreadsheet::Template::Generator::Parser; +use Moose::Role; + +requires 'parse'; + +no Moose::Role; + +1; diff --git a/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm b/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm new file mode 100644 index 0000000..b542ac3 --- /dev/null +++ b/lib/Spreadsheet/Template/Generator/Parser/XLSX.pm @@ -0,0 +1,89 @@ +package Spreadsheet::Template::Generator::Parser::XLSX; +use Moose; + +use XML::Entities; +use Spreadsheet::XLSX; + +with 'Spreadsheet::Template::Generator::Parser'; + +sub parse { + my $self = shift; + my ($filename) = @_; + + my $excel = Spreadsheet::XLSX->new($filename); + return $self->_parse_workbook($excel); + my $data = { + worksheets => [], + }; + for my $sheet ($excel->worksheets) { + push @{ $data->{worksheets} }, $self->_parse + } +} + +sub _parse_workbook { + my $self = shift; + my ($excel) = @_; + + my $data = { + worksheets => [], + }; + + for my $sheet ($excel->worksheets) { + push @{ $data->{worksheets} }, $self->_parse_worksheet($sheet); + } + + return $data; +} + +sub _parse_worksheet { + my $self = shift; + my ($sheet) = @_; + + my $data = { + cells => [], + }; + + my ($rmin, $rmax) = $sheet->row_range; + my ($cmin, $cmax) = $sheet->col_range; + + for my $row (0..$rmin - 1) { + push @{ $data->{cells} }, []; + } + + for my $row ($rmin..$rmax) { + my $row_data = []; + for my $col (0..$cmin - 1) { + push @$row_data, {}; + } + for my $col ($cmin..$cmax) { + if (my $cell = $sheet->get_cell($row, $col)) { + push @$row_data, $self->_parse_cell($cell); + } + else { + push @$row_data, {}; + } + } + push @{ $data->{cells} }, $row_data + } + + return $data; +} + +sub _parse_cell { + my $self = shift; + my ($cell) = @_; + + + my $data = { + # XXX this decode call really feels like a bug in Spreadsheet::XLSX + contents => XML::Entities::decode('all', $cell->unformatted), + type => $cell->type, + }; + + return $data; +} + +__PACKAGE__->meta->make_immutable; +no Moose; + +1; -- cgit v1.2.3-54-g00ecf