% $csv->combine(@$header); #or die $csv->status; % <% $opt{no_csv_header} ? '' : $csv->string %>\ % % foreach my $row ( @$rows ) { % % if ( $opt{'fields'} ) { % % my @line = (); % % foreach my $field ( @{$opt{'fields'}} ) { % if ( ref($field) eq 'CODE' ) { % push @line, map { % ref($_) eq 'ARRAY' % ? '(N/A)' #unimplemented % : $_; % } % &{$field}($row); % } else { % push @line, $row->$field(); % } % } % % $csv->combine(@line); #or die $csv->status; % % } else { % $csv->combine(@$row); #or die $csv->status; % } % <% $csv->string %>\ % % } % % if ( $opt{'footer'} and !$opt{'no_csv_header'} ) { % my @footer; % foreach my $item (@{ $opt{'footer'} }) { % if ( ref($item) eq 'CODE' ) { % $item = &{$item}(); % } % push @footer, $item; % } % $csv->combine(@footer); <% $csv->string %>\ % } <%init> my %args = @_; my $header = $args{'header'}; my $rows = $args{'rows'}; my %opt = %{ $args{'opt'} }; #http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes #http_header('Content-Type' => 'text/plain' ); http_header('Content-Type' => 'text/csv' ); # So saith RFC 4180 http_header('Content-Disposition' => 'attachment;filename="'.($opt{'name'} || PL($opt{'name_singular'}) ).'.csv"'); my $quote_char = '"'; $quote_char = $opt{csv_quote} if exists($opt{csv_quote}); my $csv = new Text::CSV_XS { 'always_quote' => $opt{avoid_quote} ? 0 : 1, 'eol' => "\n", #"\015\012", #"\012" };