使用OpenXML SDK w / ASP.NET流式传输内存Word文档导致“损坏”文档
我无法将我创建的word文档流式传输到浏览器。 我不断从Microsoft Word收到一条消息,说明该文档已损坏。
当我通过控制台应用程序运行代码并将ASP.NET从图片中删除时,文档生成正确,没有任何问题。 我相信一切都围绕着写下文件。
这是我的代码:
using (MemoryStream mem = new MemoryStream()) { // Create Document using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true)) { // Add a main document part. MainDocumentPart mainPart = wordDocument.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(); // Stream it down to the browser // THIS IS PROBABLY THE CRUX OF THE MATTER <--- Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx"); Response.ContentType = "application/vnd.ms-word.document"; mem.WriteTo(Response.OutputStream); Response.End(); } }
我看过很多链接 – 但没有什么可行的。 我很多人使用MemoryStream.WriteTo
,有些人使用BinaryWrite
– 此时我不确定正确的方法是什么。 此外,我尝试了更长的内容类型,即application/vnd.openxmlformats-officedocument.wordprocessingml.document
但没有运气。
一些截图 – 即使你试图恢复你得到相同的“部分丢失或无效”
那些偶然发现这个问题的人的解决方案:
在WordProcessingDocument
的using
指令中,您必须调用:
wordDocument.Save();
另外,为了正确地传输MemoryStream
,请在外部使用块中使用它:
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx"); mem.Position = 0; mem.CopyTo(Response.OutputStream); Response.Flush(); Response.End();
使用CopyTo
, WriteTo
存在一个错误,当目标流不支持一次编写所有内容时,它会无法写入缓冲区的全部内容。
我相信您的ContentType值不正确; 这是Word 97 – 2003格式。 将其更改为:
application/vnd.openxmlformats-officedocument.wordprocessingml.document
并看看是否能解决问题。
我复制并粘贴了你的代码并注意到:“wordDocument.close();” clausule丢失,添加它并且它工作(我在Asp.NET MVC做了一个动作)
作为.NET Framework 3.5及更低版本的变体。 这个版本的框架在类Stream
没有方法CopyTo
。 因此,方法WriteTo
被下一个代码替换:
byte[] arr = documentStream.ToArray(); fileStream.Write(arr, 0, arr.Length);
示例来自http://blogs.msdn.com/b/mcsuksoldev/archive/2010/04/09/creating-a-new-microsoft-word-document-from-a-template-using-openxml.aspx
为了扩展Rodion的答案并匹配问题中使用的变量,这对我有用:
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();