2016-08-24 1 views
1

Ich erstellte eine DLL, die eine Word-Vorlage nimmt, habe Code, der das Dokument mit openXML bearbeitet, dann wird das Ergebnis über Speicherströme an einen Webdienst gesendet, wo die Dokumente an den Benutzer heruntergeladen werden. Das Problem besteht darin, dass der Speicherstream entweder das ursprüngliche Vorlagendokument ohne die Aktualisierungen sendet ODER das aktualisierte Word-Dokument-XML-Format sendet, in dem das Dokument offensichtlich beschädigt ist. Hier ist der Code:Bearbeiten von docx mit openxml gibt ungültigen memorystream zurück

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

Nach dem Speichern des Dokuments, wenn Sie den folgenden Code unter Verwendung der Speicherstrom die ursprüngliche Vorlage zurück, ohne Änderungen zu dem Dokument:

return memstreamDocument; 

Wenn Sie den folgenden Code unter Verwendung der Speicher Strom gibt die OpenXML-Daten mit dem Updates aber das Dokument beschädigt ist:

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

Hier mein Code im Web-Service ist, der gut arbeitet:

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; 

Antwort

2

Nach dem mitgelieferten Code Überprüfung ich einen modifizierten Code-Schnipsel zur Verfügung gestellt habe, die Ihre Bedürfnisse der Rückkehr ein modifizierten MemoryStream aus einer Dateivorlage mit der WordprocessingDocument Klasse von OpenXML passen sollten. Ihr bereitgestelltes Webservice-Code-Snippet sollte so funktionieren wie es ist.

// 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; 
Verwandte Themen