Recently at work I was tasked with coding a solution for an interesting problem. I was pretty excited about it since most of my work is centered around database work and data analysis, and this would be 'real' coding in ASP.NET.
The specifics of this stage of the project were to create a web page that accessed server side data and allowed them to click a button in the browser and print out a selected group of post cards, which may number in the 1000's. This instantly brings up the thought of a couple of things. First, this is a web page accessing the client's printer, which can be ugly after Service Pack 2's 'hardening' (I use that term loosely when talking about IE) of Internet Explorer, and it brings up the thought of the easiest way of doing a mail merge, which one would assume would mean word.
This is definitely a doable project, especially if this part of the project will have a very limited number of controllable end user machines. I *know* the machines are all Windows XP SP2 and Word 2003. I found an awesome KB article on automating Word in C# and starting coding. In retrospect, the *easiest* way to do a mail merge is no such thing when you actually get down to it.
Before we get into the details, the first thing you will notice about the KB article is there interesting way you add a using statement for Word 2003.
using Word = Microsoft.Office.Interop.Word;
Definitely a little different than I am used to seeing. So, I add my using statement and get all my code going. I've decided to use a WinControl hosted in IE to do the automation instead of trying to automate Word in clientside script (ick). I get the WinControl working great in a WinForm application, and move the assembly into the folder that contains my ASP.NET app. The control comes up and renders correctly, and then issue number one comes up.
To do a mail merge, Word needs to use something as a data source. Our SQL Server is buried behind ISA server and not accessable from the web, as it should be so I can't query SQL directly. Word won't take a reader or a data set as a data source, but it will take a csv file or a table in a Word document among other things. The example in the article had used a table in another Word document as an example, so I figured that was the best place to start. My WinControl was calling a Web Service and building a new Word document on the fly for the data source. Well, once I hosted this in IE, a caveat came into view. For word to use the new Word document as the data source, it needed to be saved to disk first. The framework was not pleased with this and threw a huge security error.
After doing some research the 'solution' I find is that in order to access the hard drive I need to first strongly name and sign my assemble. I run sn.exe on it, generate the keys, but find out something more interesting when I try to host it after it is signed. It no longer even renders in the browser.
At this point, I've decided 'Fine, I don't want to write to their drive anyhow, let's find a new solution.' My next thought is, why don't I write a csv file onto the server, named with a unique identifier and kill it when I am done. Not the best solution by far, but I want to get something working until I can find a better solution. Well, I come to find out, this is 2005 and I am using Word 2003, but there is no support for using a URI path as a data source...
At this point, I decided that I wasn't going to use Word at all, and was going to pursue writing my own routines to create a maiol merge template. That article will have to be tomorrow's agenda, my fingers are tired...And I know there are better things I could have done with the Word portion and could have even gotten it to work, so remember that if you comment, but I wanted to go into the solution I ended up with, as it is much nicer and cleaner, even though it is lacking in its own rights. Till tomorrow.