diff options
author | Jesse Luehrs <doy@tozt.net> | 2013-10-29 10:13:26 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2013-10-29 10:13:26 -0400 |
commit | 95e314227491736459ae2a651c9148216f9980d4 (patch) | |
tree | 8266a123e079d7f108d6f4e71f9f79d2780b58b2 | |
parent | 0bb1e9c969aac5ca9d924ccacfa5b21076aba806 (diff) | |
download | spreadsheet-template-95e314227491736459ae2a651c9148216f9980d4.tar.gz spreadsheet-template-95e314227491736459ae2a651c9148216f9980d4.zip |
add a utf8 decoder helper
xslate doesn't provide any way to mark code inside template files as
utf8, so strings in that code end up as undecoded strings, even if the
rest of the template file itself is decoded. this provides a helper
function you can use in your templates to explicitly decode the strings.
if this ever gets fixed in xslate, i'll be able to just conditionally
turn this helper function into a noop, so it shouldn't really affect
forwards compatibility.
-rw-r--r-- | lib/Spreadsheet/Template/Helpers/Xslate.pm | 10 | ||||
-rw-r--r-- | t/data/utf8.json | 50 | ||||
-rw-r--r-- | t/utf8.t | 99 |
3 files changed, 157 insertions, 2 deletions
diff --git a/lib/Spreadsheet/Template/Helpers/Xslate.pm b/lib/Spreadsheet/Template/Helpers/Xslate.pm index 56df981..a05ff0a 100644 --- a/lib/Spreadsheet/Template/Helpers/Xslate.pm +++ b/lib/Spreadsheet/Template/Helpers/Xslate.pm @@ -2,6 +2,7 @@ package Spreadsheet::Template::Helpers::Xslate; use strict; use warnings; +use Encode; use JSON; my $JSON = JSON->new; @@ -10,10 +11,10 @@ use Sub::Exporter 'build_exporter'; my $import = build_exporter({ exports => [ - map { $_ => \&_curry_package } qw(format c merge true false) + map { $_ => \&_curry_package } qw(format c merge true false u) ], groups => { - default => [qw(format c merge true false)], + default => [qw(format c merge true false u)], }, }); @@ -65,6 +66,11 @@ sub merge { sub true { JSON::true } sub false { JSON::false } +sub u { + my ($package, $str) = @_; + return Encode::decode('UTF-8', $str, Encode::FB_CROAK) +} + sub _parse_range { my ($range) = @_; diff --git a/t/data/utf8.json b/t/data/utf8.json new file mode 100644 index 0000000..c65a4bc --- /dev/null +++ b/t/data/utf8.json @@ -0,0 +1,50 @@ +%% my $default = { color => '#000000', size => 14 }; +%% format(normal => $default.merge({})); +%% format(date => $default.merge({ num_format => 'd-mmm' })); +%% format(money => $default.merge({ bold => true(), num_format => u('_(¥* #,##0.00_);_(¥* (#,##0.00);_(¥* -??_);_(@_)')})); +%% format(title => $default.merge({ bg_color => '#c6d9f0', pattern => 'solid' })); +%% format(bold => $default.merge({ bold => true() })); +%% format(bold_money => $default.merge({ bold => true(), num_format => u('_(¥* #,##0.00_);_(¥* (#,##0.00);_(¥* -??_);_(@_)')})); +{ + "selection" : 0, + "worksheets" : [ + { + "column_widths" : [ 14.6, 18.5, 15.8, 12.2 ], + "name" : "Report 1", + "selection" : [ 1, 9 ], + "row_heights" : [ 25, 18, 18, 18 ], + "cells" : [ + [ + [% c("Descriptions", "title") %], + [% c("Numbers", "title") %], + [% c("Dates", "title") %], + [% c("Money", "title") %] + ], + %% for $rows -> $row { + [ + [% c($row.description, "normal") %], + [% c($row.number, "normal", "number") %], + [% c($row.date, "date", "date_time") %], + [% c($row.money, "money", "number") %] + ], + %% } + [ + [% c("Totals:", "bold") %], + [% c( + $rows.map(-> $a { $a.number }).reduce(-> $a, $b { $a + $b }), + "bold", + "number", + formula => 'SUM(B2:B' ~ ($rows.size() + 1) ~ ')', + ) %], + [% c("", "bold") %], + [% c( + $rows.map(-> $a { $a.money }).reduce(-> $a, $b { $a + $b }), + "bold_money", + "number", + formula => 'SUM(D2:D' ~ ($rows.size() + 1) ~ ')', + ) %] + ] + ] + } + ] +} diff --git a/t/utf8.t b/t/utf8.t new file mode 100644 index 0000000..03c72d8 --- /dev/null +++ b/t/utf8.t @@ -0,0 +1,99 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +use utf8; + +use Spreadsheet::ParseXLSX; +use Spreadsheet::Template; + +my $template = Spreadsheet::Template->new; +my $data = do { local $/; local @ARGV = ('t/data/utf8.json'); <> }; +{ + my $excel = $template->render( + $data, + { + rows => [ + { + description => "Row 1", + number => 26, + date => '2013-03-21T00:00:00', + money => 3.50, + }, + { + description => "Row 2", + number => 83, + date => '2013-06-25T00:00:00', + money => 84.28, + }, + ], + } + ); + + open my $fh, '<:encoding(UTF-8)', \$excel; + my $wb = Spreadsheet::ParseXLSX->new->parse($fh); + is($wb->worksheet_count, 1); + + my $ws = $wb->worksheet(0); + is($ws->get_name, 'Report 1'); + is_deeply([$ws->row_range], [0, 3]); + is_deeply([$ws->col_range], [0, 3]); + + my @values = ( + ["Descriptions", "Numbers", "Dates", "Money" ], + ["Row 1", "26", "21-Mar", "¥ 3.50" ], + ["Row 2", "83", "25-Jun", "¥ 84.28"], + ["Totals:", "109", "", "¥ 87.78"], + ); + for my $row (0..3) { + for my $col (0..3) { + is($ws->get_cell($row, $col)->value, $values[$row][$col]); + } + } +} + +{ + my $excel = $template->render( + $data, + { + rows => [ + { + description => "Another Row", + number => 42, + date => '2012-12-25T00:00:00', + money => 1.22, + }, + { + description => "Yet Another Row", + number => 0, + date => '2011-03-09T00:00:00', + money => 1001.01, + }, + ], + } + ); + + open my $fh, '<:encoding(UTF-8)', \$excel; + my $wb = Spreadsheet::ParseXLSX->new->parse($fh); + is($wb->worksheet_count, 1); + + my $ws = $wb->worksheet(0); + is($ws->get_name, 'Report 1'); + is_deeply([$ws->row_range], [0, 3]); + is_deeply([$ws->col_range], [0, 3]); + + my @values = ( + ["Descriptions", "Numbers", "Dates", "Money" ], + ["Another Row", "42", "25-Dec", "¥ 1.22" ], + ["Yet Another Row", "0", "9-Mar", "¥ 1,001.01"], + ["Totals:", "42", "", "¥ 1,002.23"], + ); + for my $row (0..3) { + for my $col (0..3) { + is($ws->get_cell($row, $col)->value, $values[$row][$col]); + } + } +} + +done_testing; |