みんな大好き Excel ファイルを perl で書くメモ。
perl モジュール Spreadsheet::WriteExcel で Excel 関数を使いたいと思った
ので調べました。
CPAN の ココ を読むとこんな感じで簡単にできるらしい。
$sheet->write( 5, 1, '=SUM(B2:I2)');
簡単!!
でも、列名をアルファベットで指定しなければならないので、このままだとちょ
っと微妙。
行と列に合わせて計算範囲も勝手にシフトして欲しい。でも、持ってる列情報
は数字だけ。
と、言うことで “数字” => “アルファベット” に変換する方法を考えて書いた
のがコレ。
#!/usr/bin/perl use strict; use warnings; use Spreadsheet::WriteExcel; my $file = "dir/perl.xls"; my $font_name = 'MS UI Gothic'; my $font_size = '11'; my $book = Spreadsheet::WriteExcel->new("$file"); my $sheet = $book->add_worksheet(); my $format0 = $book->add_format( font => $font_name, size => $font_size, bold => 1, border => 1, valign => 'vcenter', align => 'center' ); my $format1 = $book->add_format( font => $font_name, size => $font_size, bold => 1, border => 1, valign => 'vcenter', align => 'center' ); my $x = '0'; my $y = '0'; $sheet->merge_range( $x, $y, $x, $y + 5, "write start", $format0 ); $x++; for (my $i = '0'; $i <= '5'; $i++ ) { for (my $j = '1'; $j <= '20'; $j++ ) { $sheet->write( $x, $y + $i, int( rand(100) ), $format1 ); $x++; if ( $j == '20' ) { my $abc = &column_abc( $y + $i ); my $range = $abc . ($x - $j) . ":" . $abc . $x; my $excel_func = "=SUM($range)"; $sheet->write( $x, $y + $i, $excel_func, $format1 ); } } $x = '1'; } $book->close(); sub column_abc { my $position = shift; my @abc = ( 'A'..'Z' ); my ( $abc, $i, $j ); if ( $position > '701' ) { $abc = "over"; } elsif ( $position > '51' ) { $i = int( $position / 26 ) - 1; $j = $position - ( $i + 1 ) * 26; $abc = "$abc[$i]$abc[$j]"; } elsif ( $position > '25' ) { $i = int( $position / 26 ) - 1; $j = $position - 26; $abc = "$abc[$i]$abc[$j]"; } else { $i = $position; $abc = "$abc[$i]"; } return( $abc ); } exit;
これを実行するとこんなやつができます。
列名の変換は A ? ZZ までは対応。
意外と難しくて、結構やっつけな感じで書いてます。
AAA (703 列) 以上は省きましたが、702 列もあれば流石に足りるだろって事で。
でも、いざやってみると Spreadsheet::WriteExcel では 256 列までしか書け
ないようなので、この方法で OK と思うことにしました。