Aug 20

Generating a document using OpenXml and returning it from code-behind looks trivial but it's not! I lost many hours searching on Internet to understand why my accents are obfuscated.
After many unsuccessful attempts, I arrive to this code: SPEncode.UrlEncode() But wait… I don't always work with SharePoint… another solution was given by Rick Strahl: Uri.EscapeDataString

The accent problem only occurs when working with IE. Others browsers seems to handle the encoding fine.

Other problems encountered: Office Word cannot download the document if SSL is used. But this time, it seems to be a known bug.

 

public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
{
	if (reportName.Length > 128) reportName = reportName.Substring(0, 128);
	string encodedFilename = reportName.Replace(';', ' ');

	if (request.Browser.Browser.Contains("IE"))
	{
		// Replace the %20 to obtain a clean name when saving the file from Word.
		encodedFilename =
		  Uri.EscapeDataString(Path.GetFileNameWithoutExtension(encodedFilename)).Replace("%20", " ")
			+ Path.GetExtension(encodedFilename);
	}

	// use the correct content-type (not 'application/msword') or FF will append .doc to the filename
	response.AppendHeader("Content-Disposition", "attachment;filename=\"" + encodedFilename + "\"");
	if (reportName.EndsWith(".docx"))
		response.ContentType = "application/vnd.ms-word.document";
	else
		response.ContentType = "application/vnd.ms-word.template";

	// IE cannot download an MS Office document from a website using SSL if the response
	// contains HTTP headers such as:   Pragram: no-cache   and/or    Cache-controo: no-cache,max-age=0,must-revalidate
	// http://support.microsoft.com/kb/316431/
	if (!(request.IsSecureConnection && request.Browser.Browser.Contains("IE")))
		response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
}

 

That's it for the cosmetic part of the generation. Now, let's deal with a minimal empty document, generated from scratch:

using (WordprocessingDocument package = WordprocessingDocument.Create(generatedStream, WordprocessingDocumentType.Document))
{
	MainDocumentPart mainPart = package.AddMainDocumentPart();
	new Document(new Body()).Save(mainPart);

	Body body = mainPart.Document.Body;
	body.Append(new Paragraph(
				new Run(
					new Text("Hello World!"))));

	mainPart.Document.Save();
}
  

You cannot write a smaller code!
Now we will output the document stream to the asp.net response. Put the next code in your Page or IHttpHandler

using(MemoryStream generatedStream = new MemoryStream())
{
	CreateDocument(generatedStream);

	SetContentType(context.Request, context.Response, "Modèle par défaut.docx");
	generatedStream.WriteTo(context.Response.OutputStream);
	context.Response.Flush();
}

And you will obtain:

 

Tags:

Comments

surfing anonymously

Posted on Saturday, 24 October 2009 09:08

Well, this is my first visit to your blog! We are a group of volunteers and starting a new initiative in a community in the same niche. Your blog provided us valuable information to work on. You have done a marvellous job!

Add comment




  Country flag

biuquote
Loading