- 2006-07-06 (木)
- Perl
川合孝典さん作の、Perlからエクセルシートを扱えるCPANモジュール - Spreadsheet::ParseExcel - の使い方基本形。サンプルコード備忘録。
sample: エクセルからデータを読みとる
parseExcel.pl
#!/usr/bin/perl -w
use strict;
use Dumpvalue;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan;
our @COL_DEF= qw(
pid
name
stand_name
);
our $PKEY = 'pid';
our $FILE = 'jojo.xls';
my %dupChk; # for checking duplicate records
my $dv = Dumpvalue->new; # for data dumping
my $fmt = Spreadsheet::ParseExcel::FmtJapan->new( Code=>'utf8' );
my $xls = Spreadsheet::ParseExcel::Workbook->Parse( $FILE, $fmt );
foreach my $ws (@{ $xls->{Worksheet} }){
for(
my $iR = $ws->{MinRow};
defined $ws->{MaxRow} && $iR <= $ws->{MaxRow};
$iR++
){
# fetch columns
my @cols;
for(
my $iC = $ws->{MinCol};
defined $ws->{MaxCol} && $iC <= $ws->{MaxCol};
$iC++
){
my $cell = $ws->{Cells}[$iR][$iC];
push(@cols,$cell->Value);
}
# create column data hash
my %recs;
@recs{ @COL_DEF } = @cols;
# duplicate key check
my $pkey = $recs{ $PKEY };
if($dupChk{ $pkey }){
warn "duplicate entry $pkey";
next;
}
$dupChk{ $pkey }++;
#
# do whatever routine with %recs here
# ie: database insert
#
print $dv->dumpValue(\%recs);
print "\n";
}
}
注意点
フォーマット指定 S::P::FmtJapan をしておかないと warning が大量に出る
日本語文字列 (ucs2) がエクセルに含まれている場合、上記サンプルのように、Parse() する際 $fmt を指定しておかないとこんな感じの warnings が大量に出まくるので注意:
Character in 'C' format wrapped in pack at ...
※ S::P::FmtJapan を使うには Jcode が必要。
フォーマットは S::P::FmtJapan で充分
他にも FmtJapan2 とか FmtUnicode とかありますが、FmtJapan がよさげ。理由:
- FmtJapan2 も FmtUnicode も、Unicode::Map なるモジュールに依存している。今まで使った事無いし・・・ Encode / Jcode の方がいいなぁ。
- FmtJapan2 はコンストラクタにて Unicode::Map のマッピング 'CP932Excel' を読み込もうとするも、インストールしたバージョン v0.112 だと、マッピングファイルが存在しなくてエラーになる。
課題・理解が足りない部分
でかいエクセル読むとメモリ喰いまくる点
サンプルコードで使ったエクセル、行6 x 列3 くらいだとインスタンス作って一通りループまわした前後でメモリ増加量は
memory bloat : 288k
位なのに対して、 思いっきり行数増やして 行20000 x 列3 くらいにすると、同じ処理流した後でのメモリ増加量は
memory bloat : 37.5M
と、順当に増える。セルごとの文字数がもっと多いと、余裕で100M越えしたりする (このエクセルとか)。これを XML::Parser みたいに、行ごとに効率よく read & release memory していく方法は無いのかなぁ、と。課題。
※サンプルコード一式はこちら。要GTopモジュール。
Comments:3
- たくと 2006-09-12 (火) 17:06
-
FmtJapan だと「?」とか、化けません?
'CP932Excel' は、CPAN から直接ソースをダウンロードした中にある README_Japan.htm に、
設置手順が書いてありました。http://search.cpan.org/~kwitknr/Spreadsheet-ParseExcel-0.2603/
- たくと 2006-09-12 (火) 17:11
-
投稿確認の画面では化けてなかったのですが……
「?」の中は、「月曜から金曜」などで用いる「から」を示す波線を書いたのです。
- bashi 2006-09-14 (木) 23:13
-
ほんとですね・・・。
波線 = CP932をうまく変換できていないようです。
windows環境で作成されたエクセルファイルは FmtJapan2 を使う必要があるのかも、ですね。
perl5.8なら Jcode = Encode ラッパーなのでどうにかならないかと、小一時間 FmtJapan で格闘してみたものの・・・無理でした orz
後日もうちょっと調べてみます。
ご指摘ありがとうです!