-->

How do I apply formatting to a particular word in

2019-04-13 17:07发布

问题:

For example, my docx file contains the following sentences:

This is a Perl example
This is a Python example
This is another Perl example

I want to apply bold style to all the occurrences of the word "Perl" like so:

This is a Perl example
This is a Python example
This is another Perl example

I've so far come up with the following script:

use strict; use warnings;
use Win32::OLE::Const 'Microsoft Word';

my $file = 'E:\test.docx';

my $Word = Win32::OLE->new('Word.Application', 'Quit');
$Word->{'Visible'} = 0;
my $doc = $Word->Documents->Open($file);
my $paragraphs = $doc->Paragraphs() ;
my $enumerate = new Win32::OLE::Enum($paragraphs);


while(defined(my $paragraph = $enumerate->Next())) {

    my $text = $paragraph->{Range}->{Text};
    my $sel = $Word->Selection;
    my $font = $sel->Font;

    if ($text =~ /Perl/){
        $font->{Bold} = 1;              
    }   
    $sel->TypeText($text);          
}

$Word->ActiveDocument->Close ;
$Word->Quit;

But it has applied bold style to the whole paragraph and it does not edit the sentences in their original place. It gives me both the modified version and the original version like this:

This is a Perl example
This is a Python example
This is another Perl example
This is a Perl example
This is a Python example
This is another Perl example

How should I fix my problem. Any pointers? Thanks like always :)

UPDATE

Problem solved! Big thanks to @Zaid, and @cjm :)

Here's the code that works lovely:

while ( defined (my $paragraph = $enumerate->Next()) ) {

    my $words = Win32::OLE::Enum->new( $paragraph->{Range}->{Words} );

    while ( defined ( my $word = $words->Next() ) ) {

        my $font = $word->{Font};
        $font->{Bold} = 1 if $word->{Text} =~ /Perl/;
    }
}

回答1:

Try using the Words method instead of Text.

Untested:

while ( defined (my $paragraph = $enumerate->Next()) ) {

    my $words = Win32::OLE::Enum->new( $paragraph->{Range}->{Words} );

    while ( defined ( my $word = $words->Next() ) ) {

        my $font = $word->{Font};
        $font->{Bold} = 1 if $word->{Text} =~ /Perl/;
    }
}


回答2:

I dont know anything about perl. But you look at office open xml

You can use treat the .docx file as a zip file, and do a simple search and replace, wich works a million times quicker than the interop. and you dont have to worry about the million things that can go wrong with it also.

Rename your .docx file to .zip and open it and you will see what I mean.