2011-11-09 9 views
6

実際にライブラリ "DocX"を使用して、.NetからWord文書(2007+)を生成しています。良いことは、 "docx"テンプレートを使用してドキュメントを再作成または更新できることです。既存のカスタムプロパティを追加するとドキュメントが更新されません

問題:I "AddCustomProperty(...)は" それはWord文書を更新しません。私は実際にそれを開いてすべてを選択し、F9を押す必要があります。 DocXライブラリを使用して「カスタムプロパティ」を自動更新する方法があるかどうか疑問に思っていました。

  1. オープンDOCXプロジェクトで利用できる「サンプル」:

    は、次の手順を行うことができます私の問題を再現します。
  2. を実行し、ファイルを一度
  3. オープン請求書のテンプレート(これは、デバッグ\ドキュメント内のファイルを作成します)、その後(またはテキストなし)の行を追加し、保存し
  4. (同じサンプルプロジェクトを再実行します
  5. 請求書の結果を開きます。あなたがそうするとき、あなたは、テーブルが作成されていることをしかしを見ることができ、他のすべてのフィールドが更新されていない、あなたはすべて選択するまで、その後、誰もが解決策を持っている場合

CTRL + F9キーを押して、I喜んでそれについての耳に好きです。

(注:私はMS Wordの相互運用をしたくない)

プロジェクトとサンプルがで入手できます。私たちは(私は2010年バージョンを使用)MS Wordを使用するときに問題があるhttp://docx.codeplex.com/

答えて

3

テンプレートを修正して保存します。ドキュメントの内容を変更します。

は、ここでは、最初の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を追加しました。 2番目の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)); 
       } 
      } 
} 
関連する問題