2011-11-09 28 views
6

Używam biblioteki "DocX" do generowania dokumentu Word (2007+) z .Net. Dobrze, że może użyć szablonu "docx" do odtworzenia lub aktualizacji dokumentu.Dodawanie istniejącej CustomProperty nie aktualizuje dokumentu

Problem: Kiedy "AddCustomProperty (...)" to nie aktualizuje dokumentu tekstowego. Muszę go otworzyć, a następnie wybrać wszystkie i wcisnąć F9. Zastanawiam się, czy istnieje sposób automatycznej aktualizacji "właściwości niestandardowych" przy użyciu biblioteki DocX.

Aby odtworzyć mój problem można wykonać następujące kroki:

  1. Otwórz „próbka” dostępne na stronie projektu DOCX.
  2. uruchomić go raz (będzie tworzyć pliki w debug \ Docs)
  3. otworzyć szablon faktury, a następnie dodaj linię (z lub bez tekstu) i zapisz plik
  4. ponownie uruchomić projekt samej próbki (będzie używać istniejącego szablonu)
  5. Otwórz wynik faktury. Gdy to zrobisz, możesz zobaczyć, że tabela została utworzona, BUT, wszystkie pozostałe pola nie zostały zaktualizowane do momentu wybrania wszystkich, a następnie wcisnąć CTRL + F9

Jeśli ktoś ma rozwiązanie, ja chętnie zechce to sprawdzić.

(Uwaga: Nie chcę się współdziałanie MS Word)

Projekt i próbki są dostępne na stronie: http://docx.codeplex.com/

Odpowiedz

3

Problem jest wtedy, gdy używamy MS Word (używam wersji 2010) a następnie modyfikujemy szablon i zapisujemy go. Zmienia to, co zawiera dokument.

Oto, co mamy, kiedy najpierw wygenerować szablon używając 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> 

A kiedy edytować Word (dodać linię przerwania lub tekst), a my go uratować, to przepisać fldSimple do czegoś w ten sposób:

<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> 

Zamiast czekać na kogoś, kto naprawi problem, po prostu próbowałem zrobić pierwszy projekt wdrożenia. Właściwie zmodyfikowałem metodę UpdateCustomPropertyValue (...). Właściwie dodałem kod pierwszego foreach. Drugi foreach już tam był i dotyczy dokumentu utworzonego z 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)); 
       } 
      } 
} 
Powiązane problemy