end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

Spreadsheet::ParseExcelでlinuxのperlからexcelファイルを読む

2013/11/8 追記

久しぶり、Spreadsheet::ParseExcel をinstallしたところ、それが、ver.0.59 。以前、使用していたver.0.44から、仕様が変更になったのか、Spreadsheet::ParseExcel::FmtJapan2 を利用すると、逆に日本語のparseに失敗。

Spreadsheet::ParseExcel::FmtJapan2 は不要になったのかな?

つまり、これまでの

my $format = Spreadsheet::ParseExcel::FmtJapan2->new(Code => 'sjis');
my $excel = Spreadsheet::ParseExcel->new;
my $wbook = $excel->Parse($xls_path, $format);

のような処理を

#    my $format = Spreadsheet::ParseExcel::FmtJapan2->new(Code => 'sjis');
    my $excel = Spreadsheet::ParseExcel->new;
    my $wbook = $excel->Parse($xls_path);

のように Spreadsheet::ParseExcel::FmtJapan2 非依存にすれば
解消する気がします

Spreadsheet::ParseExcel

http://search.cpan.org/perldoc?Spreadsheet::ParseExcel

Spreadsheet::ParseExcelというperlモジュールがあれば、linuxperlからでもexcelファイルを読むことができますが、今回はそのinstall方法と使用方法を紹介します。

Spreadsheet::ParseExcel::FmtJapan2の設定?がちょっと面倒

読込み対象のexcelファイルに機種依存文字(例:㈱①)がある場合、Spreadsheet::ParseExcel::FmtJapan2をしますが、FmtJapan2を使用するには少々、追加作業が必要になるので、その作業を紹介します。

私の場合、Spreadsheet-ParseExcel-0.44をinstallしましたが、Spreadsheet-ParseExcel自体のinstallは簡単ですので、ここでは割愛します。

参考url:
http://search.cpan.org/src/JMCNAMARA/Spreadsheet-ParseExcel-0.44/README_Japan.htm

1)依存moduleのJcode.pm,Unicode::Mapをinstall

既に私のcolinux環境にはjcode ver.0.88がinstallされていたので、Unicode::Map ver.0.112のみをcpanコマンドでinstallしました。

# cpan
cpan[1]> install Unicode::Map
<略>
cpan[4]> exit
2)CP932Excel.mapをsite_perl以下にcopy

Spreadsheet-ParseExcel-0.44.tar.gz にはCP932Excel.mapというmapファイルがあるので、これをsite_perl以下にcopyして下さい。

# cd /usr/local/lib/perl5/site_perl/5.10.0/i686-linux-thread-multi/Unicode/Map/MS/WIN
# cp /tmp/CP932Excel.map .
3)REGISTORYファイルの編集

Unicode::MapのREGISTORYを編集すれば、作業完了です。

# cd /usr/local/lib/perl5/site_perl/5.10.0/i686-linux-thread-multi/Unicode/Map
# vi REGISTRY

#↓次の内容を追記してください. (既にあるCP932の後あたりへ)
name:    CP932Excel
srcURL:  $SrcUnicode/VENDORS/MICSFT/WINDOWS/CP932.TXT
src:     $DestUnicode/VENDORS/MICSFT/WINDOWS/CP932.TXT
map:     $DestMap/MS/WIN/CP932Excel.map

Spreadsheet::ParseExcelの動作テスト

Spreadsheet::ParseExcelの動作テストに使用したexcelファイル、perl script、及び実行結果を記載しておきます。

#!/usr/local/bin/perl

use strict;
use warnings;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan2;
use Data::Dumper;

sub main {
    my ($excel_file) = @_;

    my $format = Spreadsheet::ParseExcel::FmtJapan2->new(Code => 'sjis');
    my $excel = Spreadsheet::ParseExcel->new;
    my $book = $excel->Parse($excel_file, $format);

    for my $sheet ( @{$book->{"Worksheet"}} ){
	my $sheet_name = $sheet->{Name};
	print "#### sheet:$sheet_name\n";

	my $row_max = $sheet->{MaxRow};
	my $col_max = $sheet->{MaxCol};

	my $row = 0;
	while ($row <= $row_max){
	    my $col = 0;
	    while ($col <= $col_max){
		my $cell = $sheet->{Cells}->[$row]->[$col];
		if ($cell) {
		    my $val = $cell->value();
		    print "$val\t";
		}
		$col++;
	    }
	    print "\n";
	    $row++;
	}
    }
}

main(@ARGV);
[endo@colinux tmp]$ ./excel_parse.pl Book1.xls 
#### sheet:シート1
てすと  テスト  テスト     
㈱      ①      
値参照  値参照  
#### sheet:Sheet2
1       1       
[endo@colinux tmp]$ 

Attempt to bless into a reference 〜 Spreadsheet/ParseExcel/FmtJapan.pm line 96.

と、エラーになったら、FmtJapan.pm line 96. を次のように書換えてみましょう

旧)    return bless $self, $class;
新)    return bless $self, ref($class) || $class;

式の内容は取得できない?

先程のexcelファイルでB3セルを「=A3」として、A3を参照するようにしていましたが、この式(=A3)を取得する方法が分かりませんでした。
Spreadsheet::ParseExcelでは、式の内容は取得できないのかもしれません。