I am writing some perl code to create a .csv file from records in the database, using the Text::CSV module. Occasionally, one or more of the fields in my table will contain multiple repeating 0s, which will write to the CSV as a single 0. I'm trying to find out how to force the number as text format, so that all of the 0s from those fields will remain in tact.
use Text::CSV_XS;
sub write_file {
my ($self, %params) = @_;
my $fh = $params{fh};
.. do stuff
.. get database rows
my $csv = Text::CSV_XS->new({ sep_char => ',' });
for my $row (@$rows) {
my @fields = (
$row->{name},
$row->{address},
$row->{code}
);
$csv->combine(@fields);
print $fh $csv->string . "\r\n"
or die 'Write error.';
}
With this approach, everything looks good most of the time. But, when code comes through as "00000", it is truncated and written as "0" in my CSV.
I've investigated $csv->types
, but this only allows the type to be defined when decoding during a parse.
I've also tried wrapping the fields in quotes using $csv->quote(@fields)
, with no luck.
To preserve all the digits in text-formatted numbers, you have to import the downloaded CSV file as raw data into a new Excel spreadsheet, set the column datatypes as needed, and then save the new file as an Excel workbook. Excel (XLSX) files will preserve these formats, CSV files won't.
Refer to always_quote()
to force the the combined fields to be quoted
use Text::CSV_XS;
my $csv = Text::CSV_XS->new( { sep_char => ',' } );
my @fields = ( "0", "00", "000" );
$csv->combine(@fields);
print $csv->string . "\n";
$csv->always_quote(1);
$csv->combine(@fields);
print $csv->string . "\n";
which results in
0,00,000
"0","00","000"
If the problem is that
Then you can simply normalize the data with sprintf
$x = 5;
print sprintf("%05d", $x)
You can choose how many leading zeros you want in your output, and make all colums read the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With