我有一个表中有一些Unicode。我知道Unicode数据很好,因为它在我们的网络服务器上作为JSON就好了。但由于某种原因,我正在生成的CSV最终被破坏了。这是我们当前的代码:
my $csv = Text::CSV->new ({ eol => "\015\012" });
open my $fh, '>:encoding(utf8)', 'Foo.csv';
my $sth = $dbh->prepare("SELECT * FROM Foo");
$sth->execute();
my $i = 0;
while (my $row = $sth->fetchrow_hashref) {
$csv->print($fh, [keys %$row]) if $i == 0;
$csv->print($fh, [values %$row]);
$i++;
}
有什么想法吗?
答案 0 :(得分:3)
除编码问题外,我认为不保证values
将始终以相同的顺序提供字段。每次调用它时,您可能会从fetchrow_hashref
获取不同的hashref。解决方法是使用fetchrow_arrayref
。
Text::CSV建议Text::CSV::Encoded:
my $csv = Text::CSV::Encoded->new({ eol => "\015\012" });
open my $fh, '>:raw', 'Foo.csv';
my $sth = $dbh->prepare("SELECT * FROM Foo");
$sth->execute();
$csv->print($fh, $sth->{NAME_lc}); # or NAME or NAME_uc
while (my $row = $sth->fetchrow_arrayref) {
$csv->print($fh, $row);
}
或者,如果您不想安装新模块:
use Encode 'find_encoding';
my $utf8 = find_encoding('utf8');
my $csv = Text::CSV->new({ binary => 1, eol => "\015\012" });
open my $fh, '>:raw', 'Foo.csv';
my $sth = $dbh->prepare("SELECT * FROM Foo");
$sth->execute();
# I'm assuming your field names are ASCII:
$csv->print($fh, $sth->{NAME_lc}); # or NAME or NAME_uc
while (my $row = $sth->fetchrow_arrayref) {
$csv->print($fh, [ map { $utf8->encode($_) } @$row ]);
}