Page 1 of 2

COM and MS Word Margins?

Posted: Tue Nov 09, 2004 3:15 am
by Mr Tech
Is it possible, after generating a MS Word file using COM, to set the margins of the MS Word document? If so how?

Thanks

Ben

Posted: Tue Nov 09, 2004 4:08 am
by phpScott
didn't you ask about ms word and com awhile ago at
viewtopic.php?t=27003&highlight=word

check there agian for a list of resources.

Posted: Tue Nov 09, 2004 4:49 pm
by Mr Tech
Yes, but none of those really links helped... I posted a new topic so it would be easier to find...

Anyway, I was searching and found some code:

Code: Select all

<?php
$content = "Insert Sample Text Here\n\nThis starts a new paragraph line.";
$word= new COM("word.application") or die("Unable to create Word document"); 
print "Loaded Word, version {$word->Version}\n"; 
$word->Visible = 0; 
$word->Documents->Add(); 
$word->Selection->PageSetup->LeftMargin = '3"';
$word->Selection->PageSetup->RightMargin = '4"';
$word->Selection->Font->Name = 'Helvetica';
$word->Selection->Font->Size = 8;
$word->Selection->Font->ColorIndex= 13; //wdDarkRed = 13
$word->Selection->TypeText("$content"); 
$word->Documents[1]->SaveAs("some_tst.doc"); 
$word->quit(); 
echo "done";
?>
I tried using the leftmargin and right margin but I just got the error:

Warning: Unable to lookup PageSetup: Unknown name. in c:\program files\easyphp\www\created\invoices\generate\generate.php on line 103

Any ideas on what's wrong? Is there another word for PageSetup?

Thanks

Ben

Posted: Tue Nov 09, 2004 5:32 pm
by Weirdan
what is the version of your word?

Posted: Tue Nov 09, 2004 5:36 pm
by Mr Tech
2000.

Posted: Tue Nov 09, 2004 6:05 pm
by Weirdan
hmm... try to replace Selection with ActiveDocument or Documents[1]

Posted: Tue Nov 09, 2004 6:17 pm
by Mr Tech
will do. Thanks

Posted: Tue Nov 09, 2004 9:12 pm
by Mr Tech
Nope didnt work... I am using a class to do this script... maybe if you look at it tiw ill help.

generate.php

Code: Select all

<?php
include("msword.inc.php");
   $rawpath = getcwd();
   $root = strtr($rawpath, "", "/");
   $root = $root."/";
   $input = $root."template.htm";
   $output = $root."template.doc";

   $Word = new MSWord;
   $Word->Open($input);
   $Word->SetMargins("1","1","1.6");
   $Word->SaveAs($output);
   $Word->Quit();
   unlink($finalinput);
?>
msword.inc.php

Code: Select all

<?php
   // msword.inc.php
   
   // NOTE: Using COM with windows NT/2000/XP with apache as a service
   // - Run dcomcnfg.exe
   // - Find word application and click properties
   // - Click the Security tab
   // - Use Custom Access Permissions
   //      - Add the user who runs the web server service
   // - Use Custom Launch permissions
   //      - Add the user who runs the web server service
   
   $wdFormatDocument = 0;
   $wdFormatTemplate = 1;
   $wdFormatText = 2;
   $wdFormatTextLineBreaks = 3;
   $wdFormatDOSText = 4;
   $wdFormatDOSTextLineBreaks = 5;
   $wdFormatRTF = 6;
   $wdFormatUnicodeText = 7;
   $wdFormatHTML=8;

   class MSWord
   {
       // Vars:
       var $handle;
       
       // Create COM instance to word
       function MSWord($Visible = false)
       {
           $this->handle = new COM("word.application") or die("Unable to instanciate Word");
           $this->handle->Visible = $Visible;
       }
       
       // Open existing document
       function Open($File)
       {
           $this->handle->Documents->Open($File);
       }
       
       // Create new document
       function NewDocument()
       {
           $this->handle->Documents->Add();
       }
       
       // Write text to active document
       function WriteText( $Text )
       {
           $this->handle->Selection->Typetext( $Text );
       }

       // Set page margins
       function SetMargins($top,$bottom,$left)
       {
	    $word->handle->ActiveDocument->PageSetup->LeftMargin = '$left cm';
	    $word->handle->ActiveDocument->PageSetup->TopMargin = '$top cm';
	    $word->handle->ActiveDocument->PageSetup->BottomMargin = '$bottom cm';
       }
       
       // Number of documents open
       function DocumentCount()
       {
           return $this->handle->Documents->Count;
       }
       
       // Save document as another file and/or format
       function SaveAs($File, $Format = 0 )
       {
           $this->handle->ActiveDocument->SaveAs($File, $Format);
       }
       
       // Save active document
       function Save()
       {
           $this->handle->ActiveDocument->Save();
       }
       
       // close active document.
       function Close()
       {
           $this->handle->ActiveDocument->Close();
       }
       
       // Get word version
       function GetVersion()
       {
           return $this->handle->Version;
       }
       
       // get handle to word
       function GetHandle()
       {
           return $this->handle;
       }
   
       // Clean up instance with word
       function Quit()
       {
           if( $this->handle )
           {
               // close word
               $this->handle->Quit();
   
               // free the object
               $this->handle->Release();
               $this->handle = null;
           }
       }
   };

