work.log

元エンジニアの備忘録的ブログ

Spreadsheet::WriteExcel で Excel 関数を使う

投稿:2013-02-13 17:34  更新:

みんな大好き 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;

これを実行するとこんなやつができます。

perl_excel2

列名の変換は A ? ZZ までは対応。
意外と難しくて、結構やっつけな感じで書いてます。

AAA (703 列) 以上は省きましたが、702 列もあれば流石に足りるだろって事で。

でも、いざやってみると Spreadsheet::WriteExcel では 256 列までしか書け
ないようなので、この方法で OK と思うことにしました。

おすすめのVPSサーバ

  • OSが選べる
  • VPS同士でLANが組める
  • 複数台構成向き

このブログで使っています。

  • 転送量が多いサービスに
  • 借りてるのは3年間一度もdown無し!

よく見られている記事

  • 本日
  • 週間
  • 月間