简体   繁体   中英

How to open docx file in ASP.NET MVC project using openxml for overwriting some text

I have searched a lot for the solution but can't find any.

I have a .docx file inside my MVC project folder which I want to open to overwrite some text but I'm unable to do so.

Inside my project folder, I have a Template folder and in this folder a genrated.docx file that I want to open. Here is my code:

using (WordprocessingDocument doc = WordprocessingDocument.Open
    (@"~/Template/genrated.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("to-replace"))
                {
                    text.Text = text.Text.Replace("to-replace", "replace-with");
                    run.AppendChild(new Break());
                }
            }
        }
    }
}

Please help me with this...

Your simplistic approach to replacing text only works in simple cases. Unfortunately, as soon as you use Microsoft Word to edit your template, your text "to-replace" might get split in multiple runs. This then means that you can't find your text "to-replace" if you only look for it in a single Text instance.

The following unit test demonstrates that by creating a document with two paragraphs, one having a single Text instance with your text "to-replace" and another one in which that same text is split into two Run and Text instances.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Xunit;

namespace CodeSnippets.Tests.OpenXml.Wordprocessing
{
    public class SimplisticTextReplacementTests
    {
        private const string ToReplace = "to-replace";
        private const string ReplaceWith = "replace-with";

        private static MemoryStream CreateWordprocessingDocument()
        {
            var stream = new MemoryStream();
            const WordprocessingDocumentType type = WordprocessingDocumentType.Document;

            using WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, type);
            MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
            mainDocumentPart.Document =
                new Document(
                    new Body(
                        new Paragraph(
                            new Run(
                                new Text(ToReplace))),
                        new Paragraph(
                            new Run(
                                new Text("to-")),
                            new Run(
                                new Text("replace")))));

            return stream;
        }

        private static void ReplaceText(MemoryStream stream)
        {
            using WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);

            Body body = doc.MainDocumentPart.Document.Body;
            IEnumerable<Paragraph> paras = body.Elements<Paragraph>();

            foreach (Paragraph para in paras)
            {
                foreach (Run run in para.Elements<Run>())
                {
                    foreach (Text text in run.Elements<Text>())
                    {
                        if (text.Text.Contains(ToReplace))
                        {
                            text.Text = text.Text.Replace(ToReplace, ReplaceWith);
                            run.AppendChild(new Break());
                        }
                    }
                }
            }
        }

        [Fact]
        public void SimplisticTextReplacementOnlyWorksInSimpleCases()
        {
            // Arrange.
            using MemoryStream stream = CreateWordprocessingDocument();
            using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, false))
            {
                Document document = wordDocument.MainDocumentPart.Document;

                Paragraph firstParagraph = document.Descendants<Paragraph>().First();
                Assert.Equal(ToReplace, firstParagraph.InnerText);
                Assert.Contains(firstParagraph.Descendants<Text>(), t => t.Text == ToReplace);

                Paragraph lastParagraph = document.Descendants<Paragraph>().Last();
                Assert.Equal(ToReplace, lastParagraph.InnerText);
                Assert.DoesNotContain(lastParagraph.Descendants<Text>(), t => t.Text == ToReplace);
            }

            // Act.
            ReplaceText(stream);

            // Assert.
            using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, false))
            {
                Document document = wordDocument.MainDocumentPart.Document;

                Paragraph firstParagraph = document.Descendants<Paragraph>().First();
                Assert.Equal(ReplaceWith, firstParagraph.InnerText);
                Assert.Contains(firstParagraph.Descendants<Text>(), t => t.Text == ReplaceWith);

                Paragraph lastParagraph = document.Descendants<Paragraph>().Last();
                Assert.NotEqual(ReplaceWith, lastParagraph.InnerText);
                Assert.DoesNotContain(lastParagraph.Descendants<Text>(), t => t.Text == ReplaceWith);
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM