2016-08-24 1 views
1

J'ai créé une DLL qui prend un modèle Word, j'ai un code qui édite le document en utilisant openXML puis le résultat est envoyé par flux mémoire à un service web où les documents sont téléchargés à l'utilisateur. Le problème est que le flux de mémoire envoie est le document de modèle d'origine sans les mises à jour OU envoie le format XML de document Word mis à jour où le document est évidemment endommagé. Voici le code:L'édition de docx avec openxml renvoie une mémoire invalide

string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx"; 

WordprocessingDocument wdDocument; 

//stream the template 
byte[] fileBytes = File.ReadAllBytes(strTemplate); 
MemoryStream memstreamDocument = new MemoryStream(); 

memstreamDocument.Write(fileBytes, 0, (int)fileBytes.Length); 

wdDocument = WordprocessingDocument.Open(memstreamDocument, true); 

//CODE TO UPDATE TEMPLATE 

//Save entire document 
wdDocument.MainDocumentPart.Document.Save(); 

Après avoir enregistré le document, si vous utilisez le code suivant le flux de mémoire renvoie le modèle d'origine sans aucune mise à jour du document:

return memstreamDocument; 

Si vous utilisez le code suivant la mémoire flux renvoie les données OpenXML avec les mises à jour, mais le document est corrompu:

MemoryStream memstreamUpdatedDocument = new MemoryStream(); 
Stream streamDocument = wdDocument.MainDocumentPart.GetStream(); 
streamDocument.CopyTo(memstreamUpdatedDocument); 
return memstreamUpdatedDocument; 

Voici mon code dans le service Web qui fonctionne très bien:

HttpResponse response = HttpContext.Current.Response; 
MemoryStream stream = GR.GetReport("", intReportID, Culture, ConnectionString, false); 

response.Clear(); 
response.ClearHeaders(); 
response.ClearContent(); 
response.AddHeader("content-disposition", "attachment; filename=\"" + "Report_" + intReportID+ ".docx\""); 
response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; 
response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1"); 
stream.Position = 0; 
stream.CopyTo(response.OutputStream); 
response.End(); 
return response; 

Répondre

2

Après avoir examiné le code fourni, j'ai fourni un extrait de code modifié qui devrait répondre à vos besoins de retour d'un MemoryStream modifié à partir d'un modèle de fichier en utilisant la classe WordprocessingDocument par OpenXML. Votre extrait de code de service Web fourni doit fonctionner tel quel.

// file path of template 
string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx"; 

// create FileStream to read from template 
FileStream fsTemplate = new FileStream(strTemplate, FileMode.Open, FileAccess.Read); 

// create MemoryStream to copy template into and modify as needed 
MemoryStream msDocument = new MemoryStream(); 

// copy template FileStream into document MemoryStream 
fsTemplate.CopyTo(msDocument); 

// close the template FileStream as it is no longer necessary 
fsTemplate.Close(); 

// reset cursor position of document MemoryStream back to top 
// before modifying 
msDocument.Position = 0; 

// create WordProcessingDocument using the document MemoryStream 
using (WordprocessingDocument wdDocument = WordprocessingDocument.Open(msDocument, true)) { 

    //Access the main Workbook part, which contains all references. 
    MainDocumentPart mainPart = wdDocument.MainDocumentPart; 

    /* ... CODE TO UPDATE TEMPLATE ... */ 

    // save modification to main document part 
    wdDocument.MainDocumentPart.Document.Save(); 

    // close wdDocument as it is no longer needed 
    wdDocument.Close(); 
} 

// reset cursor position of document MemoryStream back to top 
msDocument.Position = 0; 

// return memory stream as promised 
return msDocument;