Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在循环上创建MS Word内容控件_C#_Vba_Ms Word_Openxml_Docx - Fatal编程技术网

C# 在循环上创建MS Word内容控件

C# 在循环上创建MS Word内容控件,c#,vba,ms-word,openxml,docx,C#,Vba,Ms Word,Openxml,Docx,我是一名经验丰富的C#开发人员,在项目的这一特定阶段,我遇到了困难,开始着手文档生成(团队中没有人有这方面的特殊经验) 对于Word输出,到目前为止,我一直在使用文档中嵌入的内容控件和DocumentFormat.OpenXml包中的一些方法来创建可以在代码中识别的字段,并用适当的数据动态替换。因此,我加载了一个模板,并通过如下内容控件进行循环: string template = serverRoot + @"Templates\MyTemplate.docx"; string path =

我是一名经验丰富的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
        }
    }
}
string template=serverRoot+@“Templates\MyTemplate.docx”;
字符串路径=serverRoot+@“DataOut\\”+clientName+“\\MyDocument.docx”;
复制(模板、路径、true);
使用(WordprocessingDocument newDoc=WordprocessingDocument.Open(path,true))
{
MainDocumentPart mainPart=newDoc.MainDocumentPart;
var占位符=mainPart.Document.Body.subjects();
foreach(占位符中的变量sdtRun)
{
WriteLine(“找到的字段:+sdtRun.SdtProperties.GetFirstChild().Val.Value”);
开关(sdtRun.SdtProperties.GetFirstChild().Val.Value)
{
//检查内容控制值并替换它们
}
}
}
但是,我的下一个文档需要不确定数量的重复元素,这取决于具体情况。或者换一种方式,对于包中的每个文件,它需要将如下内容输出到文档中:

Filename: <insert filename>
Quantity: <insert quantity>
Date:     <insert date>
文件名:
数量:
日期:
但我们事先不知道会有多少文件

好吧,我不能用标准的内容控件来实现这一点,至少不能保留任何合理的格式


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

Word的最新版本确实支持重复内容控件;看


或者,您可以创建自己的“重复”控件。我的建议是这样做的一种方式。您可以在Word 2007和更高版本中使用这些。您可以使用docx4j(Java)或。要使用合适的内容控件设置docx,您需要。

我最终摆脱了懦夫的做法,使用了一个内容控件,在其中添加了一个在循环中构建的详细运行对象:

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

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