c# asp.net .net ms-word openxml

c# - Transmitir en la memoria Documento de Word utilizando OpenXML SDK con ASP.NET da como resultado un documento "corrupto"



ms-word (6)

No puedo transmitir un documento de Word que cree al vuelo hacia el navegador. Recibo constantemente un mensaje de Microsoft Word de que el documento está dañado.

Cuando ejecuto el código a través de una aplicación de consola y saco a ASP.NET de la imagen, el documento se genera correctamente sin problemas. Creo que todo se centra en escribir el archivo.

Aquí está mi código:

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(); } }

He looked muchos links , pero nada funciona bien. Mucha gente usa MemoryStream.WriteTo y algunos usan BinaryWrite ; en este momento no estoy seguro de cuál es la forma correcta. También he probado el tipo de contenido más largo, es decir, application/vnd.openxmlformats-officedocument.wordprocessingml.document pero no hay suerte.

Algunas capturas de pantalla: incluso si intentas recuperar, obtienes las mismas "faltan partes o no son válidas"

Solución para quienes tropiezan con esta pregunta:

Dentro de la directiva de using de WordProcessingDocument , debe llamar a:

wordDocument.Save();

También para transmitir correctamente el MemoryStream , use esto en el bloque externo de uso:

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();



Copié y pegué su código y noté que: "wordDocument.close ();" faltó clausule, lo agregó y funcionó (lo hice en Asp.NET MVC con una acción)


Creo que su valor de ContentType es incorrecto; Eso es para Word 97 - 2003 formato. Cambiarlo a:

application/vnd.openxmlformats-officedocument.wordprocessingml.document

y ver si eso soluciona el problema.


En primer lugar, siempre incluya Content-Length. Si el navegador no conoce la longitud del cuerpo de respuesta http, entonces la conexión permanece abierta (keep-alive). Si no hay otra forma, guarde el contenido en el archivo temporal (con la opción de eliminar al cerrar) y luego obtenga la longitud del contenido.

En segundo lugar, el procesamiento de documentos IN-MEM no funciona para todas las opciones (por ejemplo, no puede insertar un fragmento en el documento. Debe usar el modo de archivo).

A continuación se muestra la muestra para el núcleo de aspnet:

[HttpPost] public async Task<ActionResult<MopedResponse>> PostAsync(IFormCollection collection) { string pathTemp = Path.GetTempFileName(); // get the temp file name // create or process the word file // reopen it for serving FileStream merged = new FileStream(pathTemp, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose); System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition { FileName = "parafa.docx", Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline }; Response.Headers.Add("Content-Disposition", cd.ToString()); Response.Headers.Add("Content-Length", merged.Length.ToString()); return File(merged, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "mywordFile1.docx"); }


En su lugar, use CopyTo , hay un error en WriteTo que hace que no pueda escribir todo el contenido del búfer cuando la secuencia de destino no admite escribir todo de una vez.


Para ampliar la respuesta de Rodion y combinar las variables utilizadas en las preguntas, esto es lo que me funcionó:

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();