Spreadsheet::ParseExcel

仕事で、Excelファイルの内容をHTMLに大量にコピペすることになって辟易してたんだけど、このモジュールとTenjinを使うことで楽しくなってきたw

 *Tenjin::Context::v = sub{
    my ($book_name,$sheet,$cell) = @_;
    my ($row,$col);
    if($cell =~ /^([^\d]+)(\d+)$/){
        $row = $2 - 1;
        $col = col_num($1);
    }else{
        die "not_found: $book_name=>$sheet=>$cell\n";
    }
    my $sheet = book($book_name)->{Worksheet}[$sheet];
    return $sheet->{Cells}[$row][$col]->Value;
};

↑Tenjinのテンプレート内で
[= v("○○台帳.xls",0,"C14") =]
と書くと、○○台帳.xlsのシート1のセルC14番目をその位置に差し込んでくれるようにしたいわけだ。


Excelを読み込むのは重い処理なので、一度読みこんだものはキャッシュしておく関数book。

my $book_cache = {};
sub book{
    my $path = shift;
    unless(defined $book_cache->{$path}){
        $book_cache->{$path} = $parser->Parse($path);
    }
    return $book_cache->{$path};
}

列名はA〜ZプラスAA〜AZあれば十分ということで、アルファベットの列名を序数に変更する関数col_num。

my %col_name;
{
    my @col_name = ('A'..'Z');
    my $i=0;
    %col_name = map {$_=>$i++} (@col_name,map {"A$_"} @col_name);
}
sub col_num{
    my $n = shift;
    return $col_name{$n};
}

ま、ハッシュで直接変換させてもいいわけだけど、関数にしておくと今後変更が必要な時に柔軟に対応できたりするので、ここでも一応関数にしておく。

以上をヘルパークラスに収めるのは次回に。