【问题标题】:Creating MS Word Content Controls on a loop在循环上创建 MS Word 内容控件
【发布时间】:2014-04-29 00:15:06
【问题描述】:

我是一位经验丰富的 C# 开发人员,他在项目的这个特定阶段吸了一口气,并开始着手生成文档(团队中没有人对此有任何特殊经验)。

到目前为止,对于 Word 输出,我一直在使用嵌入在文档中的内容控件和 DocumentFormat.OpenXml 包中的一些方法来创建我可以在代码中识别并动态替换为适当数据的字段。所以我加载了一个模板,并像这样遍历内容控件:

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

但是,我的下一个文档根据情况需要不定数量的重复元素。或者换一种说法,对于包中的每个文件,它都需要将这样的内容输出到文档中:

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

但我们事先不知道会有多少文件。

AFAIK 我不能用标准的内容控件来做到这一点,至少在保留任何合理的格式的同时不能。

这里最好的方法是什么。我是否应该将整个文本生成为一个块,添加换行符等,并将其全部填充到一个内容控件中?即时创建新的内容控件(如果是,如何创建)?还是有更好的办法?

【问题讨论】:

  • 为什么不根据需要添加内容控件?

标签: c# vba ms-word openxml docx


【解决方案1】:

我最终摆脱了这个懦夫的方式,并使用了一个内容控件,我在其中添加了一个在循环中构建的详细 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;
}

【讨论】:

    【解决方案2】:

    最新版本的 Word 确实支持重复内容控件;见https://stackoverflow.com/a/20676863/1031689

    或者,您可以创建自己的“重复”控件。我的OpenDoPE convention 是这样做的一种方式。您可以在 Word 2007 及更高版本中使用它们。您可以使用 docx4j (Java) 或 docx4j.NET 处理它们。要使用合适的内容控件设置 docx,您需要 authoring addin

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多