簡體   English   中英

在循環中創建 MS Word 內容控件

[英]Creating MS Word Content Controls on a loop

我是一位經驗豐富的 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,您需要 創作插件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM