I am unable to stream a word document that I create on the fly down to the browser. I am constantly getting a message from Microsoft Word that the document is corrupt.
(This is using OpenXML SDK v 2.10.0 and .Net Core v2.2)
I know this has been answered but I wanted to throw out another option. It is correct that trying to send a stream back in File() like below will result in a corrupt document:
MemoryStream updateStream = new MemoryStream();
wordDocument.Save();
wordDocument.Clone(updateStream);
return File(updateStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
`
A super simple alternative/workaround would be to simply convert your stream to a byte[] like below and it will result in a working word docx
MemoryStream updateStream = new MemoryStream();
wordDocument.Save();
wordDocument.Clone(updateStream);
return File(updateStream.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
I believe your ContentType value is incorrect; that is for Word 97 - 2003 format. Change it to:
application/vnd.openxmlformats-officedocument.wordprocessingml.document
and see if that fixes the problem.
As variant for .NET Framework 3.5 and lower. This version of framework haven't method CopyTo
in class Stream
. Therefore, method WriteTo
is replaced by next code:
byte[] arr = documentStream.ToArray();
fileStream.Write(arr, 0, arr.Length);
Example was found by http://blogs.msdn.com/b/mcsuksoldev/archive/2010/04/09/creating-a-new-microsoft-word-document-from-a-template-using-openxml.aspx
Use CopyTo
instead, there is a bug in WriteTo
which makes it fail to write the entire content of the buffer when the target stream does not support writing everything in one go.
To expand on Rodion's answer and match the variables used in the questions this is what worked for me:
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx");
mem.Position = 0;
byte[] arr = mem.ToArray();
Response.BinaryWrite(arr);
Response.Flush();
Response.End();
I copied and pasted your code and noticed that the :"wordDocument.close();" clausule was missing, added it and it worked (I did it in Asp.NET MVC witing an action)