如何在Perl 5中将此Unicode表导出为CSV?

时间:2010-01-12 19:36:21

标签: sql perl unicode csv

我有一个表中有一些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++;
  }

有什么想法吗?

1 个答案:

答案 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 ]);
}