perlms-wordwin32ole

Inserting a picture in a word document with perl Win32::OLE


I'm developing a tool to generate Word documents with Win32::OLE in a Perl CGI, and I'm facing a problem I can't solve : when I insert a picture, it shows at the very end of the generated document, wherever I asked it to be inserted.

Here's a sample code that explains my worries, where $go_document is my Word document ans $as_file the path to my picture file:

$go_document->ActiveWindow->Selection->TypeText( "before the picture\n" );

my $last = $go_document->Paragraphs->Count;
my $para = $go_document->Paragraphs( $last );
$go_document->InlineShapes->AddPicture( WorkDir() . $as_file, 0, 1, $para->Range );

$go_document->ActiveWindow->Selection->TypeText( "after the picture\n" );

The result includes the expected text lines, but the image shows after the second one. Moreover, if I include 2 pictures, the second one shows at the end of the document, but before the first one !

Is there something I should do and I forgot? Thanks in advance for any help.


Solution

  • I've never used perl, so I can only give you pseudo-code, based on my knowledge of the Word object model and what I see in the code in the question. Together with the explanation below, that hopefully should be enough to get you going...

    One of the most useful objects in Word's object model is Range. Think of a Range like an invisible selection in order to work with it. Automation code can use multiple Ranges, but there can be only one Selection, which is one reason Ranges are useful. Another is that execution is generally faster and there's less screen flicker.

    If the goal is to insert pictures at the end of the document what's needed is a Range that represents the end-point of the document. For example (pseudo-code! I don't know how to specify the member of a Word Enumeration in perl):

    my $endDocRange = $go_document->Content;
    $endDocRange->Collapse(Word.WdCollapseDirection.wdCollapseEnd);
    

    Think of this like first selecting the entire document, then pressing right-arrow to end up with a blinking cursor at the very end of the document.

    The object $endDocRange is then used as the target Range for the picture:

    $go_document->InlineShapes->AddPicture( WorkDir() . $as_file, 0, 1, $endDocRange );
    

    If the above code is run again an additional picture should appear at the end of the document, after the first picture. (But no guarantees where the text in the first line will end up as the Selection probably won't change, based only on the code in the question.)