?>
Hopefully that will help
?>

Posted: Wed Nov 10, 2004 1:06 pm
by Weirdan
$word->handle should be $this->handle, ='$var cm' should be ="$var cm" (type of quotes does matter). Do other methods work (such as creating, opening files, writing to the document)?

BTW, when MSWord 2003 records a macro, it uses InchesToPoints() function to convert the measures to the points. I'm not sure if it relevant here, but you may try to assign pure numbers instead of strings.

Posted: Wed Nov 10, 2004 3:32 pm
by Mr Tech
Arghhh I cant belive I missed the $word->!!!! Thanks I'll give it a go.

Posted: Wed Nov 10, 2004 9:41 pm
by Mr Tech
Wooty it worked! This is what i used:

$this->handle->Documents[1]->PageSetup->LeftMargin = "$left cm";

The ActiveDoument, Documents and Selection all gave me erros. But putting the [1] after Documents worked great!

Thanks SO MUCH Weirdan! I didn't think I'd ever work it out :)

Thanks again!

Posted: Wed Nov 10, 2004 9:48 pm
by Mr Tech
LOL while this topic is here I;ve just got a quick question.

When I generate the Word document, it is generated from a HTML document. I have done this because I needed to use str_replace() to repalce some [word] fields.

I couldn't seem to read a word document with COM() properly so I wasn't able to use str_replace(). I couldn't generate the word doc from another word doc because it wasn't able to read the contents of the word document using this function:

Code: Select all

function fileread($filename)
&#123;
 $fd = @fopen($filename, 'r');
 $filecontents = @fread ($fd, filesize($filename));
 @fclose ($fd);
 return $filecontents;
&#125;
Maybe you'll know how to generate a word doc from another word doc and still be able to use str_replace()?

That may fix my next question below but I'll ask anyway:

In the HTML document I have pictures included. When I generate the Word document, the images go into it fine except when i save it onto another computer. The pictures then don't work. The only way I can get them to work is by linking to the images from my website... But when the computer isn't connected to the computer, they don't show up anymore plus when it is connected they need to load...

Any ideas on how I can make it read them without linking to the website.

Posted: Thu Nov 11, 2004 1:35 pm
by Weirdan
Mr Tech wrote: Maybe you'll know how to generate a word doc from another word doc and still be able to use str_replace()?
Not actually str_replace, but instead Word's own find&replace function is used in the following example (VBA script, I seldom use PHP on windows boxes):

Code: Select all

' this snippet replaces each 'sdf' with six exclamation signs
  Dim w As Word.Application
  Set w = CreateObject("word.application")
  w.Visible = True
  w.Documents.Open ("templ.doc")
  w.ActiveDocument.Select
  w.Selection.Find.ClearFormatting
  w.Selection.Find.Replacement.ClearFormatting
  w.Selection.Find.Text = "sdf"
  w.Selection.Find.Replacement.Text = "!!!!!!"
  w.Selection.Find.Forward = True
  w.Selection.Find.Wrap = wdFindContinue
  w.Selection.Find.Format = False
  w.Selection.Find.MatchCase = False
  w.Selection.Find.MatchWholeWord = False
  w.Selection.Find.MatchWildcards = False
  w.Selection.Find.MatchSoundsLike = False
  w.Selection.Find.MatchAllWordForms = False
  w.Selection.Find.Execute Replace:=wdReplaceAll
Converting it to PHP is pretty straightforward, you will need to find out numerical values of wdReplaceAll and wdFindContinue constants though.

Posted: Thu Nov 11, 2004 4:38 pm
by Mr Tech
Would this help (Go to post by Justin):

http://www.progresstalk.com/printthread.php?t=25614

I also found this:

http://www.experts-exchange.com/Web/Web ... 06226.html

Tested it but the page just kept going and it wouldn't load...

Posted: Fri Nov 12, 2004 6:57 am
by Weirdan
Mr Tech wrote:Would this help (Go to post by Justin):
http://www.progresstalk.com/printthread.php?t=25614
Certainly. Now you have all you need to use .docs as a template.