簡體   English   中英

如何將通過OpenXML從模板創建的Word文檔轉換為MemoryStream?

[英]How to convert Word document created from template by OpenXML into MemoryStream?

我需要使用ASP.NET控制器方法將文檔作為MemoryStream返回,以將其下載到網頁上。 我不想將此文檔保存在文件上,然后將其讀取為MemoryStream並返回。 注意:與WordprocessingDocument.Create(stream,...)相比,重載方法WordprocessingDocument.CreateFromTemplate(template)沒有流選項。

保存臨時文件的解決方案如下。

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

不幸的是,這似乎是不可能的。 如果轉到“另存為”上的“定義”並盡可能深入地查找,則可以:

受保護的抽象OpenXmlPackage OpenClone(字符串路徑,bool isEditable,OpenSettings openSettings);

因此,看起來原始字符串XML是在運行時構造的,並在內部保存到文件中,並且沒有任何方法可以產生原始字符串(或流)。

找到了無需保存到中間臨時文件即可工作的答案。 技巧是打開模板進行編輯,使用可訪問的流,將文檔類型從模板更改為文檔,然后返回此流。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM