2011-11-09 29 views
6

我实际上使用库“DocX”从.Net生成Word文档(2007+)。好的是,它可以使用“docx”模板来重新创建或更新文档。添加现有的CustomProperty不更新文档

问题:当我 “AddCustomProperty(...)” 它不更新word文档。我实际上需要打开它,然后选择全部并按F9。我想知道是否有方法使用DocX库自动更新“自定义属性”。

要重现我的问题,你可以做以下步骤:

  1. 打开“样品”关于DOCX项目中可用。
  2. 运行一次(它会创建在调试\文档文件)
  3. 开的发票模板,然后添加一行(有或无文本),并保存文件
  4. 重新运行相同的样本项目(它将使用现有的模板)
  5. 打开发票结果。当你这样做,你可以看到,该表已被创建,但,其他所有领域,直到您选择所有尚未更新,然后按CTRL + F9

如果任何人有一个解决方案,我很乐意听到它。

(注:我不希望MS Word中互操作)

项目和样品,请访问:http://docx.codeplex.com/

回答

3

问题是,当我们用微软Word(我用的是2010年版)然后我们修改模板并保存。它改变了文档包含的内容。

下面是我们所拥有的,当我们使用DOCX第一生成模板:

<w:fldSimple w:instr="DOCPROPERTY company_name \* MERGEFORMAT" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
    <w:r> 
    <w:t> 
     <w:rPr> 
     <w:b /> 
     <w:sz w:val="24" /> 
     <w:szCs w:val="24" /> 
     <w:color w:val="1F497D" /> 
     </w:rPr>Company Name</w:t> 
    </w:r> 
</w:fldSimple> 

当我们使用Word编辑(添加一个分界线,或一些文本),我们救它,它改写fldSimple的东西像这样:

<w:p w:rsidR="006D64DE" w:rsidRDefault="006B25B1"> 
     <w:r> 
      <w:fldChar w:fldCharType="begin" /> 
     </w:r> 
     <w:r> 
      <w:instrText>DOCPROPERTY company_name \* MERGEFORMAT</w:instrText> 
     </w:r> 
     <w:r> 
      <w:fldChar w:fldCharType="separate" /> 
     </w:r> 
     <w:r> 
     <w:rPr> 
      <w:b /> 
      <w:color w:val="1F497D" /> 
      <w:sz w:val="24" /> 
     <w:szCs w:val="24" /> 
    </w:rPr> 
    <w:t>Company Name</w:t> 
    </w:r> 
    ... 
    <w:r> 
    <w:rPr> 
     <w:b /> 
     <w:color w:val="1F497D" /> 
     <w:sz w:val="24" /> 
     <w:szCs w:val="24" /> 
    </w:rPr> 
    <w:fldChar w:fldCharType="end" /> 
    </w:r> 
</w:p> 

我没有等待别人来解决这个问题,我只是试着做一个初稿的实施。我实际上修改了UpdateCustomPropertyValue(...)方法。我其实添加了第一个foreach的代码。第二个foreach已经存在,它适用于从DocX创建的文档。

internal static void UpdateCustomPropertyValue(DocX document, string customPropertyName, string customPropertyValue) 
     { 
      foreach (XElement e in document.mainDoc.Descendants(XName.Get("instrText", w.NamespaceName))) 
      { 
       string attr_value = e.Value.Replace(" ", string.Empty).Trim(); 
       string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", customPropertyName).Replace(" ", string.Empty); 

       if (attr_value.Equals(match_value, StringComparison.CurrentCultureIgnoreCase)) 
       { 
        XNode node = e.Parent.NextNode; 
        bool found = false; 
        while (true) 
        { 
         if (node.NodeType == XmlNodeType.Element) 
         { 
          var ele = node as XElement; 
          var match = ele.Descendants(XName.Get("t", w.NamespaceName)); 
          if (match.Count() > 0) 
          { 
           if (!found) 
           { 
            match.First().Value = customPropertyValue; 
            found = true; 
           } 
           else 
           { 
            ele.RemoveNodes(); 
           } 
          } 
          else 
          { 
           match = ele.Descendants(XName.Get("fldChar", w.NamespaceName)); 
           if (match.Count() > 0) 
           { 
            var endMatch = match.First().Attribute(XName.Get("fldCharType", w.NamespaceName)); 
            if (endMatch != null && endMatch.Value == "end") 
            { 
             break; 
            } 
           } 
          } 
         } 
         node = node.NextNode; 
        } 
       } 
      } 

      foreach (XElement e in document.mainDoc.Descendants(XName.Get("fldSimple", w.NamespaceName))) 
      { 
       string attr_value = e.Attribute(XName.Get("instr", w.NamespaceName)).Value.Replace(" ", string.Empty).Trim(); 
       string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", customPropertyName).Replace(" ", string.Empty); 

       if (attr_value.Equals(match_value, StringComparison.CurrentCultureIgnoreCase)) 
       { 
        XElement firstRun = e.Element(w + "r"); 
        XElement firstText = firstRun.Element(w + "t"); 
        XElement rPr = firstText.Element(w + "rPr"); 

        // Delete everything and insert updated text value 
        e.RemoveNodes(); 

        XElement t = new XElement(w + "t", rPr, customPropertyValue); 
        Novacode.Text.PreserveSpace(t); 
        e.Add(new XElement(firstRun.Name, firstRun.Attributes(), firstRun.Element(XName.Get("rPr", w.NamespaceName)), t)); 
       } 
      } 
} 
相关问题