use Excel::Template::Base;
use vars qw ($VERSION @ISA);
- $VERSION = '0.12';
+ $VERSION = '0.21';
@ISA = qw( Excel::Template::Base );
}
use File::Basename;
use XML::Parser;
-use IO::File;
use IO::Scalar;
+use constant RENDER_NML => 'normal';
+use constant RENDER_BIG => 'big';
+use constant RENDER_XML => 'xml';
+
+my %renderers = (
+ RENDER_NML, 'Spreadsheet::WriteExcel',
+ RENDER_BIG, 'Spreadsheet::WriteExcel::Big',
+ RENDER_XML, 'Spreadsheet::WriteExcelXML',
+);
+
sub new
{
my $class = shift;
if defined $self->{FILENAME};
my @renderer_classes = ( 'Spreadsheet::WriteExcel' );
- if (exists $self->{BIG_FILE} && $self->{BIG_FILE})
+
+ if (exists $self->{RENDERER} && $self->{RENDERER})
+ {
+ if (exists $renderers{ lc $self->{RENDERER} })
+ {
+ unshift @renderer_classes, $renderers{ lc $self->{RENDERER} };
+ }
+ elsif ($^W)
+ {
+ warn "'$self->{RENDERER}' is not recognized\n";
+ }
+ }
+ elsif (exists $self->{BIG_FILE} && $self->{BIG_FILE})
{
+ warn "Use of BIG_FILE is deprecated.\n";
unshift @renderer_classes, 'Spreadsheet::WriteExcel::Big';
}
$class->import;
};
if ($@) {
- warn "Could not find or compile '$class'\n";
+ warn "Could not find or compile '$class'\n" if $^W;
} else {
$self->{RENDERER} = $class;
last;
join("\n\t", @renderer_classes) .
"\n";
+ $self->{USE_UNICODE} = ~~0
+ if $] >= 5.008;
+
return $self;
}
$params{uc $_} = delete $params{$_} for keys %params;
@{$self->{PARAM_MAP}}{keys %params} = @params{keys %params};
- return 1;
+ return ~~1;
}
sub write_file
$xls->close;
- return 1;
+ return ~~1;
}
sub output
return $output;
}
-sub parse
-{
- my $self = shift;
-
- $self->parse_xml(@_);
-}
-
sub parse_xml
{
my $self = shift;
my $name = uc shift;
- my $node = Excel::Template::Factory->create_node($name, @_);
+ my $node = Excel::Template::Factory->_create_node($name, @_);
die "'$name' (@_) didn't make a node!\n" unless defined $node;
- if ($name eq 'WORKBOOK')
+ if ( $node->isa( 'WORKBOOK' ) )
{
push @{$self->{WORKBOOKS}}, $node;
}
- elsif ($name eq 'VAR')
+ elsif ( $node->is_embedded )
{
return unless @stack;
);
{
- my $fh = IO::File->new($fname)
+ open( INFILE, "<$fname" )
|| die "Cannot open '$fname' for reading: $!\n";
- $parser->parse(do { local $/ = undef; <$fh> });
+ $parser->parse(do { local $/ = undef; <INFILE> });
- $fh->close;
+ close INFILE;
}
- return 1;
+ return ~~1;
}
+*parse = \&parse_xml;
sub _prepare_output
{
my $self = shift;
my ($xls) = @_;
- my $context = Excel::Template::Factory->create(
+ my $context = Excel::Template::Factory->_create(
'CONTEXT',
XLS => $xls,
PARAM_MAP => [ $self->{PARAM_MAP} ],
+ UNICODE => $self->{UNICODE},
);
$_->render($context) for @{$self->{WORKBOOKS}};
- return 1;
+ return ~~1;
}
sub register { shift; Excel::Template::Factory::register(@_) }
Now, create a small program to use it:
#!/usr/bin/perl -w
- use Excel::Template
+ use Excel::Template;
# Create the Excel template
my $template = Excel::Template->new(
instead. The existing modules don't do the trick, as they require replication
of logic that's already been done within HTML::Template.
-Currently, only a small subset of the planned features are supported. This is
-meant to be a test of the waters, to see what features people actually want.
-
=head1 MOTIVATION
I do a lot of Perl/CGI for reporting purposes. In nearly every place I've been,
=head2 new()
-This creates a Excel::Template object. If passed a filename parameter, it will
+This creates a Excel::Template object. If passed a FILENAME parameter, it will
parse the template in the given file. (You can also use the parse() method,
described below.)
+=head3 Parameters
+
+=over 4
+
+=item * RENDERER
+
+The default rendering engine is Spreadsheet::WriteExcel. You may, if you choose, change that to another choice. The legal values are:
+
+=over 4
+
+=item * Excel::Template->RENDER_NML
+
+This is the default of Spreadsheet::WriteExcel.
+
+=item * Excel::Template->RENDER_BIG
+
+This attempts to load Spreadsheet::WriteExcel::Big.
+
+=item * Excel::Template->RENDER_XML
+
+This attempts to load Spreadsheet::WriteExcelXML.
+
+=back
+
+=item * USE_UNICODE
+
+This will use L<Unicode::String> to represent strings instead of Perl's internal string handling. You must already have L<Unicode::String> installed on your system.
+
+The USE_UNICODE parameter will be ignored if you are using Perl 5.8 or higher as
+Perl's internal string handling is unicode-aware.
+
+NOTE: Certain older versions of L<OLE::Storage_Lite> and mod_perl clash for some
+reason. Upgrading to the latest version of L<OLE::Storage_Lite> should fix the
+problem.
+
+=back
+
+=head3 Deprecated
+
+=over 4
+
+=item * BIG_FILE
+
+Instead, use RENDERER => Excel::Template->RENDER_BIG
+
+=back
+
=head2 param()
-This method is exactly like HTML::Template's param() method. Although I will
-be adding more to this section later, please see HTML::Template's description
-for info right now.
+This method is exactly like L<HTML::Template>'s param() method.
=head2 parse() / parse_xml()
file as a stream, usually for output to the web. (This is when the actual
merging of the template and the parameters occurs.)
+=head2 register()
+
+This allows you to register a class as handling a node. q.v. L<Excel::Template::Factory> for more info.
+
=head1 SUPPORTED NODES
-This is just a list of nodes. See the other classes in this distro for more
+This is a partial list of nodes. See the other classes in this distro for more
details on specific parameters and the like.
Every node can set the ROW and COL parameters. These are the actual ROW/COL
-values that the next CELL tag will write into.
+values that the next CELL-type tag will write into.
=over 4
-=item * WORKBOOK
+=item * L<WORKBOOK|Excel::Template::Container::Workbook>
+
+This is the node representing the workbook. It is the parent for all other
+nodes.
+
+=item * L<WORKSHEET|Excel::Template::Container::Worksheet>
+
+This is the node representing a given worksheet.
-=item * WORKSHEET
+=item * L<IF|Excel::Template::Container::Conditional>
-=item * IF
+This node represents a conditional expression. Its children may or may not be
+rendered. It behaves just like L<HTML::Template>'s TMPL_IF.
-=item * LOOP
+=item * L<LOOP|Excel::Template::Container::Loop>
-=item * ROW
+This node represents a loop. It behaves just like L<HTML::Template>'s TMPL_LOOP.
-=item * CELL
+=item * L<ROW|Excel::Template::Container::Row>
-=item * FORMULA
+This node represents a row of data. This is the A in A1.
-=item * BOLD
+=item * L<FORMAT|Excel::Template::Container::Format>
-=item * ITALIC
+This node varies the format for its children. All formatting options supported
+in L<Spreadsheet::WriteExcel> are supported here. There are also a number of
+formatting shortcuts, such as L<BOLD|Excel::Template::Container::Bold> and
+L<ITALIC|Excel::Template::Container::Italic>.
-=back 4
+=item * L<BACKREF|Excel::Template::Element::Backref>
+
+This refers back to a cell previously named.
+
+=item * L<CELL|Excel::Template::Element::Cell>
+
+This is the actual cell in a spreadsheet.
+
+=item * L<FORMULA|Excel::Template::Element::Formula>
+
+This is a formula in a spreadsheet.
+
+=item * L<RANGE|Excel::Template::Element::Range>
+
+This is a BACKREF for a number of identically-named cells.
+
+=item * L<VAR|Excel::Template::Element::Var>
+
+This is a variable. It is generally used when the 'text' attribute isn't
+sufficient.
+
+=back
=head1 BUGS
=head1 SUPPORT
-This is currently beta-quality software. The featureset is extremely limited,
-but I expect to be adding on to it very soon.
+This is production quality software, used in several production web
+applications.
=head1 AUTHOR
- Rob Kinyon
- rob.kinyon@gmail.com
+ Rob Kinyon (rob.kinyon@gmail.com)
=head1 CONTRIBUTORS
-There is a mailing list at http://groups-beta.google.com/group/ExcelTemplate
+There is a mailing list at http://groups.google.com/group/ExcelTemplate or exceltemplate@googlegroups.com
+
+=head2 Robert Graff
+
+=over 4
+
+=item * Finishing formats
+
+=item * Fixing several bugs in worksheet naming
+
+=back
+
+=head1 TEST COVERAGE
+
+I used Devel::Cover to test the coverage of my tests. Every release, I intend to improve these numbers.
+
+Excel::Template is also part of the CPAN Kwalitee initiative, being one of the top 100 non-core modules downloaded from CPAN. If you wish to help out, please feel free to contribute tests, patches, and/or suggestions.
+
+---------------------------- ------ ------ ------ ------ ------ ------ ------
+File stmt branch cond sub pod time total
+---------------------------- ------ ------ ------ ------ ------ ------ ------
+blib/lib/Excel/Template.pm 90.0 57.1 50.0 90.5 100.0 26.0 80.8
+...ib/Excel/Template/Base.pm 83.3 50.0 66.7 75.0 88.9 8.8 80.0
+...cel/Template/Container.pm 46.3 20.0 33.3 58.3 85.7 4.6 47.7
+...emplate/Container/Bold.pm 100.0 n/a n/a 100.0 0.0 0.6 95.0
+.../Container/Conditional.pm 58.5 52.3 66.7 75.0 66.7 0.7 58.4
+...plate/Container/Format.pm 100.0 n/a n/a 100.0 0.0 0.8 96.6
+...plate/Container/Hidden.pm 100.0 n/a n/a 100.0 0.0 0.2 95.0
+...plate/Container/Italic.pm 100.0 n/a n/a 100.0 0.0 0.2 95.0
+...plate/Container/Locked.pm 100.0 n/a n/a 100.0 0.0 0.1 95.0
+...emplate/Container/Loop.pm 55.6 40.0 50.0 77.8 75.0 0.5 56.6
+...late/Container/Outline.pm 71.4 n/a n/a 80.0 0.0 0.0 70.0
+...Template/Container/Row.pm 100.0 75.0 n/a 100.0 50.0 0.3 93.8
+...mplate/Container/Scope.pm 100.0 n/a n/a 100.0 n/a 0.1 100.0
+...plate/Container/Shadow.pm 100.0 n/a n/a 100.0 0.0 0.1 95.0
+...te/Container/Strikeout.pm 100.0 n/a n/a 100.0 0.0 0.1 95.0
+...ate/Container/Workbook.pm 100.0 n/a n/a 100.0 n/a 1.1 100.0
+...te/Container/Worksheet.pm 94.1 50.0 n/a 100.0 0.0 0.9 88.0
+...Excel/Template/Context.pm 83.1 53.4 54.2 95.0 92.9 19.2 75.2
+...Excel/Template/Element.pm 100.0 n/a n/a 100.0 n/a 0.5 100.0
+...mplate/Element/Backref.pm 100.0 50.0 33.3 100.0 0.0 0.1 87.1
+.../Template/Element/Cell.pm 95.8 65.0 80.0 100.0 66.7 3.6 86.9
+...mplate/Element/Formula.pm 100.0 n/a n/a 100.0 0.0 0.3 94.1
+...Template/Element/Range.pm 100.0 66.7 n/a 100.0 66.7 0.2 93.3
+...l/Template/Element/Var.pm 100.0 n/a n/a 100.0 0.0 0.2 94.1
+...Excel/Template/Factory.pm 57.1 34.6 n/a 88.9 100.0 15.4 55.2
+.../Excel/Template/Format.pm 98.3 81.2 33.3 100.0 100.0 9.9 93.2
+...xcel/Template/Iterator.pm 85.2 70.6 70.6 84.6 87.5 2.0 80.4
+...el/Template/TextObject.pm 92.9 62.5 33.3 100.0 50.0 3.6 83.0
+Total 83.0 55.6 57.0 91.1 98.7 100.0 78.6
+---------------------------- ------ ------ ------ ------ ------ ------ ------
=head1 COPYRIGHT