简体   繁体   English

如何使用 openxml 在 ASP.NET MVC 项目中打开 docx 文件以覆盖一些文本

[英]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.我的 MVC 项目文件夹中有一个 .docx 文件,我想打开它来覆盖一些文本,但我无法这样做。

Inside my project folder, I have a Template folder and in this folder a genrated.docx file that I want to open.在我的项目文件夹中,我有一个Template文件夹,在这个文件夹中有一个我想要打开的genrated.docx文件。 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.不幸的是,一旦您使用 Microsoft Word 编辑模板,您的“要替换”文本可能会在多次运行中拆分。 This then means that you can't find your text "to-replace" if you only look for it in a single Text instance.这意味着如果您仅在单个Text实例中查找文本,则无法找到“要替换”的Text

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.下面的单元测试演示了通过创建一个包含两个段落的文档,一个段落有一个带有“要替换”文本的单个Text实例,另一个是将相同的文本拆分为两个RunText实例。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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