1 % $csv->combine(@$header); #or die $csv->status;
3 <% $opt{no_csv_header} ? '' : $csv->string %>\
5 % foreach my $row ( @$rows ) {
7 % if ( $opt{'fields'} ) {
11 % foreach my $field ( @{$opt{'fields'}} ) {
12 % if ( ref($field) eq 'CODE' ) {
15 % ? '(N/A)' #unimplemented
20 % push @line, $row->$field();
24 % $csv->combine(@line); #or die $csv->status;
27 % $csv->combine(@$row); #or die $csv->status;
34 % if ( $opt{'footer'} and !$opt{'no_csv_header'} ) {
36 % foreach my $item (@{ $opt{'footer'} }) {
37 % if ( ref($item) eq 'CODE' ) {
40 % push @footer, $item;
42 % $csv->combine(@footer);
48 my $header = $args{'header'};
49 my $rows = $args{'rows'};
50 my %opt = %{ $args{'opt'} };
52 #http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes
53 #http_header('Content-Type' => 'text/plain' );
54 http_header('Content-Type' => 'text/csv' ); # So saith RFC 4180
55 http_header('Content-Disposition' =>
56 'attachment;filename="'.($opt{'name'} || PL($opt{'name_singular'}) ).'.csv"');
59 $quote_char = $opt{csv_quote} if exists($opt{csv_quote});
61 my $csv = new Text::CSV_XS { 'always_quote' => $opt{avoid_quote} ? 0 : 1,
62 'eol' => "\n", #"\015\012", #"\012"