Friday, September 5, 2008

Viewing a document in memory with WPF

I have to create a tool that displays documents to a user with a memorystream. I decided to try this with wpf, but i was having a lot of trouble with it.

This site was giving me the idea on how to view xps documents through a memorystream, but I was getting a corrupted file error on Package.Open when i tried to read a .doc or .pdf file. The files that I'll be needing to read are mostly .pdf files.

I don't want to make the file available to the users, which is why i'm not just quickly writing the data from it's bytes to a an actual file, and just reading that. I've ended up just deciding to make a compromise with that, and use isolated storage to write the file to, and purge it when the app is done. Feels like a cheat, but I'm not getting many better results.

I integrated a webbrowser with my WPF code using windowsformsintegration:

<WindowsFormsHost>
<winfrm:WebBrowser x:Name="wbBrow"></winfrm:WebBrowser>
</WindowsFormsHost>

I tried playing with the 'documentstream' option on the webbrowser control, but that doesn't work for .pdf files, it just shows gibberish. I also tried using adobe's own COM control, but there is only a "LoadFile" option, which doesn't give me any extra help.

One of the real annoying things about this project is that the pdf file is password protected, and i have no idea how avoid getting the user to type in the password by doing it programmatically.

Labels: , , , , , ,

Tuesday, September 2, 2008

Exporting a web report as a word doc

I've been working on a project where a user can naviagate to a web page, and choose to download the latest information on a project as a word document. This information can contain grids, attachments, all sorts of things. I decided to take the easy/quick way of doing this, and just write out HTML to the actual web page. On the response object, i would simply set:


HttpContext.Current.Response.Clear()
HttpContext.Current.Response.Charset = ""
HttpContext.Current.Response.ContentType = "application/msword"
HttpContext.Current.Response.AddHeader("Content-Disposition", "inlinefilename=" + strFileName)

i would then write out the content as HTML, where strHTMLContent is a stringbuilder. Something like:

strHTMLContent.Append("<br/>")
strHTMLContent.Append("<table align="'Center'" width="'100%'">")
strHTMLContent.AppendLine("<tr><th>Attachments:</th></tr>")
strHTMLContent.AppendLine("<tr><td>")

'blah blah blah, and then i would finish it by:

HttpContext.Current.Response.Write(strHTMLContent)
HttpContext.Current.Response.End()
HttpContext.Current.Response.Flush()

This works fine for the most part, but the attachments make it a bit annoying. For images, i just use a reference to "<img src='viewattachment.aspx?...",, where i created a secondary web page called "viewattachment" that can display my attachments based on a primary key value.

When the word doc gets saved, since it has the .doc extension, it's opened by Word, but it isn't an actual word file, regardless of the ContentType value I entered in at the top. This means that opening the word file calls the link to the viewattachment.aspx web page, which isn't really acceptable if the client opening the word doc has no internet connection. If you choose to 'save as' for the document, it will show that it sees it as an .html file. If you choose to save it as a word document, then that embeds the image.

An annoying extra step, but probably what I have to deal with by taking the easy way out and avoiding word COM objects.

The last point was that using the "<iframe src=''" string to show attachments doesn't work at all. It just doesn't show up in the word document, HTML version or DOC version. Some of our attachments are html documents, and i was hoping to display them that way, but it looks like i'll have to open each document one-by-one and write out their text.

Labels: , , ,