简体   繁体   English

如何使用Open XML SDK将文本插入到内容控件中

[英]How to insert text into a content control with the Open XML SDK

I'm trying to develop a solution which takes the input from a ASP.Net Web Page and Embed the input values into Corresponding Content Controls within a MS Word Document. 我正在尝试开发一个解决方案,该解决方案从ASP.Net Web页面获取输入并将输入值嵌入到MS Word文档中的相应内容控件中。 The MS Word Document has also got Static Data with some Dynamic data to be Embed into the Header and Footer fields. MS Word文档还具有静态数据,其中一些动态数据将嵌入到页眉和页脚字段中。

The Idea here is that the solution should be Web based. 这里的想法是解决方案应该基于Web。 Can I use OpenXML for this purpose or any other approach that you can suggest. 我可以将OpenXML用于此目的或您可以建议的任何其他方法。

Thank you very much in advance for all your valuable inputs. 非常感谢您提供的所有宝贵意见。 I really appreciate them. 我真的很感激他们。

I have a little code sample from my project, to insert a few words in a content control you've created in a Word document: 我从我的项目中获得了一些代码示例,在您在Word文档中创建的内容控件中插入几个单词:

public static WordprocessingDocument InsertText(this WordprocessingDocument doc, string contentControlTag, string text)
{
    SdtElement element = doc.MainDocumentPart.Document.Body.Descendants<SdtElement>()
      .FirstOrDefault(sdt => sdt.SdtProperties.GetFirstChild<Tag>()?.Val == contentControlTag);

    if (element == null)
      throw new ArgumentException($"ContentControlTag \"{contentControlTag}\" doesn't exist.");

    element.Descendants<Text>().First().Text = text;
    element.Descendants<Text>().Skip(1).ToList().ForEach(t => t.Remove());

    return doc;
}

It simply looks for the first contentcontrol in the document with a specific Tag (you can set that by enabling designer mode in word and right-clicking on the content control), and replaces the current text with the text passed into the method. 它只是使用特定Tag查找文档中的第一个contentcontrol(您可以通过在单词中启用设计器模式并右键单击内容控件来设置它),并使用传递给方法的文本替换当前文本。 After this the document will still contain the content controls of course which may not be desired. 在此之后,文档仍将包含当然可能不需要的内容控件。 So when I'm done editing the document I run the following method to get rid of the content controls: 因此,当我完成编辑文档时,我运行以下方法来摆脱内容控件:

internal static WordprocessingDocument RemoveSdtBlocks(this WordprocessingDocument doc, IEnumerable<string> contentBlocks)
{
    List<SdtElement> SdtBlocks = doc.MainDocumentPart.Document.Descendants<SdtElement>().ToList();

    if (contentBlocks == null)
        return doc;

    foreach(var s in contentBlocks)
    {
        SdtElement currentElement = SdtBlocks.FirstOrDefault(sdt => sdt.SdtProperties.GetFirstChild<Tag>()?.Val == s);
        if (currentElement == null)
            continue;
        IEnumerable<OpenXmlElement> elements = null;

        if (currentElement is SdtBlock)
            elements = (currentElement as SdtBlock).SdtContentBlock.Elements();
        else if (currentElement is SdtCell)
            elements = (currentElement as SdtCell).SdtContentCell.Elements();
        else if (currentElement is SdtRun)
            elements = (currentElement as SdtRun).SdtContentRun.Elements();

        foreach (var el in elements)
            currentElement.InsertBeforeSelf(el.CloneNode(true));
        currentElement.Remove();
    }
    return doc;
}

To open the WordProcessingDocument from a template and edit it, there is plenty of information available online. 要从模板打开WordProcessingDocument并对其进行编辑,可以在线获得大量信息。

Edit: 编辑:

Little sample code to open/save documents while working with them in a memorystream, of course you should take care of this with an extra repository class that takes care of managing the document in the real code: 在内存流中使用它们时打开/保存文档的示例代码很少,当然您应该使用额外的存储库类来处理这个问题,该类负责管理实际代码中的文档:

byte[] byteArray = File.ReadAllBytes(@"C:\...\Template.dotx");

using (var stream = new MemoryStream())
{
    stream.Write(byteArray, 0, byteArray.Length);

    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
    {
       //Needed because I'm working with template dotx file, 
       //remove this if the template is a normal docx. 
        doc.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
        doc.InsertText("contentControlName","testtesttesttest");
    }
    using (FileStream fs = new FileStream(@"C:\...\newFile.docx", FileMode.Create))
    {
       stream.WriteTo(fs);
    }
}

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

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