Page 1 of 1

Word Template - Fill In, Print and Preview Rate Topic: -----

#1 andrewsw  Icon User is offline

  • I'd like to return this printer
  • member icon

Reputation: 6322
  • View blog
  • Posts: 25,422
  • Joined: 12-December 12

Posted 22 January 2016 - 05:03 AM

This tutorial is a small project to fill-in values for a Word template, save it, then have options to print the document or preview it on the WinForm.

This is essentially an 'outline project' as I built it over a short period to demonstrate the possibilities. In particular, I wanted to describe how Word Bookmarks are used to locate, and fill in, information for a template, and to offer a reasonable way to preview the document directly on the form; that is, by saving the document as an html file.

There is a lot that could be added and improved with the application. Some examples:

  • Could check if Word is running rather than creating a new instance each time
  • Use a dialog to specify the save location
  • Check if the file already exists
  • Use a dialog so as to preview any document
  • Save the html to a temporary folder, and/or delete before exit
  • Lots more error checking/handling
  • Should use Path.Combine

In particular, I decided to make it a simple, once only, process, by disabling the buttons and (subsequently) the filename-textbox. Not doing this would have required a lot more of the error checking that I've just mentioned.

Added: Actually, just adding a "New" Button could make the application effective more than once. This button would just need to reset the controls to their initial state.

In a real application you'd want a Holiday class and others, and perhaps a helper class to assist with the Word interactivity.



Create a Word document. Where variable information is required, position the cursor there and choose the Insert tab, Bookmark (or press Ctrl-Shift-F5). Name the Bookmarks using the format 'bkSomething' (no spaces).

Attached Image

Instead of a cursor position we could type and select some text before defining the Bookmark. This is useful to provide some default text that we would optionally replace.

A Bookmark is a named location, or selection, within a Word Document or Template. You can use the GoTo dialog (Ctrl-G) to navigate between Bookmarks.

