在循环中创建MS Word内容控件
本文关键字:控件 Word MS 循环 创建 | 更新日期: 2023-09-27 17:59:38
我是一名经验丰富的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我不能用标准的内容控件来做到这一点,至少在保留任何合理格式的情况下都不能。
这里最好的方法是什么。我是否应该将整个文本生成为一个块,添加换行符等,并将其全部填充到一个内容控件中?动态创建新的内容控件(如果是,如何创建)?或者有更好的方法吗?
我最终摆脱了这一困境,并使用了一个内容控件,在该控件中添加了一个在循环中构建的详细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;
}
Word的最新版本确实支持重复内容控件;看见https://stackoverflow.com/a/20676863/1031689
或者,您可以创建自己的"重复"控件。我的OpenDoPE约定就是这样做的一种方式。您可以在Word 2007及更高版本中使用这些功能。您可以使用docx4j(Java)或docx4j.NET来处理它们。要设置具有适当内容控件的docx,您需要创作插件。