2011-11-09 30 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)); 
       } 
      } 
} 
相關問題