Streaming in memoria Documento Word che utilizza OpenXML SDK con ASP.NET produce un documento “corrotto”

Non riesco a riprodurre in streaming un documento word che creo rapidamente sul browser. Ricevo costantemente un messaggio da Microsoft Word che il documento è corrotto.

Quando eseguo il codice tramite un’applicazione console e estrapolo ASP.NET dall’immagine, il documento viene generato correttamente senza problemi. Credo che tutto sia incentrato sulla scrittura del file.

Ecco il mio codice:

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

Ho esaminato molti collegamenti , ma niente funziona. Molte persone usano MemoryStream.WriteTo e alcuni usano BinaryWrite – a questo punto non sono sicuro di quale sia il modo corretto. Inoltre ho provato il tipo di contenuto più lungo, vale a dire application/vnd.openxmlformats-officedocument.wordprocessingml.document ma senza fortuna.

Alcuni screenshot – anche se provi a recuperare ottieni le stesse “parti mancanti o non valide”

Soluzione per coloro che incappano in questa domanda:

All’interno della direttiva using di WordProcessingDocument , è necessario chiamare:

 wordDocument.Save(); 

Inoltre, per eseguire correttamente lo streaming di MemoryStream , utilizzare questo nel blocco using esterno:

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

inserisci la descrizione dell'immagine quiinserisci la descrizione dell'immagine qui

Usa CopyTo , invece, c’è un errore in WriteTo che non riesce a scrivere l’intero contenuto del buffer quando lo stream di destinazione non supporta la scrittura di tutto in una volta.

Credo che il valore ContentType non sia corretto; questo è per il formato Word 97 – 2003. Cambiarlo in:

 application/vnd.openxmlformats-officedocument.wordprocessingml.document 

e vedere se questo risolve il problema.

Ho copiato e incollato il codice e ho notato che: “wordDocument.close ();” mancava clausule, l’ho aggiunto e ha funzionato (l’ho fatto in Asp.NET MVC witing un’azione)

Come variante per .NET Framework 3.5 e versioni precedenti. Questa versione del framework non ha il metodo CopyTo nella class Stream . Pertanto, il metodo WriteTo è sostituito dal codice seguente:

 byte[] arr = documentStream.ToArray(); fileStream.Write(arr, 0, arr.Length); 

L’esempio è stato trovato da http://blogs.msdn.com/b/mcsuksoldev/archive/2010/04/09/creating-a-new-microsoft-word-document-from-a-template-using-openxml.aspx

Per espandere la risposta di Rodion e abbinare le variabili utilizzate nelle domande questo è ciò che ha funzionato per 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();