【问题标题】:Editing docx with openxml returns invalid memorystream使用 openxml 编辑 docx 会返回无效的内存流
【发布时间】:2023-04-10 22:11:01
【问题描述】:

我创建了一个使用 Word 模板的 DLL,我有使用 openXML 编辑文档的代码,然后通过内存流将结果发送到 Web 服务,在该 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;

这是我在网络服务中运行良好的代码:

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;

【问题讨论】:

    标签: c++ web-services openxml memorystream


    【解决方案1】:

    在查看了提供的代码后,我提供了一个修改后的代码 sn-p,它应该满足您使用 OpenXML 的 WordprocessingDocument 类从文件模板返回修改后的 MemoryStream 的需要。您提供的网络服务代码 sn-p 应该可以正常工作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 2014-02-10
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      相关资源
      最近更新 更多