Introduction
Recently, I was commissioned to develop an ASP.NET solution to which the client would randomly upload a Word document as a template with pre-defined 'mail merge' fields which would then be automatically populated through my code from an RDMS (in my case, MS SQL Server, but you could use just about any source of input instead) and saved elsewhere.
Background
A basic understanding of how COM works and .NET is enough for anyone to accomplish this.
Using the code
As any programmer can tell you, there are many ways of going about any task.
- Read articles off forums and try to understand what is going on from the different forms of explanations provided.
- Download sample code and trace it, hopefully understanding what is going on.
- Mess around with the code yourself hoping to get lucky, and use the methods in the right order and the right way (good luck).
Well, I am hoping that you go for the former option, which would make sense, but to save you time, I will just take you step by step and explain the basics required for you to understand what is going on... you can then take it from there.
Note
Although my code samples are provided in C#, you can very easily adapt this code to any .NET language once you understand what is going on.
Assumptions
There are many things I shall have to assume for this article since they go beyond the scope of the article itself.
For the purposes of this example, I shall be assuming that you are using some flavour of the Visual Studio IDE. If you don't have one, the Express Editions of the Visual Studio 2005 are available for free off the Microsoft web site.
Getting Started
First and foremost, we must create a project to work in. What language you use is totally your choice, as is the kind of application you are going to develop. The methods used are the same, you just obviously need to map my syntax to the equivalent in your chosen language.
Now, the first thing we must do prior to developing anything that uses another technology is to 'reference' it in our project. This will allow our code to access methods in the required libraries and use them for our purposes.
I am also assuming that you already have a very basic Word document set up with a couple of Mail Merge fields already in place.
Right click the References section in your project, select Add Reference, followed by selecting the COM tab. Scroll down the list till you find Microsoft Word x.0..., where X represents the version of Office that you have installed.
This is the COM we want to use, so just double click it and voila... you will notice that Visual Studio will automatically add the required references for you (don't you just love it?)
Time to Code
Now that we have the correct references set up, we can start coding.
The way a program references a Word document (or any Office document for that matter) is quite simple.
- First, we need an instance of the application in question to be running (visible or not).
- Then, we resume to load or create our document.
- We do all the editing we need and use any other feature accordingly.
- We save the document.
...and that's pretty much it really. So let's go over them one at a time.
Step 1 - Prepare the 'Application' and 'Document'
The first thing we want to do is add a 'using
' clause to our code, this will make references to the required methods far easier since we won't have to stay qualifying them each time.
using System;
using Microsoft.Office.Interop.Word;
The next thing we want to do is create a Word 'Application' referencing object and a 'Document
' object which we shall be using to allow us to interface with the Word application itself, giving instructions as to what should be done to the document.
So, here we go...
public class MyClass
{
private ApplicationClass myWordApp = new ApplicationClass();
private Document myWordDoc = new Document();
Now, all we need to do is use these objects to do our biddings.
Step 2 - Load our Document Template
Now, we just need to tell Word from where to load our template...
private void ParseWord()
{
object nothing = System.Reflection.Missing.Value;
object filename = "C:\MyWordTemplate.dot";
object destination = "C:\MyNewDocument.doc";
object notTrue = false;
string myText = "Hello World!!";
The above declarations are the basic objects we shall be using as parameters to send to our Word application each time we invoke any method. Since we are speaking COM, we are therefore also speaking 'object
'.
Also, note the declaration of 'nothing
'. We use this for parameters that we are not interested in addressing. So rather than trying to figure out the correct parameters, we need only concentrate on the ones that really affect us.
Next, we want to:
- tell Word not to show itself,
- tell Word to load the template,
- see how many fields we have in this document.
So, here goes...
myWordApp.Visible = false;
myWordDoc = myWordApp.Documents.Add(
ref filename,
ref missing,
ref missing,
ref missing);
int fields = myWordDoc.Count;
Note, we first told Word not to show itself prior to doing anything, you want this if you plan on creating documents, otherwise your workstation might start acting a little bit weird. You can always set this to true
should you want to see what is going on, but I generally see it as far more professional if the end user doesn't see the application itself (after all, that is the beauty of automation).
If you delve further into the object, you will find multiple (very intuitive) parameters which you can add, such as read-only, passwords etc... you can set these using the same style above, ex. object myTrue = true
for a boolean false
.
Step 3 - Let's do our editing
Next, we are counting how many fields we have that can be updated, this can be done through the myWordApp
object, but it is far easier to access it directly through the myWordDoc
(which is why we created it).
Next, we want to change all the fields to our text (for the purposes of this example).
foreach (Field myField in myWordDoc.Fields)
{
myField.Select();
myWordApp.Selection.TypeText( myText );
}
And that is it really, we have replaced all the fields with our default text. Of course, you will hopefully want to make some more complex updates rather than just pasting a string in, but you should now have a rather good understanding of how all this works.
Also, note the use of the 'Field
' data type, this is also part of the COM object and denotes a field. There is a property with this type called 'Result
' which stores the current default text in the field. Rather than using the 'Select()
' option, we could have just written myField.Result = myText
, yet this would still leave it as a field in your new document, which is why I opt for the 'Select()
' method instead (which basically is like highlighting the text in Word and typing over it).
Step 4 - Save...and quit
Last but not least, we now want to save our new document and close Word.
It is important to remember to close Word, since it is actually open in the background, just not visible.
myWordDoc.SaveAs(
ref destination,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing,
ref missing);
myWordApp.Application.Quit(
ref notTrue,
ref missing,
ref missing);
That is all, we now have a new document with updated fields. Neat huh?
Conclusion
As outlined earlier, the purpose of this article is more of an explanation of how to interface with Word rather than a real life example. I seriously doubt you would want to just replace the same string in every field of a document. Yet hopefully, this simple example has given you enough understanding of how things work.
History
- v1.0 - Saturday 12th November 2005.