package CatalystX::CRUD::View::Excel; use warnings; use strict; use base qw( Catalyst::View::Excel::Template::Plus CatalystX::CRUD ); use Class::C3; use Path::Class; our $VERSION = '0.06'; =head1 NAME CatalystX::CRUD::View::Excel - view CRUD search/list results in Excel format =head1 SYNOPSIS package MyApp::View::Excel; use base qw( CatalystX::CRUD::View::Excel ); __PACKAGE__->config( TEMPLATE_EXTENSION => 'tt', etp_config => { INCLUDE_PATH => [ 'my/tt/path', __PACKAGE__->path_to('root') ], } ); 1; =cut =head1 DESCRIPTION CatalystX::CRUD::View::Excel makes it easy to export your search results as an Excel document. If you are using the other CatalystX::CRUD Controller and Model classes, your default end() method might look something like this: sub end : ActionClass('RenderView') { my ( $self, $c ) = @_; if ( $c->req->param('as_xls') ) { $c->stash->{current_view} = 'Excel'; } } and get a .xls document for any search or list by simply adding a C param pair to your url query. B If you are paging results, then you will need to turn off paging in order to get all your results in a single .xls file. You can do this with the standard C<_no_page> param as defined in the CatalystX::CRUD::Model API. =head1 METHODS =head2 new Overrides base new() method to set default INCLUDE and TEMPLATE_EXTENSION config values. =cut sub new { my ( $class, $c, $args ) = @_; my $self = $class->next::method( $c, $args ); $self->etp_config->{INCLUDE_PATH} ||= [ $c->config->{root} ]; $self->config->{TEMPLATE_EXTENSION} ||= 'tt'; return $self; } =head2 process Overrides base process() method to call get_filename() and create template from results_template if a template file does not exist. =cut sub process { my $self = shift; my $c = shift; my @args = @_; my $template = $self->get_template_filename($c); ( defined $template ) || $self->throw_error('No template specified for rendering'); # does $template exist? otherwise create one ad-hoc unless ( $self->template_exists( $c, $template ) ) { $template = \( $self->results_template($c) ); } my $etp_engine = $c->stash->{etp_engine} || $self->etp_engine; my $etp_config = $c->stash->{etp_config} || $self->etp_config; my $etp_params = $c->stash->{etp_params} || $self->etp_params; my $excel = $self->create_template_object( $c => ( engine => $etp_engine, template => $template, config => $etp_config, params => $etp_params, ) ); $excel->param( $self->get_template_params($c) ); $c->response->content_type('application/x-msexcel'); my $filename = $self->get_filename($c); $c->response->header( 'Content-Disposition', qq{attachment; filename="$filename"} ); $c->response->body( $excel->output ); } =head2 template_exists( I ) Search the TT include path to see if I really exists. =cut sub template_exists { my ( $self, $c, $template ) = @_; for my $path ( @{ $self->etp_config->{INCLUDE_PATH} } ) { if ( -s file( $path, $template ) ) { $c->log->debug("using Excel template: $template") if $c->debug; return 1; } } return 0; } =head2 get_template_filename( I ) Overrides base method to change the default naming convention. If C