広告 プログラミング言語-Perl

7 PerlからExcel,Wordを操作する

いよいよWindows でPerlを使う真骨頂!! MS-OfficeのOLEを用いて、データを取り出したり、加工したりします。

これも、いきなりサンプルソースを提示します。

「excel2text.pl」 適当なExcelファイルが複数入っているフォルダで実行すると、1シート目をTAB区切りテキストにして出力してくれます。

複数のエクセルファイルを順次処理している所等が、参考になるかもです。ファイル名をcp932からエンコードしたり、デコードしたり。

print OUT %en_sjis(......);としている所等。

なお、改行文字はASCIIと同じコードなので、エンコードに含めなくても大丈夫っぽい。

print OUT "\n";

とか。

OLEをPerlから呼び出している所は、Excel VBA を使い慣れた方なら「こんな風にやるんだ~」と、コツがつかめるのではないでしょうか。

そうなんです。Excel VBA そのまんまなんですよ~。Perlでは正規表現や連想配列も使えるので、VBAなんかより、遥かに便利です!

Wordを操作するサンプルは示しませんが、似たような感じでWord VBA が使えますよ。色々試してみてね~

サンプルソース「excel2text.pl」

#!/usr/bin/perl

# excel2text.pl

#必ずソースをUTF-8で記載すること。

use strict;
use Encode;
#use Encode::JP::H2Z;
use utf8;

use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
use Win32::OLE::Enum;

binmode STDIN, ":encoding(cp932)";   # 入力なのに、何故かencoding
binmode STDOUT, ":encoding(cp932)";
binmode STDERR, ":encoding(cp932)";
# ファイルハンドル<IN>等からの入力時はdecodeが必要
# ファイルハンドル<OUT>等への出力時はencodeが必要

our $debug=1;

# Excel オブジェクトはグローバル変数として宣言し取得。(そうしないと何個もExcelが開くので)
our $Excel=Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application','Quit');

#Excel ファイルは絶対pathでないと開かないようです。

our $ExcelDir=$0; #実行中のplスクリプトフルパス
$ExcelDir=&de_sjis($ExcelDir);
$ExcelDir=~s/[^\\]+\.pl$//;

&vv('$ExcelDir',$ExcelDir);

opendir (LS,&en_sjis($ExcelDir));

my @fnames=readdir(LS);
for my $FName(@fnames) {
    $FName=&de_sjis($FName);
    chomp $FName;
    if ($FName =~ /\.(xls|xlsx)$/) {
        print '$FName=[',$FName,"]\n";
        &excel2text($ExcelDir,$FName);
    }

}
$Excel->Quit();

print '[Finish!]',"\n";
<>;
exit;


sub excel2text
{
    my ($ExcelDir,$ExFileName)=@_;

    print 'ExFileName=[',$ExcelDir.$ExFileName,']',"\n";
    
    my $FNameHead=$ExFileName;
    $FNameHead=~s/\.(xls|xlsx)$//;
    &vv('$FNameHead',$FNameHead);

    my $Book=$Excel->Workbooks->Open(&en_sjis($ExcelDir.$ExFileName));
    print 'BookName=[',&de_sjis($Book->Name),']',"\n";

    my $SheetCnt=$Book->WorkSheets->Count;
    print 'SheetCnt=[',$SheetCnt,']',"\n";


#    for (my $i=1;$i<=$SheetCnt;$i++) {     # 全シート対象の場合
        my $i=1; #シート1のみ対象

        my $Sheet=$Book->Worksheets($i);
        my $SheetName=$Sheet->{'Name'};
        $SheetName=&de_sjis($SheetName);
        print 'SheetName=[',$SheetName,']',"\n";

        my $MaxRow = $Sheet->Cells->SpecialCells(xlCellTypeLastCell)->{'Row'};
        my $MaxCol = $Sheet->Cells->SpecialCells(xlCellTypeLastCell)->{'Column'};
        print 'MaxRow=[',$MaxRow,']',"\n";
        print 'MaxCol=[',$MaxCol,']',"\n";

        open (OUT,'>'.&en_sjis($ExcelDir.$FNameHead.'.txt'));
        for (my $row=1; $row<=$MaxRow+1; $row++) {
            for (my $col=1; $col<=$MaxCol+1; $col++) {
                my $str1=$Sheet->Cells($row,$col)->{'Value'};
                $str1=&de_sjis($str1);
                $str1=~s/(\t|\r|\n)//g;        # Tabや改行文字を削除する
                print OUT &en_sjis($str1."\t");   # Tab区切りテキストで、出力
            }
            print OUT "\n";
        }
        close(OUT);
#    }

    $Excel->{DisplayAlerts} = 'False';
    $Excel->Workbooks->close();
    close(OUT2);
}

print '[Finish!]',"\n";
<>;
exit;


#===============================
sub en_jis
{
    my ($buf)=@_;
    encode('iso-2022-jp',$buf);
}

sub de_jis
{
    my ($buf)=@_;
    decode('iso-2022-jp',$buf);
}

sub en_sjis
{
    my ($buf)=@_;
    encode('cp932',$buf);
}

sub de_sjis
{
    my ($buf)=@_;
    decode('cp932',$buf);
}

sub en_utf8
{
    my ($buf)=@_;
    encode('utf-8',$buf);
}

sub de_utf8
{
    my ($buf)=@_;
    decode('utf-8',$buf);
}

sub en_euc
{
    my ($buf)=@_;
    encode('euc-jp',$buf);
}

sub de_euc
{
    my ($buf)=@_;
    decode('euc-jp',$buf);
}

sub vv
{
    my($Name,$Value)=@_;
    if($debug) {
        print $Name.'=['.$Value.']',"\n";
    }
}

1;

ソースは必ずUTF-8に変換しよう(解説ページへ)

「cmd.exe」で「perl スクリプト名.pl」で実行(解説ページへ)

-プログラミング言語-Perl