web-dev-qa-db-fra.com

Remplacer le texte dans un document Word en utilisant Open Xml

J'ai créé un fichier docx à partir d'un modèle Word. J'accède maintenant au fichier docx copié et souhaite remplacer un texte par d'autres données.

Je ne parviens pas à comprendre comment accéder au texte à partir de la partie principale du document.

Toute aide serait appréciable.

Voici mon code jusqu'à maintenant.

private void CreateSampleWordDocument()
    {
        //string sourceFile = Path.Combine("D:\\GeneralLetter.dot");
        //string destinationFile = Path.Combine("D:\\New.doc");
        string sourceFile = Path.Combine("D:\\GeneralWelcomeLetter.docx");
        string destinationFile = Path.Combine("D:\\New.docx");
        try
        {
            // Create a copy of the template file and open the copy
            File.Copy(sourceFile, destinationFile, true);
            using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true))
            {
                // Change the document type to Document
                document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
                //Get the Main Part of the document
                MainDocumentPart mainPart = document.MainDocumentPart;
                mainPart.Document.Save();
            }
        }
        catch
        {
        }
    }

Maintenant, comment trouver certains textes et les remplacer? Je ne parviens pas à me connecter via Link, un indice de code serait donc appréciable.

12
Iti Tyagi

Juste pour vous donner une idée de la façon de le faire, essayez:

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

Veuillez noter que le texte est sensible à la casse. La mise en forme du texte ne sera pas modifiée après le remplacement. J'espère que cela vous aide.

15
Flowerking

En plus de la réponse de Flowerking:

Lorsque votre fichier doc contient des zones de texte, le processus ne fonctionnera pas. Parce que textbox a un élément TextBoxContent, il n'apparaîtra donc pas à chaque boucle.

Mais en écrivant

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

il mettra en boucle tous les textes du document (que ce soit dans la zone de texte ou non) afin de remplacer les textes.

7
sertsedat

Peut-être que cette solution est plus simple:
1. StreamReader lit tout le texte,
2. Si vous utilisez une Regex, vous remplacez le nouveau texte sans tenir compte de la casse
3. StreamWriter écrit à nouveau le texte modifié dans le 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);
}
4
Emanuele Greco

Si le texte que vous recherchez est placé entre crochets et que Word scinde votre texte en plusieurs fois ...;

Rechercher le texte (ienumerable (of text))

for (int i = 0; i <= SearchIn.Count - 1; i++) {

    if (!(i + 2 > SearchIn.Count - 1)) {
        Text TXT = SearchIn(i);
        Text TXT1 = SearchIn(i + 1);
        Text TXT2 = SearchIn(i + 2);

        if (Strings.Trim(TXT.Text) == "[" & Strings.Trim(TXT2.Text) == "]") {
            TXT1.Text = TXT.Text + TXT1.Text + TXT2.Text;

            TXT.Text = "";
            TXT2.Text = "";
        }
    }
}
0
Jeroen Samsom