Calendar

<<  mars 2010  >>
lumamejevesadi
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

(septembre 6, 2008 09:09)

Some time ago, I have published a serie of article speaking about VSTO, .NET 3.5 and Excel. A few time ago, I wanted to merge a word document with a CSV file.

Let's see step by step how to achieve this:

Let's create a .csv file

  • Create a simple text file on which you will put
    • Some key names on the first line
    • Some values in the second line
  • Save it (let's say c:\temp\merge\datafile.txt)

This file will be the one that will be merged with your word template.

Let's create your template word document

  • Open Word (I will give the instructions following Word 2007)
  • Click on "Mailings"
  • Click on "Start Mail Merge" and "Letter"
  • Click on "Select Recipients"
  • Click on "Use an existing Data Source File" and select the file you have just created in the previous step
  • Just write down your document and when you want to insert one of the fields that is present in the document just do the following :
    • Click on "Mailings"
    • Click on "Insert a merge field" and select the field you want to add
  • Save the document (let's say c:\temp\merge\doc to merge.docx)

Let's now do the merge programmatically

  • Create a new Console Application
  • Add a reference to the following DLLs:
    • Microsoft.Office.Interop.Word.dll
    • Microsoft.Office.Tools.Word.v9.0.dll 

The code is quite clear but here are some additional comments to help understanding some parts:

using System;
using Microsoft.Office.Interop.Word;
 
class Program
{
   static object missing = Type.Missing;
 
   static void Main(string[] args)
   {
      //1. Get the winword application
      _Application application = (_Application)new Application();
 
      //2. Open the template document
      object fileName = @"C:\Temp\Merge\doc to merge.docx";
      _Document document = application.Documents.Open(ref fileName, 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);
 
      //3. Prepare the Mail Merge
      document.MailMerge.MainDocumentType = WdMailMergeMainDocType.wdFormLetters;
      document.MailMerge.Destination = WdMailMergeDestination.wdSendToNewDocument;
 
      //4. Open the data source (recipents)
      string dataSource = @"C:\Temp\Merge\datafile.txt";
      object subType = WdMergeSubType.wdMergeSubTypeOther;
      document.MailMerge.OpenDataSource(dataSource, 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 subType);
 
      //5. Execute the MailMerge
      document.MailMerge.Execute(ref missing);
 
      //6. Close the template without saving
      object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
      document.Close(ref saveChanges, ref missing, ref missing);
 
      //7. Get a reference to the newly created document 
      //   (it will be the only opened document, ie, index = 1)
      object index = 1;
      document = application.Documents.get_Item(ref index);
 
      //8. Save the newly created document
      object newFileName = @"C:\Temp\Merge\doc merged.docx";
      document.SaveAs(ref newFileName, 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);
      document.Close(ref missing, ref missing, ref missing);
 
      //9. Close Winword
      object saveOptions = WdSaveOptions.wdDoNotSaveChanges;
      application.Quit(ref saveOptions, ref missing, ref missing);
   }
}
  • I use the _Application and _Document class instead of Application and Document to avoid having some warning due to ambiguous calls.
  • Yes, Application is an interface. So why do we do a new on an interface ? Simply because we are dealing with COM objects
  • The WORD object model uses only by reference parameters. However there is no problelm declaring a static variable as a shortcut to Type.Missing
  • All collection in the office object model are 1-based (contrary to the .NET collections that are all 0-based)
  • You should of course be a lot more cautious when using this code in production mode : be sure that the Close and Quit methods get called, otherwise, you will get many processes running in background !
  • If you want to see the application running, just do application.visible = true

What does it give ?

Billets liés

Commentaires

janvier 29. 2009 21:40

merci pour l'information.
il est très utile.

Busby SEO Test Freak

février 26. 2009 16:09

Thanks very helpful. You did have one error though. Although you are declaring the new file name "doc Merged.docx", by default the Document.SaveAs method saves the file in compatibility mode. (At least it did on my computer.) I was getting an error trying to open the merged file and couldn't figure out why. I believe Word was expecting 07 format from the extension, but getting '97 format.

If you set the second parameter on the SaveAs() it fixes the issue.

object saveFormat = WdSaveFormat.wdFormatDocumentDefault;
document.SaveAs(ref newFileName, ref saveFormat, 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);
document.Close(ref missing, ref missing, ref missing);

Thanks!

Jason Gerstorff

Ajouter un commentaire


 

  Country flag





Live preview

mars 12. 2010 15:37

Powered by BlogEngine.NET 1.2.0.0 | Theme by Pierre-Emmanuel Dautreppe