File Coverage

lib/Win32/Word/Writer.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             =head1 NAME
2            
3             Win32::Word::Writer - Create Microsoft Word documents
4            
5            
6             =head1 DESCRIPTION
7            
8             Easily create MS Word documents, abstracting away the Word.Application
9             DOM interface and all the required workarounds. The DOM interface is
10             still exposed for doing more fancy stuff.
11            
12            
13            
14             =head1 SYNOPSIS
15            
16             use strict;
17             use Win32::Word::Writer;
18            
19             my $oWriter = Win32::Word::Writer->new();
20            
21             #Adding text and paragraphs with different styles
22             $oWriter->WriteParagraph("Example document", heading => 1); #Heading level 1
23             $oWriter->WriteParagraph("Usage", style => "Heading 2"); #Style "Heading 2"
24             $oWriter->WriteParagraph("Write sentences to the document using a"); #Normal
25             $oWriter->WriteParagraph("heading level, or Normal
26             if none is specified. "); #\n is new paragraph
27            
28             $oWriter->Write("Add some more text the current paragraph");
29            
30             $oWriter->NewParagraph(style => "Envelope Return"); #The style must exist
31             $oWriter->Write("Return to sender. ");
32            
33             $oWriter->SetStyle("Envelope Address"); #Change the current style
34             $oWriter->Write("Nope, we changed the style of the entire paragraph");
35             $oWriter->Write("to a footer style");
36            
37             #Setting character styles
38             $oWriter->WriteParagraph("Some more normal text. ");
39             $oWriter->SetStyle("Hyperlink"); #A charachter style
40             $oWriter->Write("http://www.DarSerMan.com/Perl/");
41             $oWriter->ClearCharacterFormatting(); #Clear character style
42             $oWriter->Write(" <-- my ");
43            
44             #Bold/Italics
45             $oWriter->ToggleBold(); #Toggle bold
46             $oWriter->Write("Perl ");
47             $oWriter->SetItalic(1); #Turn on Italic
48             $oWriter->Write("stuff.");
49             $oWriter->ToggleItalic(); #Toggle Italic
50             $oWriter->SetBold(0); #Turn off bold
51            
52             #Bullet point lists
53             $oWriter->ListBegin();
54             $oWriter->ListItem();
55             $oWriter->Write("The first bullet item");
56             $oWriter->ListItem();
57             $oWriter->Write("The second bullet item");
58            
59             $oWriter->ListBegin(); #Nested bullet point list
60             $oWriter->ListItem();
61             $oWriter->Write("The first inner bullet item");
62             $oWriter->ListItem();
63             $oWriter->Write("The second inner bullet item");
64            
65             $oWriter->ListEnd();
66             $oWriter->ListEnd();
67            
68            
69             #Do this at regular intervals (say, every couple of 10K of text you add)
70             $oWriter->Checkpoint();
71            
72            
73             #Tables
74             $oWriter->WriteParagraph("Table example", heading => 1);
75             $oWriter->NewParagraph();
76            
77             $oWriter->TableBegin();
78             $oWriter->TableRowBegin();
79             $oWriter->TableColumnBegin();
80             $oWriter->SetBold(1);
81             $oWriter->Write("HTML table");
82             $oWriter->TableColumnBegin();
83             $oWriter->Write("Win32::Word::Writer");
84            
85             $oWriter->TableRowBegin();
86             $oWriter->TableColumnBegin();
87             $oWriter->SetBold(0);
88             $oWriter->Write(""); ");
89             $oWriter->TableColumnBegin();
90             $oWriter->Write("TableBegin()");
91            
92             $oWriter->TableRowBegin();
93             $oWriter->TableColumnBegin();
94             $oWriter->Write("
95             $oWriter->TableColumnBegin();
96             $oWriter->Write("TableRowBegin()");
97            
98             $oWriter->TableEnd();
99            
100            
101             #Save the document
102             $oWriter->SaveAs("01example.doc");
103            
104            
105            
106             =head1 INSTALLATION
107            
108             With L, the regular CPAN
109             shell should work:
110            
111             cpan Win32::Word::Writer
112            
113             All L except Microsoft Word itself should
114             sort itself out automatically.
115            
116             This may work with ActiveState too if you have the MinGW compiler, or
117             it might be easier to install with C (if available, I'm not sure
118             about the state of the PPM repos at this point).
119            
120            
121            
122             =head1 CONCEPTS
123            
124             Win32::Word::Writer uses an OLE instance of Word to create Word
125             documents.
126            
127             The documents are constructed in a linear fashion, i.e. you add text
128             to the document and generally don't move around the document a lot.
129            
130            
131             =head2 Styles
132            
133             A "style" in Word is a set of properties that can be assigned to a
134             piece of text. There are two types of styles: Paragraph and Character
135             styles.
136            
137             "Normal", and "Heading 1" are example of paragraph styles.
138            
139             When a paragraph gets applied to a piece of text it applies to the
140             entire paragraph, whereas the character style only affects the actual
141             chars. You can see the difference if you open a Word document and look
142             at the available styles.
143            
144            
145             =cut
146            
147             package Win32::Word::Writer;
148            
149             our $VERSION = '0.03';
150            
151            
152            
153 13     13   59634 use warnings;
  13         34  
  13         542  
154 13     13   74 use strict;
  13         28  
  13         457  
155            
156 13     13   93 use Carp;
  13         44  
  13         1108  
157            
158 13     13   71 use File::Spec;
  13         27  
  13         357  
159 13     13   6823 use Win32::OLE;
  0            
  0            
160             use Win32::OLE::Const;
161             use File::Temp;
162             use Data::Dumper;
163            
164             use Win32::Word::Writer::Table;
165            
166            
167             my $rhConst = Win32::OLE::Const->Load('Microsoft Word') or Croak("Could not load Word constants. Is Word installed?");
168            
169            
170            
171            
172            
173             =head1 PROPERTIES
174            
175             =head2 oWord
176            
177             A Win32::OLE object with a Word Application instance.
178            
179            
180             =head2 oDocument
181            
182             A Win32::OLE object with the Application's Document object. Often used
183             shorthand.
184            
185            
186             =head2 oSelection
187            
188             A Win32::OLE object with the Application's Selection object.
189            
190            
191             =head2 oTable
192            
193             The current Win32::Word::Writer::Table object, if a table is
194             being created, or undef if not.
195            
196            
197             =cut
198             use Class::MethodMaker new_with_init => "new", get_set =>
199             [ qw(
200             oWord
201             oDocument
202             oSelection
203             hasWrittenParagraph
204             hasWrittenText
205             levelIndent
206             hasWrittenInIndent
207             oTable
208             rhConst
209             styleOld
210             fileTemp
211             )
212             ];
213            
214            
215            
216            
217            
218             =head1 METHODS
219            
220             Note that all methods return 1 or die on errors, unless otherwise
221             stated.
222            
223            
224             =head2 new()
225            
226             Create new Word Writer object which can be written to.
227            
228             Return new object, or die on errors.
229            
230            
231            
232             =head2 init()
233            
234             Init the object. Called by new.
235            
236             =cut
237             sub init {
238             my $self = shift;
239             my (%hParam) = @_;
240            
241             $self->levelIndent(0);
242             $self->hasWrittenInIndent(0);
243             $self->hasWrittenParagraph(0);
244             $self->hasWrittenText(0);
245             $self->rhConst($rhConst);
246             $self->oWord( Win32::OLE->new('Word.Application'));
247             Win32::OLE->Option(Warn => 3);
248            
249             $self->oDocument( $self->oWord->Documents->Add ) or die("Could not add Word document\n");
250             $self->oSelection( $self->oWord->Selection ) or die("Could not get Word selection\n");
251             $self->oTable(undef);
252             $self->styleOld("");
253             $self->fileTemp("");
254            
255             # $self->oWord->{ScreenUpdating } = 0; #Makes it faster. Visible = 0 would make it faster, but doesn't work for all operations. See also: http://word.mvps.org/FAQs/InterDev/MakeAppInvisible.htm
256             $self->oWord->{DisplayAlerts} = $rhConst->{wdAlertsNone}; #Suppress dialog boxes. Doesn't work that well though...
257             return;
258             }
259            
260            
261            
262            
263            
264             =head2 Open($file)
265            
266             Discard the current document and open the Word document in
267             $file.
268            
269             Note that you may want to MoveToEnd() after opening an existing
270             document before adding new text.
271            
272             Note that this object is in an unusable state if the Open
273             fails to load a document.
274            
275             =cut
276             sub Open {
277             my $self = shift;
278             my ($file) = @_;
279            
280             $file = File::Spec->rel2abs($file);
281             -f $file or croak("Could not open file: File ($file) does not exist");
282             -r $file or croak("Could not open file: Can't read File ($file)");
283            
284             $self->Close();
285            
286             my $oDocument = $self->oWord->Documents->Open({
287             FileName => $file,
288             ConfirmConversions => $self->rhConst->{False}, #Don't show dialog
289             Revert => 1, #Discard changes
290             Visible => 0, #No window
291             });
292             $oDocument->Select; #Otherwise we have no selection
293             $self->oSelection( $self->oWord->Selection ) or die("Could not get Word selection\n");
294            
295             $self->oDocument($oDocument);
296            
297             $self->Checkpoint(); #Release locks on the template file, otherwise other Word instances may not be able to open it
298            
299             return(1);
300             }
301            
302            
303            
304            
305            
306             =head2 SaveAs($file, %hOpt)
307            
308             Save the document to $file (may be a relative file name). %hOpt is:
309            
310             format => $format -- Save $file as $format (default:
311             Document). Valid values are: Document, DOSText, DOSTextLineBreaks,
312             EncodedText, HTML, RTF, Template, Text, TextLineBreaks, UnicodeText
313            
314             (A common mistake is to inspect the document in another Word instance
315             when re-running a script. The document will be locked by Word and the
316             script can't re-create the file.)
317            
318             =cut
319             sub SaveAs {
320             my $self = shift;
321             my ($file, %hOpt) = @_;
322             my $format = $hOpt{format} || "Document";
323            
324             defined(my $formatConst = $self->rhConst->{"wdFormat$format"}) or croak("Invalid format ($format), use Document, DOSText, DOSTextLineBreaks, EncodedText, HTML, RTF, Template, Text, TextLineBreaks, UnicodeText");
325            
326             $file = File::Spec->rel2abs($file);
327            
328             eval { $self->oDocument->SaveAs({ FileName => $file, FileFormat => $formatConst }) };
329             if($@) {
330             my $err = $@;
331             if($err =~ /OLE exception from "Microsoft Word":\n\n(.+?)\nWin32::OLE/si) {
332             croak("Could not save file ($file): $1");
333             }
334             croak($err);
335             }
336            
337             return(1);
338             }
339            
340            
341            
342            
343            
344             =head2 Checkpoint()
345            
346             Checkpoint the document, i.e. save it to a temp file.
347            
348             This is necessary to do sometimes because Word seems to keep state
349             until the document is saved, and when using Word automation you tend
350             to exercise the application in ways they haven't tested properly. And
351             after a while you get weird errors, just because Word couldn't deal
352             with all that information.
353            
354             So you should call this after adding, say, 20K of text to the document
355             (this is true for Word 2000, it may be better in later versions).
356            
357             =cut
358             sub Checkpoint {
359             my $self = shift;
360            
361             $self->SaveAs( $self->GetFileTemp );
362            
363             return(1);
364             }
365            
366            
367            
368            
369            
370             =head2 Close()
371            
372             Discard the current document no-questions-asked (i.e. even if it's not
373             saved).
374            
375             Note that this object is in an unusable state until a new document is
376             created or opened.
377            
378             =cut
379             sub Close {
380             my $self = shift;
381            
382             $self->MarkDocumentAsSaved();
383            
384             $self->oSelection(undef);
385             $self->oDocument->Close({ SaveChanges => $self->rhConst->{wdDoNotSaveChanges} });
386             $self->oDocument(undef);
387            
388             return(1);
389             }
390            
391            
392            
393            
394             =head1 METHODS - ADDING TEXT
395            
396             =head2 Write($text)
397            
398             Append $text to the document (using the current style etc).
399            
400             =cut
401             sub Write {
402             my $self = shift;
403             my ($text) = @_;
404            
405             $self->oSelection->TypeText($text);
406             $self->hasWrittenText(1);
407            
408             return(1);
409             }
410            
411            
412            
413            
414            
415             =head2 WriteParagraph($text, [heading => $level], [style => $name])
416            
417             Append $text as a new paragraph of heading $level or style $name. The
418             style overrides heading. The style should be a paragraph style.
419            
420             The default style is "Normal".
421            
422             =cut
423             sub WriteParagraph {
424             my $self = shift;
425             my ($text, %hOpt) = @_;
426            
427             if($self->hasWrittenParagraph) {
428             $self->NewParagraph(%hOpt);
429             } else {
430             $self->SetStyle( $self->StyleSpec(%hOpt) );
431             }
432            
433             $self->hasWrittenParagraph(1);
434             $self->Write($text);
435            
436             return(1);
437             }
438            
439            
440            
441            
442            
443             =head2 NewParagraph([heading => $level], [style => $name])
444            
445             Start a new paragraph of heading $level or with style $name. The style
446             overrides heading. The style should be a paragraph style.
447            
448             The default style is "Normal".
449            
450             =cut
451             sub NewParagraph {
452             my $self = shift;
453             my (%hOpt) = @_;
454            
455             $self->hasWrittenText and $self->oSelection->TypeParagraph();
456            
457             $self->hasWrittenText(1);
458             $self->hasWrittenParagraph(1);
459            
460             $self->SetStyle( $self->StyleSpec(%hOpt) );
461            
462             return(1);
463             }
464            
465            
466            
467            
468            
469             =head2 SetStyle([$style = "Normal"])
470            
471             Set the style to $style.
472            
473             If $style is a paragraph style, it will change the style of the
474             current paragraph.
475            
476             If $style is a character style, it will turn on that style. It will be
477             in effect until a new style is set somehow, or until it's cleared with
478             ClearCharacterFormatting().
479            
480             =cut
481             sub SetStyle {
482             my $self = shift;
483             my ($style) = @_;
484             $style ||= "Normal";
485            
486             return(1) if($style eq $self->styleOld); #Workaround for bug in Word 2000/2002: http://support.microsoft.com/kb/292174
487             $self->styleOld($style);
488            
489             local $SIG{__WARN__} = sub { die(@_) };
490             eval { $self->oSelection->{Style} = $style; };
491             if($@) {
492             my $err = $@;
493             if($err =~ /OLE exception from "Microsoft Word":\n\n(.+?)\nWin32::OLE/si) {
494             die("Could not set style ($style), it may not be defined in the document: $1\n");
495             }
496             die($err);
497             }
498            
499             return(1);
500             }
501            
502            
503            
504            
505            
506            
507             =head2 ClearCharacterFormatting()
508            
509             Clear the characther formatting/set it to default.
510            
511             The paragraph can have a style, and individual characters a separate
512             formatting style.
513            
514             =cut
515             sub ClearCharacterFormatting {
516             my $self = shift;
517            
518             $self->SetStyle("Default Paragraph Font"); ##Change for Word 2002 to "Clear Formatting", or does it work?
519            
520             return(1);
521             }
522            
523            
524            
525            
526            
527            
528             =head2 StyleSpec([heading => $level], [style => $name])
529            
530             Return the final style, given a specification of heading $level or
531             style $name. The style overrides heading.
532            
533             The default style is "Normal".
534            
535             =cut
536             sub StyleSpec {
537             my $self = shift;
538             my (%hOpt) = @_;
539             my $heading = $hOpt{heading};
540             my $style = $hOpt{style};
541            
542             $heading && !$style and return( "Heading $heading" );
543             return($style || "Normal");
544             }
545            
546            
547            
548            
549            
550             =head2 ToggleBold()
551            
552             Toggle the current Bold charachter setting
553            
554             =cut
555             sub ToggleBold {
556             my $self = shift;
557            
558             $self->oSelection->Font->{Bold} = $rhConst->{wdToggle};
559            
560             return($self->oSelection->Font->{Bold} ? 1 : 0);
561             }
562            
563            
564            
565            
566            
567             =head2 SetBold($enable)
568            
569             Set the Bold status to 1 or 0.
570            
571             Return the new Bold state, or throw OLE exception.
572            
573             =cut
574             sub SetBold {
575             my $self = shift;
576             my ($enable) = @_;
577             $enable = $enable ? 1 : 0;
578            
579             $self->oSelection->Font->{Bold} = $enable;
580            
581             return($self->oSelection->Font->{Bold} ? 1 : 0);
582             }
583            
584            
585            
586            
587            
588             =head2 ToggleItalic()
589            
590             Toggle the current Italic charachter setting
591            
592             =cut
593             sub ToggleItalic {
594             my $self = shift;
595            
596             $self->oSelection->Font->{Italic} = $rhConst->{wdToggle};
597            
598             return($self->oSelection->Font->{Italic} ? 1 : 0);
599             }
600            
601            
602            
603            
604            
605             =head2 SetItalic($enable)
606            
607             Set the Italic status to 1 or 0.
608            
609             Return the new Italic state, or throw OLE exception.
610            
611             =cut
612             sub SetItalic {
613             my $self = shift;
614             my ($enable) = @_;
615             $enable = $enable ? 1 : 0;
616            
617             $self->oSelection->Font->{Italic} = $enable;
618            
619             return($self->oSelection->Font->{Italic} ? 1 : 0);
620             }
621            
622            
623            
624            
625            
626             =head1 METHODS - BULLET POINT LISTS
627            
628             =head2 ListBegin()
629            
630             Begin a new bullet point list.
631            
632             Can be nested to create sub-lists.
633            
634             Use ListItem() to create new bullet points before adding text to the
635             list.
636            
637             =cut
638             sub ListBegin {
639             my $self = shift;
640            
641             $self->oSelection->TypeParagraph();
642             if( ! $self->levelIndent) { #Not yet started a list at all
643             $self->oSelection->Range->ListFormat->ApplyBulletDefault();
644             } else {
645             $self->oSelection->Range->ListFormat->ListIndent();
646             }
647            
648             $self->levelIndent( $self->levelIndent + 1);
649             $self->hasWrittenInIndent(0);
650            
651             return(1);
652             }
653            
654            
655            
656            
657            
658             =head2 ListItem()
659            
660             Start a new bullet point in the list.
661            
662             The first text you Write() after this becomes the new bullet text.
663            
664             You should not WriteParagraph() within a list item. New paragraphs are
665             signals to Word to advance to the next list item, so that will confuse
666             Win32::Word::Writer and/or Word.
667            
668             =cut
669             sub ListItem {
670             my $self = shift;
671            
672             if($self->hasWrittenInIndent) {
673             $self->oSelection->TypeParagraph();
674             }
675            
676             $self->hasWrittenInIndent(1);
677            
678             return(1);
679             }
680            
681            
682            
683            
684            
685            
686             =head2 ListEnd()
687            
688             End an existing bullet point list.
689            
690             If it's the outermost list, go back to normal text.
691            
692             =cut
693             sub ListEnd {
694             my $self = shift;
695            
696             $self->oSelection->TypeParagraph();
697            
698             if($self->levelIndent <= 1) { #Is the first level
699             $self->oSelection->Range->ListFormat->RemoveNumbers();
700             } elsif($self->levelIndent <= 2) { #Is the second level. This is just weird and I don't like to not understand why it works, but it does...
701             $self->oSelection->Range->ListFormat->RemoveNumbers();
702             $self->oSelection->Range->ListFormat->ApplyBulletDefault();
703             } else {
704             $self->oSelection->Range->ListFormat->ListOutdent();
705             }
706            
707             $self->levelIndent( $self->levelIndent - 1);
708             $self->hasWrittenInIndent(0);
709            
710             return(1);
711             }
712            
713            
714            
715            
716            
717             =head1 METHODS - TABLES
718            
719             =head2 TableBegin()
720            
721             Begin a new table.
722            
723             The table model resembles a HTML table with rows and columns, but you don't
724             have to close columns or rows. Simply start a new one.
725            
726             A row and col must be created with TableRowBegin() and
727             TableColumnBegin() before any text is added.
728            
729             Tables can not be nested.
730            
731             Note that tables are rather fragile so don't expect them to work with
732             very complex layouts, or very wide columns. Prepare for exceptions to
733             be thrown.
734            
735             =cut
736             sub TableBegin {
737             my $self = shift;
738            
739             $self->oTable and return(0);
740            
741             my $oTable = Win32::Word::Writer::Table->new(oWriter => $self) or die("Could not create Table object\n");
742             $self->oTable($oTable);
743             $self->oTable->TableBegin();
744             # $self->oTable(undef);
745            
746             return(1);
747             }
748            
749            
750            
751            
752            
753             =head2 TableRowBegin()
754            
755             Begin a new row in the current table.
756            
757             Add a column also before adding text to the table.
758            
759             =cut
760             sub TableRowBegin {
761             my $self = shift;
762            
763             $self->oTable or return(0);
764             $self->oTable->RowBegin();
765            
766             return(1);
767             }
768            
769            
770            
771            
772            
773             =head2 TableColumnBegin()
774            
775             Begin a column in the current table in the current row.
776            
777             Any new text/paragraph added to the document will end up in this table
778             cell until a new row or column is created, or the table is ended.
779            
780             =cut
781             sub TableColumnBegin {
782             my $self = shift;
783            
784             $self->oTable or return(0);
785             $self->oTable->ColumnBegin();
786            
787             return(1);
788             }
789            
790            
791            
792            
793            
794             =head2 TableEnd()
795            
796             Begin a column in the current table in the current row.
797            
798             Any new text/paragraph added to the document will end up in this table
799             cell until a new row or column is created, or the table is ended.
800            
801             =cut
802             sub TableEnd {
803             my $self = shift;
804            
805             $self->oTable or return(0);
806            
807             $self->oTable->TableEnd();
808             $self->oTable(undef);
809            
810             $self->styleOld("Normal"); #We jump to the end of the document, so the style is currently Normal
811            
812             return(1);
813             }
814            
815            
816            
817            
818            
819             =head1 METHODS - MOVEMENT AND SELECTION
820            
821             =head2 MoveToEnd()
822            
823             Set the insertion point at the end of the document.
824            
825             =cut
826             sub MoveToEnd {
827             my $self = shift;
828            
829             $self->oSelection->EndKey({ Unit => $self->rhConst->{wdStory}});
830            
831             return(1);
832             }
833            
834            
835            
836            
837            
838             =head2 SelectAll()
839            
840             Make the selection the entire document.
841            
842             Return 1 on success, else die.
843            
844             =cut
845             sub SelectAll {
846             my $self = shift;
847            
848             $self->oSelection->WholeStory();
849            
850             return(1);
851             }
852            
853            
854            
855            
856            
857             =head1 METHODS - FIELDS AND TABLES
858            
859             =head2 FieldsUpdate()
860            
861             Update the fields in the entire document. Retain the current
862             cursor location.
863            
864             But note this doesn't always work with Table of Contents
865             tables.
866            
867             Return 1 on success, else die.
868            
869             =cut
870             sub FieldsUpdate {
871             my $self = shift;
872            
873             $self->oDocument->Fields->Update() and croak("Could not update all fields");
874            
875             # my $nameBookmark = "wordwriter" . int(rand(10000));
876             # $self->BookmarkAdd($nameBookmark);
877             # $self->SelectAll();
878            
879             # $self->oSelection->Fields->Update();
880            
881             # $self->BookmarkGoto($nameBookmark);
882             # $self->BookmarkDelete($nameBookmark);
883            
884             return(1);
885             }
886            
887            
888            
889            
890            
891             =head2 ToCUpdate()
892            
893             Update both entries and page numebers of all the Tables of
894             Contents in the entire document. Retain the current cursor
895             location.
896            
897             Return 1 on success, else die.
898            
899             =cut
900             sub ToCUpdate {
901             my $self = shift;
902            
903             my $count = 0;
904             for my $oToC ($self->oDocument->TablesOfContents->in()) {
905             $count++;
906             $oToC->Update() and croak("Could not update entries of Table of Contents number ($count)");
907             $oToC->UpdatePageNumbers() and croak("Could not update page numbers of Table of Contents number ($count)");
908             }
909            
910             return(1);
911             }
912            
913            
914            
915            
916            
917             =head1 METHODS - IMAGES
918            
919             =head2 InsertPicture($file, $embed = 0)
920            
921             Insert the picture $file at the current cursor location. $file must be
922             one Word supports.
923            
924             If $embed is 1, the picture $file itself will be embedded inside the
925             Word document. If $embed is 0, the picture is isn't embedded in the
926             document, but linked to it.
927            
928             Return 1 on success, else die.
929            
930             =cut
931             sub InsertPicture {
932             my $self = shift;
933             my ($file, $embed) = @_;
934             $embed ||= 0;
935            
936             $file = File::Spec->rel2abs($file);
937             -f $file or croak("Could not open file: File ($file) does not exist");
938             -r $file or croak("Could not open file: Can't read File ($file)");
939            
940             # LinkToFile, SaveWithDocument
941             my @aLinkSave = qw/ True False /;
942             $embed and @aLinkSave = qw/ False True /;
943             $self->oSelection->InlineShapes->AddPicture($file, @aLinkSave) or croak("Could not insert image object");
944            
945             return(1);
946             }
947            
948            
949            
950            
951            
952             =head1 METHODS - BOOKMARKS
953            
954             =head2 BookmarkAdd($name)
955            
956             Add a new bookmark called $name at the current cursor
957             location.
958            
959             Return 1 on success, else die.
960            
961             =cut
962             sub BookmarkAdd {
963             my $self = shift;
964             my ($name) = @_;
965            
966             $self->oDocument->Bookmarks->Add( { Name => $name } );
967            
968             return(1);
969             }
970            
971            
972            
973            
974            
975             =head2 BookmarkGoto($name)
976            
977             Go to bookmark called $name. The bookmark should exist.
978            
979             Return 1 on success, else die.
980            
981             =cut
982             sub BookmarkGoto {
983             my $self = shift;
984             my ($name) = @_;
985            
986             $self->oSelection->GoTo( { What => $self->rhConst->{wdGoToBookmark}, Name => $name } );
987            
988             return(1);
989             }
990            
991            
992            
993            
994            
995             =head2 BookmarkDelete($name)
996            
997             Delete bookmark called $name. The bookmark should exist.
998            
999             Return 1 on success, else die.
1000            
1001             =cut
1002             sub BookmarkDelete {
1003             my $self = shift;
1004             my ($name) = @_;
1005            
1006             $self->oDocument->Bookmarks($name)->Delete();
1007            
1008             return(1);
1009             }
1010            
1011            
1012            
1013            
1014            
1015             =head1 METHODS - UTILITY
1016            
1017             =head2 MarkDocumentAsSaved()
1018            
1019             Mark the Word document as "saved". This is in effect until
1020             the document is changed again.
1021            
1022             Being saved e.g. means it can be abandoned without
1023             questions.
1024            
1025             Return 1 on success, else die.
1026            
1027             =cut
1028             sub MarkDocumentAsSaved {
1029             my $self = shift;
1030            
1031             $self->oDocument->{Saved} = 1;
1032            
1033             return(1);
1034             }
1035            
1036            
1037            
1038            
1039            
1040             =head2 GetFileTemp()
1041            
1042             Return a temporary file name in fileTemp().
1043            
1044             =cut
1045             sub GetFileTemp {
1046             my $self = shift;
1047            
1048             $self->fileTemp or $self->fileTemp( File::Temp::tmpnam() . "-wordwriter.doc" ); #Can't use the proper auto-unlink because that only works with the file handles
1049            
1050             return($self->fileTemp);
1051             }
1052            
1053            
1054            
1055            
1056            
1057             =head2 DESTROY
1058            
1059             Release objects including the OLE Word object.
1060            
1061             =cut
1062             sub DESTROY {
1063             my $self = shift;
1064             $self->oTable(undef);
1065            
1066             $self->oWord->{DisplayAlerts} = $rhConst->{wdAlertsNone};
1067             $self->MarkDocumentAsSaved(); ##workaround: wdAlertsNone doesn't work in Word2000 so we insist that the document is already saved to avoid the dialog box
1068            
1069             $self->oWord->Quit();
1070             $self->oWord(undef); #This destroys the OLE object
1071            
1072             #Save after quitting to keep Word from locking the file
1073             if($self->fileTemp and -e $self->fileTemp) {
1074             unlink($self->fileTemp) or ($^W and warn("Could not delete temp file (" . $self->fileTemp . "): $!\n"));
1075             }
1076             }
1077            
1078            
1079            
1080            
1081            
1082             1;
1083            
1084            
1085            
1086            
1087            
1088             __END__