(The bookmark names I've chosen are seen in the code.)

Save the document as a template using the Save As dialog by selecting Word Template (.dotx) from the 'Save as type' list. Make a note of the file location and name.

Start a new WinForm application, I named mine WordTemplate. I named the form frmWordTemplate. (To do this, right-click the form in Solution Explorer and choose Rename, this will offer to update all references to the name.)

Attached Image

The form includes a TextBox, several Labels, two ComboBoxes, two DateTimePickers, a few Buttons and a WebBrowser control. The names of these controls can be determined from the code, although I've used consistent names like cboStaffMember, dtpFirstDate, btnPreview, etc..

My Control prefixes: lbl, cbo, dtp, txt, btn, wb (WebBrowser).

The Print and Preview Buttons start with Enabled = False.

From the Project menu choose Add Reference.. and find, and tick, the Microsoft Word 15.0 (or 14.0) Object Library.
Option Strict On

Imports Word = Microsoft.Office.Interop.Word  'Add Reference
'Microsoft Word 15.0 Object Library

Public Class frmWordTemplate
    Private wdApp As Word.Application
    Private wdDocs As Word.Documents
    Const sPath As String = "C:\Users\Andrew\Documents\"        'change this
    Private sFileName As String


[The full code is listed at the end of the tutorial.]

We need references to Word objects, such as Application, Documents, document. I didn't want to create these entirely from scratch for each procedure, but I also didn't want to keep Word running for the whole application session. I took the middle ground to just have the Application and Documents references at the class-level. In the Form's Closing event I ensure that these are released:
    Private Sub frmWordTemplate_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If wdDocs IsNot Nothing Then
            ReleaseObject(wdDocs)
        End If
        If wdApp IsNot Nothing Then
            ReleaseObject(wdApp)
        End If
    End Sub


The Word objects need to be released (correctly disposed of) in reverse order; that is, the Document is released before Documents, and Documents before Application. Here is the method:
    Private Sub ReleaseObject(ByVal obj As Object)
        'http://www.siddharthrout.com/2012/08/06/vb-net-two-dot-rule-when-working-with-office-applications-2/
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub


Having filled in the values for the template the main sequence is from the Create Button:
    Private Sub btnCreate_Click(sender As Object, e As EventArgs) Handles btnCreate.Click
        If cboStaffMember.SelectedIndex = -1 OrElse cboDestination.SelectedIndex = -1 Then
            MessageBox.Show("Select both a staff member and destination.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        If dtpFirstDate.Value.Date < dtpLastDate.Value.Date Then
            MessageBox.Show("First date must be before last date.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        If String.IsNullOrWhiteSpace(txtFileName.Text) Then
            MessageBox.Show("Provide a file name.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        sFileName = txtFileName.Text


This just checks that we have all the values we need before using Word.

Now we start Word, create a new document based on our template, and specify some Word references that we will need:
        wdApp = New Word.Application

        wdDocs = wdApp.Documents

        Dim wdDoc As Word.Document = wdDocs.Add(sPath & "Custom Office Templates\HOLIDAY FORM.dotx")
        Dim wdBooks As Word.Bookmarks = wdDoc.Bookmarks


Here is the significant code, set the Text of the Bookmarks we created earlier to the values from the form's controls:
        wdBooks("bkStaffMember").Range.Text = cboStaffMember.SelectedItem.ToString()
        wdBooks("bkFirstDate").Range.Text = dtpFirstDate.Value.ToLongDateString()
        wdBooks("bkLastDate").Range.Text = dtpLastDate.Value.ToLongDateString()
        wdBooks("bkDestination").Range.Text = cboDestination.SelectedItem.ToString()


Now we can save the document and tidy up. the Print and Preview buttons are then made available.
        wdDoc.SaveAs2(sPath & sFileName)

        ReleaseObject(wdBooks)
        wdDoc.Close(False)
        ReleaseObject(wdDoc)
        ReleaseObject(wdDocs)
        wdApp.Quit()

        txtFileName.Enabled = False
        btnPrint.Enabled = True
        btnPreview.Enabled = True
    End Sub


As mentioned, it is preferable to use Path.Combine rather than concatenating with & to create the file locations.

The Print Button simply opens the file and prints it to the default printer.
    Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
        wdApp = New Word.Application
        wdDocs = wdApp.Documents
        wdApp.Visible = True    'need to monitor process

        Dim wdDoc As Word.Document = wdDocs.Open(sPath & sFileName & ".docx")
        wdDoc.PrintOut()

        wdDoc.Close(False)
        ReleaseObject(wdDoc)
        ReleaseObject(wdDocs)
        wdApp.Quit()
    End Sub


The Preview Button (see the full code below) creates an html page from the document and loads it into the WebBrowser. Note that Word gives the file an '.htm' extension.

If we wanted to delete the html file then, rather than waiting until the application exits, we could use the Navigated event of the WebBrowser. I don't think this will cause any problems although I haven't investigated. Note that in addition to the htm file, Word creates a folder based on the filename.

There is some other useful Word information here:

How to automate Word from Visual Basic .NET to create a new document



The full code:
Option Strict On

Imports Word = Microsoft.Office.Interop.Word  'Add Reference
'Microsoft Word 15.0 Object Library

Public Class frmWordTemplate
    Private wdApp As Word.Application
    Private wdDocs As Word.Documents
    Const sPath As String = "C:\Users\Andrew\Documents\"
    Private sFileName As String

    Private Sub btnCreate_Click(sender As Object, e As EventArgs) Handles btnCreate.Click
        If cboStaffMember.SelectedIndex = -1 OrElse cboDestination.SelectedIndex = -1 Then
            MessageBox.Show("Select both a staff member and destination.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        If dtpFirstDate.Value.Date < dtpLastDate.Value.Date Then
            MessageBox.Show("First date must be before last date.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        If String.IsNullOrWhiteSpace(txtFileName.Text) Then
            MessageBox.Show("Provide a file name.", "Error", MessageBoxButtons.OK)
            Exit Sub
        End If
        sFileName = txtFileName.Text

        wdApp = New Word.Application

        wdDocs = wdApp.Documents

        Dim wdDoc As Word.Document = wdDocs.Add(sPath & "Custom Office Templates\HOLIDAY FORM.dotx")
        Dim wdBooks As Word.Bookmarks = wdDoc.Bookmarks

        wdBooks("bkStaffMember").Range.Text = cboStaffMember.SelectedItem.ToString()
        wdBooks("bkFirstDate").Range.Text = dtpFirstDate.Value.ToLongDateString()
        wdBooks("bkLastDate").Range.Text = dtpLastDate.Value.ToLongDateString()
        wdBooks("bkDestination").Range.Text = cboDestination.SelectedItem.ToString()

        wdDoc.SaveAs2(sPath & sFileName)

        ReleaseObject(wdBooks)
        wdDoc.Close(False)
        ReleaseObject(wdDoc)
        ReleaseObject(wdDocs)
        wdApp.Quit()

        txtFileName.Enabled = False
        btnPrint.Enabled = True
        btnPreview.Enabled = True
    End Sub

    Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
        wdApp = New Word.Application
        wdDocs = wdApp.Documents
        wdApp.Visible = True    'need to monitor process

        Dim wdDoc As Word.Document = wdDocs.Open(sPath & sFileName & ".docx")
        wdDoc.PrintOut()

        wdDoc.Close(False)
        ReleaseObject(wdDoc)
        ReleaseObject(wdDocs)
        wdApp.Quit()
    End Sub

    Private Sub btnPreview_Click(sender As Object, e As EventArgs) Handles btnPreview.Click
        wdApp = New Word.Application
        wdDocs = wdApp.Documents

        Dim wdDoc As Word.Document = wdDocs.Open(sPath & sFileName & ".docx")
        wdDoc.SaveAs2(sPath & sFileName, Word.WdSaveFormat.wdFormatHTML)
        wdDoc.Close(False)

        ReleaseObject(wdDoc)
        ReleaseObject(wdDocs)
        wdApp.Quit()

        wbPreview.Navigate(sPath & sFileName & ".htm")
    End Sub

    Private Sub frmWordTemplate_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If wdDocs IsNot Nothing Then
            ReleaseObject(wdDocs)
        End If
        If wdApp IsNot Nothing Then
            ReleaseObject(wdApp)
        End If
    End Sub

    Private Sub ReleaseObject(ByVal obj As Object)
        'http://www.siddharthrout.com/2012/08/06/vb-net-two-dot-rule-when-working-with-office-applications-2/
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
End Class



Is This A Good Question/Topic? 1
  • +

Replies To: Word Template - Fill In, Print and Preview

#2 andrewsw  Icon User is offline

  • I'd like to return this printer
  • member icon

Reputation: 6322
  • View blog
  • Posts: 25,422
  • Joined: 12-December 12

Posted 22 January 2016 - 01:56 PM

For an application to be distributable you would use, for example, Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) to get the current user's Documents folder, and wdApp.Options.DefaultFilePath(Word.WdDefaultFilePath.wdWorkgroupTemplatesPath) to get the shared location for Word templates.

Environment.SpecialFolder Enumeration :MSDN
Was This Post Helpful? 0
  • +
  • -

#3 nighttrain  Icon User is offline

  • D.I.C Regular

Reputation: 8
  • View blog
  • Posts: 483
  • Joined: 22-September 10

Posted 23 March 2016 - 04:05 AM

where is code regarding webbrowser?
Was This Post Helpful? 0
  • +
  • -

#4 andrewsw  Icon User is offline

  • I'd like to return this printer
  • member icon

Reputation: 6322
  • View blog
  • Posts: 25,422
  • Joined: 12-December 12

Posted 23 March 2016 - 04:10 AM

Line 78 (and above) in the final code,
    wbPreview.Navigate(sPath & sFileName & ".htm")

Before this, SaveAs2 creates the temporary HTML version of the file.

(I've added a note in the tutorial to refer to the full code.)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1