简体   繁体   English

在循环中创建 MS Word 内容控件

[英]Creating MS Word Content Controls on a loop

I'm an experienced C# developer who drew the short straw on this particular phase of the project and got to work on document generation (no-one on the team has any particular experience with this).我是一位经验丰富的 C# 开发人员,他在项目的这个特定阶段画了一根短稻草,并开始致力于文档生成(团队中没有人对此有任何特殊经验)。

For Word output, so far, I've been using Content Controls embedded in documents and some of the methods in the DocumentFormat.OpenXml package to create fields I can identify in code and dynamically replace with the appropriate data.对于 Word 输出,到目前为止,我一直在使用嵌入在文档中的内容控件和 DocumentFormat.OpenXml 包中的一些方法来创建我可以在代码中识别并用适当的数据动态替换的字段。 So I load a template, and loop through the content controls like this:所以我加载了一个模板,并像这样循环遍历内容控件:

string template = serverRoot + @"Templates\MyTemplate.docx";
string path = serverRoot + @"DataOut\\" + clientName + "\\MyDocument.docx";
File.Copy(template, path, true);

using (WordprocessingDocument newDoc = WordprocessingDocument.Open(path, true))
{
    MainDocumentPart mainPart = newDoc.MainDocumentPart;
    var placeHolders = mainPart.Document.Body.Descendants<SdtElement>();

    foreach (var sdtRun in placeHolders)
    {
        Console.WriteLine("Found Field: " + sdtRun.SdtProperties.GetFirstChild<Tag>().Val.Value);
        switch (sdtRun.SdtProperties.GetFirstChild<Tag>().Val.Value)
        {
            //check the content control values and replace them
        }
    }
}

However, my next document requires an indeterminate number of repeat elements depending on the situation.但是,我的下一个文档根据情况需要不确定数量的重复元素。 Or to put it another way, for each file in the package it need to output something like this into the doc:或者换句话说,对于包中的每个文件,它需要将这样的内容输出到文档中:

Filename: <insert filename>
Quantity: <insert quantity>
Date:     <insert date>

But we don't know in advance how many files there will be.但是我们事先不知道会有多少文件。

AFAIK I can't do this with a standard content control, at least not while retaining any kind of sensible formatting. AFAIK 我不能用标准的内容控件来做到这一点,至少在保留任何类型的合理格式时不能。

What's the best approach here.这里最好的方法是什么。 Should I generate the whole text as a block, adding in line breaks and such, and stuff it all into one Content Control?我应该将整个文本生成为一个块,添加换行符等,然后将其全部放入一个内容控件中吗? Create new Content Controls on the fly (and if so, how)?动态创建新的内容控件(如果是,如何创建)? Or is there a better way?或者,还有更好的方法?

I took the coward's way out of this one in the end, and used one content control to which I added a detailed Run object built up inside a loop:我最终摆脱了这个懦夫的方式,并使用了一个内容控件,我在其中添加了一个在循环内构建的详细 Run 对象:

private Run ParseForOpenXML(string textualData)
{
    Run run = new Run();

    //split string on paragraph breaks, and create a Break object for each
    string[] newLineArray = { Environment.NewLine, "\n" };
    string[] textArray = textualData.Split(newLineArray, StringSplitOptions.None);
    bool first = true;

    foreach (string line in textArray)
    {
        if (!first)
        {
            run.Append(new Break());
        }
        first = false;

        //split string on tab breaks, and create a new TabChar object for each
        bool tFirst = true;
        string[] tabArray = line.Split('\t');
        foreach(string fragment in tabArray)
        {
            if (!tFirst)
            {
                run.Append(new TabChar());
            }
            tFirst = false;

            Text txt = new Text();
            txt.Text = fragment;
            run.Append(txt);
        }
    }

    return run;
}

Recent versions of Word do support a repeat content control;最新版本的 Word 支持重复内容控制; see https://stackoverflow.com/a/20676863/1031689https://stackoverflow.com/a/20676863/1031689

Alternatively, you can create your own "repeat" control.或者,您可以创建自己的“重复”控件。 My OpenDoPE convention is one way of doing this.我的OpenDoPE 约定就是这样做的一种方式。 You can use these in Word 2007 and later.您可以在 Word 2007 及更高版本中使用这些。 You can process them using docx4j (Java), or, docx4j.NET .您可以使用 docx4j (Java) 或docx4j.NET处理它们。 To set up a docx with suitable content controls, you'll need the authoring addin .要使用合适的内容控件设置 docx,您需要 创作插件

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

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