修改WordprocessingDocument不会保存更改

问题描述

这是我第一次使用DocumentFormat.OpenXml,所以我有一个菜鸟问题/问题。

使用此帖子的帮助: Save modified WordprocessingDocument to new file我编写了以下代码,以更改现有Word(.docx)文档中的某些文本(按标签),然后下载为新文件

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

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,(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,(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");
}