3

だから私はこのクレイジーな考えを持っていました。現在、次のように Text::CSV_XS を使用して Word でテーブルを生成しています。

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
use Text::CSV_XS;

# instantiation of word and Text::CSV_XS omitted for clarity
my $select = $word->Selection;
foreach my $row (@rows) { # @rows is an array of arrayrefs
    $csv->combine(@{$row});
    $select->InsertAfter($csv->string);
    $select->InsertParagraphAfter;
}
$select->convertToTable(({'Separator' => wdSeparateByCommas});

しかし、次のようなことができればもっとクールです。

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
use Text::CSV_XS;

# instantiation of word and Text::CSV_XS omitted for clarity
my $select = $word->Selection;
foreach my $row (@rows) { # @rows is an array of arrayrefs
    $csv->bind_columns($row);
    $csv->print( 
        sub {
            my $something; # Should be the combine()'d string
            $select->InsertAfter($something);
            $select->InsertParagraphAfter;
        },
        undef
    ); 
}
$select->convertToTable(({'Separator' => wdSeparateByCommas});

私の質問は$something、2 番目のコード サンプルをどのように取得するか、また、クロージャをハンドルのように見せるにはどうすればよいかということです。

4

2 に答える 2

2

Text::CSV::printハンドルは必ずしも必要ではありません。printドキュメントには、メソッドで何かが必要であると書かれています。

{
    package Print::After::Selection;
    sub new {
        my ($pkg, $selection) = @_;
        my $self = { selection => $selection };
        return bless $self, $pkg;
    }
    sub print {
        my ($self, $string) = @_;
        my $selection = $self->{selection};
        $selection->InsertAfter($string);
        $selection->InsertParagraphAfter;
        return 1;  # return true or Text::CSV will think print failed
    }
}

...
$csv->print( Print::After::Selection->new( $word->Selection ), undef );
...

(未検証)

于 2013-02-01T17:06:34.070 に答える
2

次のインターフェイスを使用して、Word でデータを作成する方法を実際に尋ねていると思います。

my $fh = SelectionHandle->new($selection);
my $csv = Text::CSV_XS->new({ binary => 1 });
$csv->print($fh, $_) for @rows;

(それは悪い考えだと思います。裏返しです。代わりに、カプセル化された CSV オブジェクトを使用してフォーマットするオブジェクトを作成してください。)

オブジェクトに変数 (スカラー、配列、ハッシュ、ファイル ハンドル) のインターフェイスを与えたい場合は、tie. あなたがするとき、あなたはで終わる

use SelectionHandle qw( );
use Text::CSV_XS    qw( );

my $selection = ...;
my @rows      = ...;

my $fh = SelectionHandle->new($selection);
my $csv = Text::CSV_XS->new({ binary => 1 });
$csv->print($fh, $_) for @rows;

モジュールは次のようになります。

package SelectionHandle;

use strict;
use warnings;

use Symbol      qw( gensym );
use Tie::Handle qw( );

our @ISA = qw( Tie::Handle );

sub new {
   my ($class, $selection) = @_;
   my $fh = gensym();
   tie(*$fh, $class, $selection);
   return $fh;
}

sub TIEHANDLE {
   my ($class, $selection) = @_;
   return bless({
      selection => $selection,
   }, $class);
}

sub PRINT {
   my ($self, $str) = @_;
   my $selection = $self->{selection};
   $selection->InsertAfter($str);
   $selection->InsertParagraphAfter();
   return 1;
}

1;
于 2013-02-01T17:33:59.360 に答える