带日语(宽)字体的Excel

时间:2010-09-16 07:53:17

标签: perl unicode

我正在解析在某些单元格中包含日语的Excel文件。通过使用 Spreadsheet :: ParseExcel(Ver.15)(我知道它比当前版本旧),一些单元格的字符如下:

  

<设定B-1コース>

显示为:

  

print Dumper $ oWkc-&gt; {_ Value};

     

$ VAR1 =“\ x {ff1c} \ x {8a2d} \ x {5b9a} B- \ x {ff11} \ x \ x {xfc} \ x {xf2} \ x {ff1e}” ;

  

打印$ oWkc-&gt; {Val}。 “\ n” 个;

     

[ - 0

     

$ VAR1 =“\ x {ff1c} \ x {8a2d} \ x {5b9a} B- \ x {xf}} \ x {xfc} \ x \ f {ff1} ;

     

[ - 0

如果我想在实际的foramat中打印这些值,我将STDOUT File句柄设置为“:utf8 ”,并且我的终端显示utf-8编码(否则我得到了一些“广泛的性格”警告)。在这里,我必须选择B-1或B-2的单元格,但我不确定在我的脚本中应该设置什么,以便这些字符可以被视为我能够在STDOUT上看到它们。

目前我使用正则表达式将这些宽字符转换为相应的ASCII值。作为一个例子,如果我想匹配存储为'B- \ x {ff11}'的B-1,我将

$oWkc->{_Value} =~ /([AB]-)(\x{ff11}|\x{ff12}|\x{ff13}/
my $lookup = $1.$2;
$lookup =~ s/\x{ff11}/1/;
$lookup =~ s/\x{ff12}/2/;
$lookup =~ s/\x{ff13}/3/;

作为参考,B-1,A-2等这些值来自其他一些来源,目前的范围是A | B- [1-3]。

处理这些宽字符的标准方法是什么?我无法使用编码/解码等。任何人都可以给我一些方向吗?

目前虽然我能够使用正则表达式完成工作......

2 个答案:

答案 0 :(得分:3)

虽然我没有验证它(我不打算从2001年3月开始安装模块),但模块显然已经解码为Perl本地字符串,所以你不需要做太多。直截了当的方式工作得很好,不需要通过这些替换使事情过于复杂。

use utf8;
my $val = '<設定B-1コース>';

# does it match A or B, followed by a dash, followed by a fullwidth 1,2 or 3?
$val =~ /(?:A|B)-[123]/;  # returns true/1

答案 1 :(得分:2)

要处理Spreadsheet::ParseExcel中的多字节字符,您应该更新到最新版本并使用FmtJapan格式化程序。日语格式的几个错误修复进入了最新版本。

以下是一个例子:

#!/usr/bin/perl


use warnings;
use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan;

my $filename  = 'Test2000J.xls';
my $parser    = Spreadsheet::ParseExcel->new();
my $formatter = Spreadsheet::ParseExcel::FmtJapan->new();
my $workbook  = $parser->parse($filename, $formatter);

if ( !defined $workbook ) {
    die "Parsing error: ", $parser->error(), ".\n";
}

# Set your output encoding.
binmode STDOUT, ':encoding(cp932)';
# Or maybe this:
#binmode STDOUT, ':utf8';


for my $worksheet ( $workbook->worksheets() ) {

    print "Worksheet name: ", $worksheet->get_name(), "\n\n";

    my ( $row_min, $row_max ) = $worksheet->row_range();
    my ( $col_min, $col_max ) = $worksheet->col_range();

    for my $row ( $row_min .. $row_max ) {
        for my $col ( $col_min .. $col_max ) {

            my $cell = $worksheet->get_cell( $row, $col );
            next unless $cell;

            print "    Row, Col    = ($row, $col)\n";
            print "    Value       = ", $cell->value(),       "\n";
            print "    Unformatted = ", $cell->unformatted(), "\n";
            print "\n";
        }
    }
}