【问题标题】:How to convert Word document created from template by OpenXML into MemoryStream?如何将 OpenXML 从模板创建的 Word 文档转换为 MemoryStream?
【发布时间】:2019-08-16 22:23:13
【问题描述】:

我需要在 ASP.NET 控制器方法中将文档作为 MemoryStream 返回以在网页上下载它。我不想将此文档保存在文件中,然后将其作为 MemoryStream 读取并返回。 注意:重载方法 WordprocessingDocument.CreateFromTemplate(template) 没有流选项 vs WordprocessingDocument.Create(stream, ...)

保存临时文件的解决方案如下。

    public static MemoryStream GetWordDocumentFromTemplate()
    {
        string tempFileName = Path.GetTempFileName();
        var templatePath = AppDomain.CurrentDomain.BaseDirectory + @"Controllers\" + templateFileName;

        using (var document = WordprocessingDocument.CreateFromTemplate(templatePath))
        {
            var body = document.MainDocumentPart.Document.Body;

            //add some text 
            Paragraph paraHeader = body.AppendChild(new Paragraph());
            Run run = paraHeader.AppendChild(new Run());
            run.AppendChild(new Text("This is body text"));

            OpenXmlPackage savedDoc = document.SaveAs(tempFileName); // Save result document, not modifying the template
            savedDoc.Close();  // can't read if it's open
            document.Close();
        }

        var memoryStream = new MemoryStream(File.ReadAllBytes(tempFileName)); // this works but I want to avoid saving and reading file

        //memoryStream.Position = 0; // should I rewind it? 
        return memoryStream;
    }

【问题讨论】:

  • 我已经有一段时间没有这样做了,但我相信您想要做的是获取响应流并在该流上构建 WordprocessingDocument。然后设置 mime 类型等并将流返回给客户端。

标签: c# ms-word openxml memorystream


【解决方案1】:

找到无需保存到中间临时文件即可工作的答案。诀窍是打开模板进行编辑,使用可访问的流,将文档类型从模板更改为文档,然后返回此流。

public static MemoryStream GetWordDocumentStreamFromTemplate()
{
    var templatePath = AppDomain.CurrentDomain.BaseDirectory + "Controllers\\" + templateFileName;
    var memoryStream = new MemoryStream();

    using (var fileStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read))
        fileStream.CopyTo(memoryStream);

    using (var document = WordprocessingDocument.Open(memoryStream, true))
    {
        document.ChangeDocumentType(WordprocessingDocumentType.Document); // change from template to document

        var body = document.MainDocumentPart.Document.Body;

        //add some text 
        Paragraph paraHeader = body.AppendChild(new Paragraph());
        Run run = paraHeader.AppendChild(new Run());
        run.AppendChild(new Text("This is body text"));

        document.Close();
    }

    memoryStream.Position = 0; //let's rewind it
    return memoryStream;
}

完整的测试解决方案: https://github.com/sergeklokov/WordDocumentByOpenXML/blob/master/WordDocumentByOpenXML/Program.cs

【讨论】:

    【解决方案2】:

    不幸的是,这似乎不可能;如果您转到“另存为”上的定义并尽可能深入,您可以:

    protected abstract OpenXmlPackage OpenClone(string path, bool isEditable, OpenSettings openSettings);

    所以看起来原始字符串 XML 是在运行时构造并在内部保存到文件中的,并且没有只产生原始字符串(或流)的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      相关资源
      最近更新 更多