2016-05-30 124 views
0

我想用我的数据使用OpenXML替换word文件中的mergefields。使用OpenXMl填充MergeField

我认为在代码中没有问题,因为它有时在一些模板中工作正常,有时mergefields不会被替换。

在文字模板中插入Mergefields是否存在问题?我不知道是什么问题。

下面是我使用的代码:

public void Fill_Document_Fields(Dictionary<string, string> Fields, string FilePath) 
    { 
     try 
     { 
      using (WordprocessingDocument Doc = WordprocessingDocument.Open(FilePath, true)) 
      { 
       foreach (FieldCode field in Doc.MainDocumentPart.RootElement.Descendants<FieldCode>()) 
       { 
        string FieldName =string.Empty; 
        try 
        { 
         FieldName = field.Text.Trim().Split(' ')[2]; 
        } 
        catch 
        { 
         FieldName = field.Text.Trim(); 
        } 


        foreach (Run run in Doc.MainDocumentPart.Document.Descendants<Run>()) 
        { 
         foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + FieldName + "»")) 
         { 
          string itemValue; 
          if (Fields.TryGetValue(txtFromRun.Text, out itemValue)) 
          { 
           txtFromRun.Text = itemValue; 
          } 
         } 
        } 

       } 
      } 
     } 
     catch 
     { 
     } 
    } 

回答

0

你的代码只能与“SimpleField”,其实你的代码是不正确的,在所有的,因为你的自定义值,该值在更换«字段名»正在取代也将是一个mergefield。

如果查看XML文档的背后,可以看到类似这样的:你更换滤芯“W:T”

<w:fldSimple w:instr=" MERGEFIELD TestFoo \* MERGEFORMAT "> 
    <w:r w:rsidR="00C44AC1"> 
     <w:rPr> 
      <w:noProof /> 
     </w:rPr> 
     <w:t>«TestFoo»</w:t> 
    </w:r> 
</w:fldSimple> 

在这一刻与你的价值(«命名为testFoo»)( Foo),结果如下所示:

<w:fldSimple w:instr=" MERGEFIELD TestFoo \* MERGEFORMAT "> 
    <w:r w:rsidR="00C44AC1"> 
     <w:rPr> 
      <w:noProof /> 
     </w:rPr> 
     <w:t>Foo</w:t> 
    </w:r> 
</w:fldSimple> 

如您所见,您的值仍在mergefield元素中。

在这种情况下(SimpleField)你需要找到'fldSimple'元素,并且可以用正则表达式读取instr属性来提取mergefield值。 当你想用你的值替换mergefield时,你必须用run元素中的文本元素来替换fldSimple元素。

mergefield的第二个实现是FieldChar。

<w:r> 
    <w:fldChar w:fldCharType="begin" /> 
</w:r> 
<w:r> 
    <w:instrText xml:space="preserve"> MERGEFIELD TestFoo \* MERGEFORMAT </w:instrText> 
</w:r> 
<w:r> 
    <w:fldChar w:fldCharType="separate" /> 
</w:r> 
<w:r w:rsidR="00FA6E12"> 
    <w:rPr> 
    <w:noProof /> 
    </w:rPr> 
    <w:t>«TestFoo»</w:t> 
</w:r> 
<w:r> 
    <w:rPr> 
    <w:noProof /> 
    </w:rPr> 
    <w:fldChar w:fldCharType="end" /> 
</w:r> 

在这种情况下,你需要找到fldCharType ATTR等于fldChar元素开始,你,直到你找到fldCharType ATTR值等于结束遍历所有节点。

在“开始”和“结束”值之间,您需要查找和读取instrText元素中的值。

当您想要替换您的值时,您必须将'begin'和'end'值之间找到的所有元素替换为run元素中的文本元素。

我认为用docx mergefield写成FieldChar和用dotx写成SimpleField。

现在我不能写一个代码的例子,我希望我已经帮助你。

对不起,我的英语, 再见