Home > Perl > Spreadsheet::ParseExcel - ごくごく普通の使い方メモ

Spreadsheet::ParseExcel - ごくごく普通の使い方メモ

  • 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
後日もうちょっと調べてみます。
ご指摘ありがとうです!

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Home > Perl > Spreadsheet::ParseExcel - ごくごく普通の使い方メモ

Search
Feeds

Page Top