Word OpenXML替换标记文本

本文关键字:文本 替换 OpenXML Word | 更新日期: 2023-09-27 18:25:22

我正在使用OpenXML来修改Word模板,这些模板包含可通过某些字符识别的简单标记(目前为双V形(ascii 171和187))。

我想用我的文本替换这些标记,它可以是多行的(即来自数据库)。

Word OpenXML替换标记文本

首先需要打开模板:

        //read file into memory
        byte[] docByteArray = File.ReadAllBytes(templateName);
        using (MemoryStream ms = new MemoryStream())
        {
            //write file to memory stream
            ms.Write(docByteArray, 0, docByteArray.Length);
            //
            ReplaceText(ms);
            //reset stream
            ms.Seek(0L, SeekOrigin.Begin);
            //save output
            using (FileStream outputStream = File.Create(docName))
                ms.CopyTo(outputStream);
        }

搜索正文的内部文本xml的简单方法是最快的方法,但不允许插入多行文本,也不提供扩展到更复杂更改的基础。

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(ms, true))
{
     string docText = null;
     //read the entire document into a text
     using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
         docText = sr.ReadToEnd();
     //replace the text
     docText.Replace(oldString, myNewString);
     //write the text back
     using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
         sw.Write(docText);
}

相反,您需要使用元素和结构:

        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(ms, true))
        {
            //get all the text elements
            IEnumerable<Text> texts = wordDoc.MainDocumentPart.Document.Body.Descendants<Text>();
            //filter them to the ones that contain the QuoteLeft char
            var tokenTexts = texts.Where(t => t.Text.Contains(oldString));
            foreach (var token in tokenTexts)
            {
                //get the parent element
                var parent = token.Parent;
                //deep clone this Text element
                var newToken = token.CloneNode(true);
                //split the text into an array using a regex of all line terminators
                var lines = Regex.Split(myNewString, "'r'n|'r|'n");
                //change the original text element to the first line
                ((Text) newToken).Text = lines[0];
                //if more than one line
                for (int i = 1; i < lines.Length; i++)
                {
                    //append a break to the parent
                    parent.AppendChild<Break>(new Break());
                    //then append the next line
                    parent.AppendChild<Text>(new Text(lines[i]));
                }
                //insert it after the token element
                token.InsertAfterSelf(newToken);
                //remove the token element
                token.Remove();
            }
            wordDoc.MainDocumentPart.Document.Save();
        }

基本上,您可以找到Text元素(Word是从文本运行的段落构建的),克隆它,更改它(如果需要,插入新的Break和Text元素),然后将它添加到原始标记Text元素之后,最后删除原始标记Text元素。