File Coverage

blib/lib/Catmandu/Exporter/CSV.pm
Criterion Covered Total %
statement 18 18 100.0
branch 8 8 100.0
condition 8 9 88.8
subroutine 6 6 100.0
pod n/a
total 40 41 97.5


line stmt bran cond sub pod time code
1             package Catmandu::Exporter::CSV;
2              
3 7     7   105524 use Catmandu::Sane;
  7         36  
  7         58  
4              
5             our $VERSION = '1.2020';
6              
7 7     7   4833 use Text::CSV;
  7         94683  
  7         354  
8 7     7   64 use Moo;
  7         17  
  7         58  
9 7     7   2803 use namespace::clean;
  7         19  
  7         59  
10              
11             with 'Catmandu::TabularExporter';
12              
13             has csv => (is => 'lazy');
14             has quote_char => (is => 'ro', default => sub {'"'});
15             has escape_char => (is => 'ro', default => sub {'"'});
16             has always_quote => (is => 'ro');
17             has quote_space => (is => 'ro');
18             has sep_char => (
19             is => 'ro',
20             default => sub {','},
21             coerce => sub {
22             my $sep_char = $_[0];
23             $sep_char =~ s/(\\[abefnrt])/"qq{$1}"/gee;
24             return $sep_char;
25             }
26             );
27              
28             sub _build_csv {
29 17     17   194 my ($self) = @_;
30 17 100       294 Text::CSV->new(
    100          
31             {
32             binary => 1,
33             eol => "\n",
34             sep_char => $self->sep_char,
35             always_quote => $self->always_quote,
36             quote_space => $self->quote_space,
37             quote_char => $self->quote_char ? $self->quote_char : undef,
38             escape_char => $self->escape_char ? $self->escape_char : undef,
39             }
40             );
41             }
42              
43             sub add {
44             my ($self, $data) = @_;
45             my $fields = $self->fields;
46             my $row = [
47             map {
48             my $val = $data->{$_} // "";
49             $val =~ s/\t/\\t/g;
50             $val =~ s/\n/\\n/g;
51             $val =~ s/\r/\\r/g;
52             $val;
53             } @$fields
54             ];
55              
56             $self->_print_header;
57             $self->csv->print($self->fh, $row);
58             }
59              
60             sub commit {
61             my ($self) = @_;
62              
63             # ensure header gets printed even if there are no records
64             $self->_print_header;
65             }
66              
67             sub _print_header {
68 46     46   86 my ($self) = @_;
69 46 100 100     233 if (!$self->count && $self->header) {
70 16   100     83 my $row = $self->columns || $self->fields;
71 16 100 66     395 $self->csv->print($self->fh, $row) if $row && @$row;
72             }
73             }
74              
75             1;
76              
77             __END__
78              
79             =pod
80              
81             =head1 NAME
82              
83             Catmandu::Exporter::CSV - a CSV exporter
84              
85             =head1 SYNOPSIS
86              
87             # On the command line
88              
89             $ catmandu convert XSL to CSV < data.xls
90              
91             $ catmandu convert JSON to CSV --fix myfixes.txt --sep_char ';' < data.json
92              
93             # In a Perl script
94              
95             use Catmandu;
96              
97             my $exporter = Catmandu->exporter('CSV',
98             fix => 'myfix.txt',
99             quote_char => '"',
100             sep_char => ',',
101             escape_char => '"' ,
102             always_quote => 1,
103             header => 1);
104              
105             $exporter->fields("f1,f2,f3");
106             $exporter->fields([qw(f1 f2 f3)]);
107              
108             $exporter->add_many($arrayref);
109             $exporter->add_many($iterator);
110             $exporter->add_many(sub { });
111              
112             $exporter->add($hashref);
113              
114             printf "exported %d items\n" , $exporter->count;
115              
116             =head1 DESCRIPTION
117              
118             This C<Catmandu::Exporter> exports items as rows with comma-separated values
119             (CSV). Serialization is based on L<Text::CSV>. A header line with field names
120             will be included if option C<header> is set. See L<Catmandu::TabularExporter>
121             on how to configure the field mapping and column names. Newlines and tabulator
122             values in field values are escaped as C<\n>, C<\r>, and C<\t>.
123              
124             =head1 CONFIGURATION
125              
126             =over
127              
128             =item file
129              
130             Write output to a local file given by its path or file handle. Alternatively a
131             scalar reference can be passed to write to a string and a code reference can be
132             used to write to a callback function.
133              
134             =item fh
135              
136             Write the output to an L<IO::Handle>. If not specified,
137             L<Catmandu::Util::io|Catmandu::Util/IO-functions> is used to create the output
138             handle from the C<file> argument or by using STDOUT.
139              
140             =item fix
141              
142             An ARRAY of one or more fixes or file scripts to be applied to exported items.
143              
144             =item encoding
145              
146             Binmode of the output stream C<fh>. Set to "C<:utf8>" by default.
147              
148             =item sep_char
149              
150             Column separator (C<,> by default)
151              
152             =item quote_char
153              
154             Quotation character (C<"> by default)
155              
156             =item escape_char
157              
158             Character for escaping inside quoted field (C<"> by default)
159              
160             =item fields
161              
162             See L<Catmandu::TabularExporter>.
163              
164             =item columns
165              
166             See L<Catmandu::TabularExporter>.
167              
168             =item header
169              
170             Include a header line with column names. Enabled by default.
171              
172             =back
173              
174             =head1 METHODS
175              
176             See L<Catmandu::TabularExporter>, L<Catmandu::Exporter>, L<Catmandu::Addable>,
177             L<Catmandu::Fixable>, L<Catmandu::Counter>, and L<Catmandu::Logger> for a full
178             list of methods.
179              
180             =head1 SEE ALSO
181              
182             L<Catmandu::Importer::CSV>, L<Catmandu::Exporter::Table>
183             L<Catmandu::Exporter::XLS>
184              
185             =cut