【问题标题】:Converting XLSX to CSV with Perl while maintaining the encoding使用 Perl 将 XLSX 转换为 CSV,同时保持编码
【发布时间】:2020-06-08 03:42:41
【问题描述】:

我是一名 BI 开发人员,使用 perl 脚本作为我的 ETL - 我通过电子邮件接收数据,获取文件,对其进行解析并将其推送到数据库中。 大多数文件都是 CSV,但偶尔我有一个 XLSX 文件。

我一直在使用 Spreadsheet::XLSX 进行转换,但我注意到 CSV 输出的编码错误(需要是 UTF8,因为口音和外语)。

这就是我正在使用的子程序($input_file 是一个 Excel 文件),但我不断得到带有错误字符的数据。

我错过了什么?

非常感谢!

sub convert_to_csv {
    my $input_file = $_[0];
    my ( $filename, $extension ) = split( '\.', $input_file );
    open( format_file, ">:**encoding(utf-8)**", "$filename.csv" ) or die "could not open out file $!\n";
    my $excel = Spreadsheet::XLSX->new($input_file);
    my $line;
    foreach my $sheet ( @{ $excel->{Worksheet} } ) {

        #printf( "Sheet: %s\n", $sheet->{Name} );
        $sheet->{MaxRow} ||= $sheet->{MinRow};
        foreach my $row ( $sheet->{MinRow} .. $sheet->{MaxRow} ) {
            $sheet->{MaxCol} ||= $sheet->{MinCol};
            foreach my $col ( $sheet->{MinCol} .. $sheet->{MaxCol} ) {
                my $cell = $sheet->{Cells}[$row][$col];
                if ($cell) {
                    my $trimcell;
                    $trimcell = $cell->value();
                    print STDERR "cell: $trimcell\n"; ## Just for the tests so I don't have to open the file to see if it's ok
                    $trimcell =~ s/^\s+|\s+$//g;  ## Just to make sure I don't have extra spaces
                    $line .= "\"" . $trimcell  . "\",";
                }
            }
            chomp($line);
            if ($line =~ /Grand Total/){} ##customized for the files
            else {
            print format_file "$line\n";
            $line = '';
        }
        }
    }
    close format_file;
}

【问题讨论】:

  • 您在 DB 中哪里看到了错误的字符?
  • 您在代码开头是否有类似以下的内容? use utf8; use open qw/ :std :encoding(UTF-8) /;
  • 是的......问题出现在那个sn-p的某个地方。我有useutf8; binmode(STDOUT, ":utf8") 并不会改变任何事情。
  • @CDP1802 不,在文件本身中。 Excel 有正确的字符,而 CSV 没有。
  • 那么您使用什么客户端来检查 csv,一个文本编辑器?或者您是否使用 Excel 来查看 csv。您可以将BOM 字符添加到文件的开头,但这并不是必需的。

标签: excel csv perl encoding


【解决方案1】:

我的知识来自使用ETL::Pipeline,它使用Spreadsheet::XLSX 读取.xlsx 文件。 但我知道哪些字段是 UTF-8

我写了一个 Local ETL::Pipeline 模块来处理 Excel 文件的输出

use Encode qw(decode encode);

$ra_rec->{name} = decode( 'UTF-8', $ra_rec->{name}, Encode::FB_CROAK );

【讨论】:

  • 为了让这句话更清晰“我写了一个 Local ETL::Pipeline 模块来处理 Excel 文件的输出”。 TO:在将行/记录插入数据库之前,我编写了一个 Local ETL::Pipeline 模块来处理 UTF-8。
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
  • 2013-07-15
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多