使用openxml编辑docx会返回无效的内存流

时间:2016-08-24 15:36:27

标签: c++ web-services openxml memorystream

我创建了一个带有Word模板的DLL,我有使用openXML编辑文档的代码,然后结果通过内存流发送到Web服务,文件被下载到用户。问题是内存流正在发送是没有更新的原始模板文档,或者发送更新的Word文档XML格式,其中文档明显被破坏。这是代码:

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

保存文档后,如果使用以下代码,则内存流将返回原始模板,而不对文档进行任何更新:

return memstreamDocument;

如果使用以下代码,内存流将返回包含更新的openXML数据,但文档已损坏:

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

以下是我在Web服务中运行良好的代码:

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;

1 个答案:

答案 0 :(得分:2)

在查看提供的代码之后,我提供了一个经过修改的代码段,它应该满足您使用OpenXML使用MemoryStream类从文件模板返回修改后的WordprocessingDocument的需要。您提供的网络服务代码段应该按原样运行。

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