About two years ago I wrote some code to construct a PDF document on the fly and display it in the browser. Yesterday I was trying to do the same thing for a Word document. If you've seen earlier posts this month you will see I am using Aspose Words for .Net to perform a mail merge. I wanted the ability to preview the result before saving the output.
Now when I did this previously for a PDF file I had a web service that returned a memory stream and I was able to load that into the Response.OutputStream object without difficulty. But I immediately ran into a problem with my web service which is built with .Net FW 4.0. The memory stream I returned became a marshalled object which does not have the same properties for WriteTo() or ToArray() which meant I could not easily load it into Response.OutputStream.
I suppose I could have found a solution but instead I thought I would return it as a string instead. Alas that gave a new set of problems which I suspect was down to encoding when converting between the stream and the string. This morning I tried converting to a base base64 string and that did the trick.
So firstly here is the code in the web service that converts the memory stream to base64.
public string PreviewMerge(DataMergeRequest req)
{ // code to do mailmerge goes here
MemoryStream msRawData = merge.MergeDataSet(ds, templatelocation);
string base64;
// ENCODE TO BASE 64
base64 = Convert.ToBase64String(msRawData.GetBuffer(), 0, (int)msRawData.Length);
return base64;
}
On the ASPX page you need to remove everything below the Page directive.
In the Page_Load event you need this code. Note you should NOT use Response.End - there is a known issue with it creating a Threading exception. Use HttpContext.Current.ApplicationInstance.CompleteRequest() instead.
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Charset = "";
// get results of merge as base 64 encoded stream
string strBase64 = ds.PreviewMerge(req);
// DECODE into memory stream
byte[] raw = Convert.FromBase64String(strBase64);
using (MemoryStream decoded = new MemoryStream(raw))
{
// load the stream into the Response Output stream
decoded.WriteTo(Response.OutputStream);
}
// set the content type for docx
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
No comments:
Post a Comment