修改 WordprocessingDocument 不保存更改

Modifying WordprocessingDocument does not save changes

这是我第一次使用 DocumentFormat.OpenXml 所以我是菜鸟 question/problem。

使用此 post 的帮助: Save modified WordprocessingDocument to new file 我编写了下面的代码来更改现有 Word (.docx) 文档中的一些文本(通过标签),然后下载为新文件。

我正在为小型 Web 应用程序使用 Asp.Net Core 3.1。

byte[] result;
//source file
var path = Path.Combine(_webHostingEnvironment.WebRootPath, "templates\MyReport.docx");
string documentText;

byte[] byteArray = System.IO.File.ReadAllBytes(path);
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length);
    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
    {
        using (StreamReader reader = new StreamReader(doc.MainDocumentPart.GetStream()))
        {
            documentText = reader.ReadToEnd();
        }

    documentText = documentText.Replace("company", "My Company ltd.");
    }
    result = stream.ToArray();
}

//download new file
return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "MyReport.docx");

我遇到了两个问题:

  1. 下载的文件与源Word文件完全相同。 documentText.Replace 似乎对正在下载的文件没有影响
  2. 当我想在源 Word 文件中使用更“复杂”的标签时,例如{company} 它在 documentText 中被“拆分”成单独的词...

我做错了什么?

显然在 WordprocessingDocument 中使用 StreamReader 是错误的。这是一个工作示例,以防其他人正在寻找类似的解决方案(在这篇文章的帮助下:OfficeTalk: Working with In-Memory Open XML Documents):

public virtual IActionResult ExportWord()
{
    byte[] result;

    // path to where your template is stored
    var path = Path.Combine(_webHostingEnvironment.WebRootPath, "files\template.docx");

    // key-value pairs of what you want to change
    Dictionary<string, string> dict = new Dictionary<string, string>
    {
        { "key1", "value1" },
        { "key2", "value2" },
        { "key3", "value3" },
        // etc.
    };

    // read template into stream
    byte[] byteArray = System.IO.File.ReadAllBytes(path);
    using (MemoryStream mem = new MemoryStream())
    {
        mem.Write(byteArray, 0, (int)byteArray.Length);
        using (WordprocessingDocument doc = WordprocessingDocument.Open(mem, true))
        {
            // Modify the document as necessary.
            var body = doc.MainDocumentPart.Document.Body;
            var paras = body.Elements<Paragraph>();

            foreach (var para in paras)
            {
                foreach (var run in para.Elements<Run>())
                {
                    foreach (var text in run.Elements<Text>())
                    {
                        foreach (var item in dict)
                        {
                            if (text.Text.Contains(item.Key))
                            {
                                text.Text = text.Text.Replace(item.Key, item.Value);
                            }
                        }
                    }
                }
            }
        }

        // At this point, the memory stream contains the modified document.
        result = mem.ToArray();
    }

    return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "modified.docx");
}