I'm Michael Suodenjoki - a software engineer living in Kgs. Lyngby, north of Copenhagen, Denmark. This is my personal site containing my blog, photos, articles and main interests.
I'm Michael Suodenjoki - a software engineer living in Kgs. Lyngby, north of Copenhagen, Denmark. This is my personal site containing my blog, photos, articles and main interests.
Updated 2011.01.23 17:22 +0100 |
Ikke tilgængelig på Dansk
Version 2.1 February 2008
This article describe how you can convert Microsoft Word documents to Adobe PDF documents using a command line VBScript and Automation.
This article (v2.0) was updated July 7, 2007 to support Word 2007. It requires Word 2007 or its requires Word 2003 and Adobe Acrobat (Distiller).
I have for some time wanted a command line tool for converting some Word documents into PDF documents during an automatic build process of a software product. As I knew that Word can be "automated" via Automation it was a straightforward task to create a small VB script program that can be executed on the command line.
A very good thing with Word 2007 is that you can download and install a Save As PDF add-in allowing you to save directly to PDF (or XPS for that matter). This means that the Adobe Distiller is no longer required. The old article code - originally written for Word 2003 - is however maintained in appendix B.
Note that Word 2007 can be used to convert Word documents created in Word 2003 or older without touching the original Word document.
Build managers are faced with the challenge of making their software builds as easily as possible. Software is not only the compilation of some software code, but does also includes the "compilation" of documentation (printable to paper as well as online), which should be distributed along with the install programs etc.
In our case the Word documents was generated from a single source Word document, which represents both the online help and the printable user documentation. We used a tool called WebWorks for Word. However we would not like to distribute the Word documents but preferred PDF documents. So an automatic conversion from Word to PDF was of high interest, preferably built directly into the build commands issued by an build manager. In this way we don't have to manually convert the Word documents to PDF when the Word documents changes (which they always does). Instead the build manager simply activates the normal commands and the build process takes care of the conversion automatically. You can even, if you use something like MAKE or similar, built into the process that the conversion only should take place if the Word document has changed (e.g. using file dates).
By god I do know why WebWorks haven't automated their product so all this could have been done more nicely. But maybe they want their customers to spend a lot of money buying their server side tools, which can something similar to what I do here.
When do software companies learn that people do not like server software?
Windows offer a pretty good command line scripting language via Visual Basic Scripting. The full code of the VB script can be found in the appendix A or B below depending on your requirements. You should create a text file and save it as e.g. doc2pdf.vbs.
When you want to run the code you can do so with the following command line:
C:> cscript /nologo <path to doc2pdf.vbs> /nologo <path to Word document>
This tells the system to use the Windows cscript VB script command line processor with the doc2pdf.vbs script, the /nologo option and the word document to convert to PDF. The output PDF file will per default be named the same as the original Word document only with the difference of having the pdf file extension. The script can optionally take a parameter specifying another file name for the output file - using option like /o:<output file>.
Requirements for the VB script code in this appendix:
'************************************************ ' ' DOC2PDF.VBS Microsoft Scripting Host Script (Requires Version 5.6 or newer) ' -------------------------------------------------------------------------------- ' ' Author: Michael Suodenjoki ' Created: 2007.07.07 ' ' This script can create a PDF file from a Word document provided you're using ' Word 2007 and have the 'Office Add-in: Save As PDF' installed. ' ' Constants Const WdDoNotSaveChanges = 0 ' see WdSaveFormat enumeration constants: ' http://msdn2.microsoft.com/en-us/library/bb238158.aspx Const wdFormatPDF = 17 ' PDF format. Const wdFormatXPS = 18 ' XPS format. ' Global variables Dim arguments Set arguments = WScript.Arguments ' *********************************************** ' ECHOLOGO ' ' Outputs the logo information. ' Function EchoLogo() If Not (arguments.Named.Exists("nologo") Or arguments.Named.Exists("n")) Then WScript.Echo "doc2pdf Version 2.0, Michael Suodenjoki 2007" WScript.Echo "==================================================" WScript.Echo "" End If End Function ' *********************************************** ' ECHOUSAGE ' ' Outputs the usage information. ' Function EchoUsage() If arguments.Count=0 Or arguments.Named.Exists("help") Or _ arguments.Named.Exists("h") _ Then WScript.Echo "Generates a PDF from a Word document file using Word 2007." WScript.Echo "" WScript.Echo "Usage: doc2pdf.vbs <options> <doc-file> [/o:<pdf-file>]" WScript.Echo "" WScript.Echo "Available Options:" WScript.Echo "" WScript.Echo " /nologo - Specifies that the logo shouldn't be displayed" WScript.Echo " /help - Specifies that this usage/help information " + _ "should be displayed." WScript.Echo " /debug - Specifies that debug output should be displayed." WScript.Echo "" WScript.Echo "Parameters:" WScript.Echo "" WScript.Echo " /o:<pdf-file> Optionally specification of output file (PDF)." WScript.Echo "" End If End Function ' *********************************************** ' CHECKARGS ' ' Makes some preliminary checks of the arguments. ' Quits the application is any problem is found. ' Function CheckArgs() ' Check that <doc-file> is specified If arguments.Unnamed.Count <> 1 Then WScript.Echo "Error: Obligatory <doc-file> parameter missing!" WScript.Quit 1 End If bShowDebug = arguments.Named.Exists("debug") Or arguments.Named.Exists("d") End Function ' *********************************************** ' DOC2PDF ' ' Converts a Word document to PDF using Word 2007. ' ' Input: ' sDocFile - Full path to Word document. ' sPDFFile - Optional full path to output file. ' ' If not specified the output PDF file ' will be the same as the sDocFile except ' file extension will be .pdf. ' Function DOC2PDF( sDocFile, sPDFFile ) Dim fso ' As FileSystemObject Dim wdo ' As Word.Application Dim wdoc ' As Word.Document Dim wdocs ' As Word.Documents Dim sPrevPrinter ' As String Set fso = CreateObject("Scripting.FileSystemObject") Set wdo = CreateObject("Word.Application") Set wdocs = wdo.Documents sDocFile = fso.GetAbsolutePathName(sDocFile) ' Debug outputs... If bShowDebug Then WScript.Echo "Doc file = '" + sDocFile + "'" WScript.Echo "PDF file = '" + sPDFFile + "'" End If sFolder = fso.GetParentFolderName(sDocFile) If Len(sPDFFile)=0 Then sPDFFile = fso.GetBaseName(sDocFile) + ".pdf" End If If Len(fso.GetParentFolderName(sPDFFile))=0 Then sPDFFile = sFolder + "\" + sPDFFile End If ' Enable this line if you want to disable autoexecute macros ' wdo.WordBasic.DisableAutoMacros ' Open the Word document Set wdoc = wdocs.Open(sDocFile) ' Let Word document save as PDF ' - for documentation of SaveAs() method, ' see http://msdn2.microsoft.com/en-us/library/bb221597.aspx wdoc.SaveAs sPDFFile, wdFormatPDF wdoc.Close WdDoNotSaveChanges wdo.Quit WdDoNotSaveChanges Set wdo = Nothing Set fso = Nothing End Function ' *** MAIN ************************************** Call EchoLogo() Call EchoUsage() Call CheckArgs() Call DOC2PDF( arguments.Unnamed.Item(0), arguments.Named.Item("o") ) Set arguments = Nothing
Requirements for the VB script code in this appendix:
'************************************************ ' ' DOC2PDF.VBS Microsoft Scripting Host Script (Requires Version 5.6 or newer) ' -------------------------------------------------------------------------------- ' ' Author: Michael Suodenjoki ' Created: 2003.09.19 ' ' This script can create a PDF file from a Word document provided that you ' have Adobe Acrobat Distiller installed. ' ' Constants Const WdPrintAllDocument = 0 Const WdDoNotSaveChanges = 0 ' Global variables Dim arguments Set arguments = WScript.Arguments ' *********************************************** ' ECHOLOGO ' ' Outputs the logo information. ' Function EchoLogo() If Not (arguments.Named.Exists("nologo") Or arguments.Named.Exists("n")) Then WScript.Echo "doc2pdf Version 1.0, Michael Suodenjoki 2003" WScript.Echo "==================================================" WScript.Echo "" End If End Function ' *********************************************** ' ECHOUSAGE ' ' Outputs the usage information. ' Function EchoUsage() If arguments.Count=0 Or arguments.Named.Exists("help") or _ arguments.Named.Exists("h") _ Then WScript.Echo "Generates a PDF file from a Word document using Adobe Distiller." WScript.Echo "" WScript.Echo "Usage: doc2pdf.vbs <options> <doc-file> [/o:<pdf-file>]" WScript.Echo "" WScript.Echo "Available Options:" WScript.Echo "" WScript.Echo " /nologo - Specifies that the logo shouldn't be displayed" WScript.Echo " /help - Specifies that this usage/help information should " + _ "be displayed." WScript.Echo " /debug - Specifies that debug output should be displayed." WScript.Echo "" WScript.Echo "Parameters:" WScript.Echo "" WScript.Echo " /o:<pdf-file> Optionally specification of output file (PDF)." WScript.Echo "" End If End Function ' *********************************************** ' CHECKARGS ' ' Makes some preliminary checks of the arguments. ' Quits the application is any problem is found. ' Function CheckArgs() ' Check that <doc-file> is specified If arguments.Unnamed.Count <> 1 Then WScript.Echo "Error: Obligatory <doc-file> parameter missing!" WScript.Quit 1 End If bShowDebug = arguments.Named.Exists("debug") Or arguments.Named.Exists("d") End Function ' *********************************************** ' DOC2PDF ' ' Converts a Word document to PDF using Adobe ' Distiller. ' ' Input: ' sDocFile - Full path to Word document. ' sPDFFile - Optional full path to output file. ' ' If not specified the output PDF file ' will be the same as the sDocFile except ' file extension will be .pdf. ' Function DOC2PDF( sDocFile, sPDFFile ) Dim fso ' As FileSystemObject Dim wdo ' As Word.Application Dim wdoc ' As Word.Document Dim wdocs ' As Word.Documents Dim sPrevPrinter ' As String Dim oDistiller ' As PDFDistiller.PDFDistiller.1 Set oDistiller = CreateObject("PDFDistiller.PDFDistiller.1") If oDistiller Is Nothing Then WScript.Echo "Error: Cannot create PDF document. Adobe Acrobat " + "Distiller is not available! Quiting..." WScript.Quit 1 End If Set fso = CreateObject("Scripting.FileSystemObject") Set wdo = CreateObject("Word.Application") Set wdocs = wdo.Documents sTempFile = fso.GetSpecialFolder(TemporaryFolder) + "\" + fso.GetTempName() sDocFile = fso.GetAbsolutePathName(sDocFile) ' Debug outputs... If bShowDebug Then WScript.Echo "Doc file = '" + sDocFile + "'" WScript.Echo "Temporary file = '" + sTempFile + "'" WScript.Echo "PDF file = '" + sPDFFile + "'" End If sFolder = fso.GetParentFolderName(sDocFile) If Len(sPDFFile)=0 Then sPDFFile = fso.GetBaseName(sDocFile) + ".pdf" End If If Len(fso.GetParentFolderName(sPDFFile))=0 Then sPDFFile = sFolder + "\" + sPDFFile End If ' Remember current active printer sPrevPrinter = wdo.ActivePrinter 'wdo.ActivePrinter = "Acrobat PDFWriter" wdo.ActivePrinter = "Acrobat Distiller" ' Open the Word document Set wdoc = wdocs.Open(sDocFile) ' Print the Word document to the Acrobat Distiller - ' will generate a postscript (.ps) (temporary) file wdo.ActiveDocument.PrintOut False , , , sTempFile ' This outcommented part was used while trying to use "Acrobat PDFWriter" 'Do While wdo.BackgroundPrintingStatus > 0 ' 'Do nothing - just wait for printing to finish before closing Word 'Loop wdoc.Close WdDoNotSaveChanges wdo.ActivePrinter = sPrevPrinter wdo.Quit WdDoNotSaveChanges Set wdo = Nothing ' Debug output... 'If bShowDebug Then WScript.Echo " Distilling to '" + sPDFFile + "'" 'End If ' Distill the postscript file to PDF oDistiller.FileToPDF sTempFile, sPDFFile, "Print" Set oDistiller = Nothing ' Delete the temporary postscript file... fso.DeleteFile( sTempFile ) Set fso = Nothing End Function ' *** MAIN ************************************** Call EchoLogo() Call EchoUsage() Call CheckArgs() Call DOC2PDF( arguments.Unnamed.Item(0), arguments.Named.Item("o") ) Set arguments = Nothing
This work by
Michael Suodenjoki is licensed under a
Creative Commons Attribution 3.0 Unported License.
A: When I made the script I remember that I experimented with using the PDFWriter. As I recall it did work to some degree, but there were some preferences towards using the distiller that I cannot remember. If you look in the source code below you will notice that some of my experimenting code with using PDFWriter is still there - just commented out. You may try to enable those lines and see what happens (remember to comment out the distiller lines though).
A: Word Application Object documentation can be found at Microsoft's MSDN documentation site, e.g. at:
http://msdn.microsoft.com/ library/default.asp?url=/ library/en-us/dv_wrcore/html/ wrgrfapplicationobject.asp.
I think that the PDF Distiller object documentation can be found in Adobes Acrobat SDK documentation located at:
http://partners.adobe.com/ asn/tech/pdf/acrobatsdks.jsp
A: The code does not currently support wildcards, however it should be pretty straightforward to implement. Also I guess that it would be pretty easy to change the code to convert Excel files - simply using the Excel.Application Automation object instead.
A: I must admit I do not know whether the VB way of "creating" (starting) the Word application
loads add-ins.
However I'm pretty sure that autoexec macros are not executed.
If you want to control whether auto macros are executed you can do so using the WordBasic.DisableAutoMacros function