Replace Text in Word document using Open Xml

In addition to Flowerking's answer:

When your Word file has textboxes in it, his solution would not work. Because textbox has TextBoxContent element so it will not appear at foreach loop of Runs.

But when writing

using ( WordprocessingDocument doc =
                    WordprocessingDocument.Open(@"yourpath\testdocument.docx", true))
{
    var document = doc.MainDocumentPart.Document

    foreach (var text in document.Descendants<Text>()) // <<< Here
    {
        if (text.Text.Contains("text-to-replace"))
        {
            text.Text = text.Text.Replace("text-to-replace", "replaced-text");
        }
    } 
}
        

it will loop all the texts in document(whether it is in textbox or not) so it will replace the texts.

Note that if the text is split between Runs or Textboxes, this also won't work. You need a better solution for those cases. One solution to split texts could be fixing the "template", sometimes, simply deleting the placeholder and re-creating it works wonders.


Just to give you the idea of how to do it, please try:

  using ( WordprocessingDocument doc =
                    WordprocessingDocument.Open(@"yourpath\testdocument.docx", true))
            {
                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>())
                        {
                            if (text.Text.Contains("text-to-replace"))
                            {
                                text.Text = text.Text.Replace("text-to-replace", "replaced-text");
                            }
                        }
                    }
                }
            }
        }

Please note the text is case sensitive. The text formatting won't be changed after the replace. Hope this helps you.


Maybe this solution is easier:
1. a StreamReader reads all the text,
2. using a Regex you case-insensitively replace the new text instead of the old tex
3. a StreamWriter writes again the modified text into the document.

 using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
    string docText = null;
    using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
        docText = sr.ReadToEnd();

    foreach (var t in findesReplaces)
        docText = new Regex(findText, RegexOptions.IgnoreCase).Replace(docText, replaceText);

    using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
        sw.Write(docText);
}