Excel :: Writer :: XLSX无法读取的内容错误

时间:2018-09-17 07:30:55

标签: excel perl excel-writer-xlsx

我刚开始使用Perl,正在使用 Excel::Writer::XLSX 查询DB2数据库并将数据导出到.xlsx文件。数据大约有25万行。

脚本运行正常,但是当我尝试打开Excel文件时,它将引发错误并要求修复该文件。修复后,某些数据将替换为inf

Error dialog saying "Excel found unreadable content in 'Chk.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."

下面是我的代码的一个片段。

while ( my $sqlStatement = ) {

    $mSQL = $dbh->prepare( $sqlStatement )
            or die "Can't prepare $sqlStatement";
    $mSQL->execute()
            or die "Can't execute $sqlStatement";
}

my $workbook = Excel::Writer::XLSX->new( $ARGV[2] );
$workbook->set_tempdir( '/tempDir/' );
$workbook->set_optimization();

my $worksheet = $workbook->add_worksheet();
$worksheet->keep_leading_zeros();

my $row    = 0;
my $column = 0;

my @emptyRow = ();

$worksheet->write_row( $row++, $column, [ @{ $mSQL->{NAME_uc} } ] );
$worksheet->write_row( $row++, $column, [ @emptyRow ] );

while ( my @Row = $mSQL->fetchrow_array ) {
    $worksheet->write_row( $row++, $column, [ @Row ] );    #, $cellFormat);
    $count++;
}

$workbook->close();

有人可以在这个问题上给我建议吗?

1 个答案:

答案 0 :(得分:3)

最后,我弄清楚了(感谢约翰·麦克纳马拉)。通过添加使用正则表达式的写入处理程序来解决此问题,该处理程序使用正则表达式检查特定令牌是否已转换为“ inf”,如果这样做,则调用write_string子例程而不是write_row。 下面是代码。

#!/usr/bin/perl

use strict;
use warnings;
use Excel::Writer::XLSX;


my $workbook  = Excel::Writer::XLSX->new( 'write_handler5.xlsx' );
my $worksheet = $workbook->add_worksheet();


# Add a handler to match any numbers in order to check for and handle
# infinity.
$worksheet->add_write_handler( qr[\d], \&write_with_infinity );


# The following function is used by write() to pre-process any the data when a
# match is found. If it finds something that looks like a number but evaluates
# to infinity it write it as a string.
sub write_with_infinity {

    my $worksheet = shift;
    my @args      = @_;
    my $token     = $args[2];

    # Check if token looks like a number, in the same way as write().
    if ( $token =~ /^([+-]?)(?=[0-9]|\.[0-9])[0-9]*(\.[0-9]*)?([Ee]([+-]?[0-9]+))?$/ ) {

    # Check for infinity.
    $token = $token + 0;

    if ($token =~ /inf/) {

        # Write the value as a string instead of a number.
        return $worksheet->write_string( @args );
    }
    }

    # Reject the match and return control to write()
    return undef;
}