OpenXML用结果值替换字段代码

时间:2016-10-27 18:21:54

标签: text replace static field openxml

我尝试使用OpenXML迭代位于供应商生成的文档的页眉和页脚中的字段,以便用存储在字段中的结果值替换它们,然后删除该字段。以下是来自页脚的代码,仅用于几个字段中的一个(在此之后想象4或5个)。由于将此作为SSIS脚本任务的一部分运行,我仅限于.Net 3.5框架和OpenXML SDK 2.0。

    <w:r>
        <w:rPr>
            <w:rFonts w:ascii="Segoe UI" w:hAnsi="Segoe UI" w:eastAsia="Segoe UI"/>
            <w:sz w:val="20"/>
        </w:rPr>
        <w:fldChar w:fldCharType="begin"/>
    </w:r>
    <w:r>
        <w:rPr>
            <w:rFonts w:ascii="Segoe UI" w:hAnsi="Segoe UI" w:eastAsia="Segoe UI"/>
            <w:sz w:val="20"/>
        </w:rPr>
        <w:instrText xml:space="preserve"> REF NG_MACRO "STANDARD" "patient_lname" </w:instrText>
    </w:r>
    <w:r>
        <w:rPr>
            <w:rFonts w:ascii="Segoe UI" w:hAnsi="Segoe UI" w:eastAsia="Segoe UI"/>
            <w:sz w:val="20"/>
        </w:rPr>
        <w:fldChar w:fldCharType="separate"/>
    </w:r>
    <w:r>
        <w:rPr>
            <w:rFonts w:ascii="Segoe UI" w:hAnsi="Segoe UI" w:eastAsia="Segoe UI"/>
            <w:sz w:val="20"/>
        </w:rPr>
        <w:t xml:space="preserve">Test</w:t>
    </w:r>

我尝试了过去3周研究中发现的多种方法,但所有方法似乎都失败了或只影响了第一个领域,而不是其他领域。

以下是我尝试做的最好的一个例子,但同样,它只找到了第一个字段并忽略了其余部分。注意:这些供应商字段之后有一组页码编号字段,类似于/我不想更改。

        using (WordprocessingDocument document = WordprocessingDocument.Open("Plan.doc", true))
        {
            MainDocumentPart main = document.MainDocumentPart;

            foreach (FooterPart foot in main.FooterParts)
            {
                foreach(var fld in foot.RootElement.Descendants<FieldCode>())
                {
                    if (fld != null && fld.InnerText.Contains("REF NG_MACRO"))
                    {
                        Run rFldCode = (Run)fld.Parent;

                        // Get the three (3) other Runs that make up our merge field
                        Run rBegin = rFldCode.PreviousSibling<Run>();
                        Run rSep = rFldCode.NextSibling<Run>();
                        Run rText = rSep.NextSibling<Run>();
                        Run rEnd = rText.NextSibling<Run>();

                        // Get the Run that holds the Text element for our merge field
                        // Get the Text element and replace the text content 
                        Text t = rText.GetFirstChild<Text>();
                        //t.Text = replacementText;

                        // Remove all the four (4) Runs for our merge field
                        rFldCode.Remove();
                        rBegin.Remove();
                        rSep.Remove();
                        rEnd.Remove();
                    }
                }

                foot.Footer.Save();
            }
            document.MainDocumentPart.Document.Save();
            document.Close();
        }

我感谢任何人可以提供的关于我所缺少的任何见解和想法,以及使用OpenXML实现这一目标的更好方法等。

2 个答案:

答案 0 :(得分:1)

试试这个。它对我有用。

using (WordprocessingDocument wordDocument = WordprocessingDocument.Open("Plan.doc", true))
 {

    if (null != wordDocument)
        {

            const string FieldDelimeter = @" MERGEFIELD ";
            List<string> listeChamps = new List<string>();

            foreach (FooterPart footer in wordDocument.MainDocumentPart.FooterParts)
            {

                foreach(var field in footer.RootElement.Descendants<FieldCode>())
                {

                    int fieldNameStart = field.Text.LastIndexOf(FieldDelimeter, System.StringComparison.Ordinal);

                    if (fieldNameStart >= 0)
                    {
                        var fieldName = field.Text.Substring(fieldNameStart + FieldDelimeter.Length).Trim();

                        Run xxxfield = (Run)field.Parent;

                        Run rBegin = xxxfield.PreviousSibling<Run>();
                        Run rSep = xxxfield.NextSibling<Run>();
                        Run rText = rSep.NextSibling<Run>();
                        Run rEnd = rText.NextSibling<Run>();

                        if (null != xxxfield)
                        {

                            Text t = rText.GetFirstChild<Text>();
                            t.Text = replacementText;

                        }
                    }

                }


            }
        }
 } 

答案 1 :(得分:0)

要获取文档,页眉和页脚FieldCode,然后替换文本,您应该分两个步骤进行操作:

  • 获取所有合并字段
  • 对每个字段执行替换文本

以下是获取所有FieldCode的方法:

public IEnumerable<FieldCode> GetMergeFields(WordprocessingDocument doc)
{
    var mergeFields = new List<FieldCode>();

    if (doc == null) return mergeFields;

    mergeFields.AddRange(doc.MainDocumentPart.RootElement.Descendants<FieldCode>());

    foreach (var header in doc.MainDocumentPart.HeaderParts)
    {
        mergeFields.AddRange(header.RootElement.Descendants<FieldCode>());
    }

    foreach (var footer in doc.MainDocumentPart.FooterParts)
    {
        mergeFields.AddRange(footer.RootElement.Descendants<FieldCode>());
    }

    return mergeFields;
}