package IO::StructuredOutput::Sheets;
use 5.00503;
use strict;
require Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
@ISA = qw(Exporter);
use Carp qw(croak);
use Text::CSV_XS;
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use test1 ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
%EXPORT_TAGS = ( 'all' => [ qw(
) ] );
@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
@EXPORT = qw(
);
$VERSION = sprintf "%d.%03d", q$Revision: 1.8 $ =~ /(\d+)/g;
# Preloaded methods go here.
sub addsheet
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $attr = shift;
my $name = $attr->{name} || 'Sheet';
my $format = $attr->{format} || 'html';
my $default_style = $attr->{style};
my $wb = $attr->{wb} || "";
if ($format eq 'csv')
{
my $csv = Text::CSV_XS->new();
my $newsheet = { ws => "", name => $name, format => $format, style => $default_style, csv => $csv };
bless $newsheet, $class;
return $newsheet;
} elsif ($format eq 'html') {
# we'll be encapsulating the output w/
when
# output is requested, so no need to do anything here
my $newsheet = { ws => "", name => $name, format => $format, style => $default_style };
bless $newsheet, $class;
return $newsheet;
} elsif ($format eq 'xls') {
my $ws = $wb->add_worksheet($name);
my $newsheet = { ws => $ws, name => $name, format => $format, style => $default_style };
bless $newsheet, $class;
return $newsheet;
} else {
croak "invalid or missing format";
}
}
sub name
{
ref(my $self = shift) or croak "instance variable needed";
# can't change name once set (limit of excel module)
# croak "instance isn't a sheet object" unless ($self->isa("Sheet"));
return $self->{name};
}
sub sheet
{
ref(my $self = shift) or croak "instance variable needed";
return $self->{ws};
}
sub addrow
{
ref(my $self = shift) or croak "instance variable needed";
return unless (ref(@_[0]) eq 'ARRAY'); # need to pass in some data to add
my $data = shift;
my $styles = shift;
my $style = $styles ? $styles : $self->{style};
my $format = $self->format(); # cut down on method calls
if ($format eq 'csv')
{
my @row;
for (my $i = 0; $i < @{$data}; $i++)
{
my $column = $data->[$i];
# my $thisstyle = ref($style) ? $style->[$i] : $style;
# $thisstyle = $self->{style} unless ($thisstyle);
# column may also be an array ref, indicating data spanning
# multiple columns. csv doesn't support that, but we'll
# handle it anyway.
if (ref($column) eq 'ARRAY')
{
# push(@row, shift(@{$column}) );
push(@row,@{$column});
} elsif (ref($column)) {
# skip. Hash and subroutine referances not supported
} else {
push(@row,$column);
}
}
$self->{csv}->combine(@row);
$self->{ws} .= $self->{csv}->string() . "\n";
$self->{rowcount}++;
} elsif ($format eq 'html') {
my $row;
for (my $i = 0; $i < @{$data}; $i++)
{
my $column = $data->[$i];
my $thisstyle = (ref($style) eq 'ARRAY') ? $style->[$i] : $style;
$thisstyle = $self->{style} unless ($thisstyle);
# column may also be an array ref, indicating data spanning
# multiple columns.
if (ref($column) eq 'ARRAY')
{
$row .= $thisstyle->output_style($column->[0], scalar(@{$column}) );
} elsif (ref($column)) {
# skip. Hash and subroutine referances not supported
} else {
$row .= $thisstyle->output_style($column);
}
}
$self->{ws} .= "\n" . $row . "
\n";
$self->{rowcount}++;
} elsif ($format eq 'xls') {
$self->{rowcount}++;
my $row = ($self->{rowcount} - 1);
my $col = 0;
for (my $i = 0; $i < @{$data}; $i++)
{
my $column = $data->[$i];
my $thisstyle = (ref($style) eq 'ARRAY') ? $style->[$i] : $style;
$thisstyle = $self->{style} unless ($thisstyle);
# column may also be an array ref, indicating data spanning
# multiple columns.
if (ref($column) eq 'ARRAY')
{
my $span = scalar(@{$column});
$self->{ws}->merge_range($row,$col,$row,($col + $span - 1),$column->[0], $thisstyle->output_style() );
$col += $span;
} elsif (ref($column)) {
# skip. Hash and subroutine referances not supported
} else {
$self->{ws}->write($row,$col,$column,$thisstyle->output_style() );
$col++;
}
}
} else {
croak "invalid or missing format";
}
}
sub setwidth
{
ref(my $self = shift) or croak "instance variable needed";
if ($self->format() eq 'xls')
{ # setting width of a column currently only supported in xls
my $first_column = shift;
my $second_column = shift;
my $width = shift;
$self->{ws}->set_column($first_column,$second_column,$width);
}
}
sub freeze_panes
{
ref(my $self = shift) or croak "instance variable needed";
if ($self->format() eq 'xls')
{ # this thing will never be supported in html or csv
# but I needed it for some excel output.
# see Spreadsheet::WriteExcel for docs
my @args = @_;
$self->{ws}->freeze_panes(@_);
}
}
sub rowcount
{
ref(my $self = shift) or croak "instance variable needed";
return $self->{rowcount};
}
sub format
{
ref(my $self = shift) or croak "instance variable needed";
return $self->{format};
}
1;
__END__
=head1 NAME
Sheets - Perl extension to IO::StructuredData to handle pages/sheets in an IO::STructuredOutput object.
=head1 SYNOPSIS
use IO::StructuredOutput::Sheets;
### See IO::StructuredOutput for details
=head1 DESCRIPTION
This class implements objects to create pages/sheets for IO::StructuredOutput objects.
=head2 EXPORT
None by default.
=head1 SEE ALSO
IO::StructuredOutput
=head1 AUTHOR
Joshua I. Miller Ejmiller@purifieddata.netE
=head1 COPYRIGHT AND LICENSE
Copyright 2003 by Joshua I. Miller
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut