2011-11-09 10 views
6

Attualmente sto utilizzando la libreria "DocX" per generare documenti Word (2007+) da .Net. Ciò che è buono è che può utilizzare il modello "docx" per ricreare o aggiornare un documento.Aggiungere una CustomProperty esistente non aggiorna il documento

Problema: Quando io "AddCustomProperty (...)" non aggiorna il documento word. In realtà ho bisogno di aprirlo e quindi selezionare tutto e premere F9. Mi chiedevo se ci fosse un modo per aggiornare automaticamente le "proprietà personalizzate" usando la libreria DocX.

a riprodurre il mio problema è possibile effettuare le seguenti operazioni:

  1. Aprire il "campione" a disposizione per il progetto DOCX.
  2. Esegui una volta (si creerà file nelle debug \ docs)
  3. aprire il modello fattura e quindi aggiungere una riga (con o senza testo) e salvare il file
  4. Eseguire nuovamente il progetto stesso campione (utilizzerà il modello esistente)
  5. Aprire il risultato della fattura. Quando lo fa, si può vedere che la tabella sono stati creati, MA, tutti gli altri campi non sono stati aggiornati fino a selezionare tutto e poi spingere CTRL + F9

Se qualcuno ha una soluzione, ho gradirei volentieri a riguardo.

(Nota: io non voglio che l'interoperabilità di MS Word)

progetti ed esempi sono disponibili presso: http://docx.codeplex.com/

risposta

3

Il problema è quando si usa MS Word (io uso la versione 2010) e quindi modifichiamo il modello e lo salviamo. Cambia ciò che il documento contiene.

Ecco quello che abbiamo quando abbiamo generare il modello utilizzando 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> 

E quando abbiamo Modifica con Word (aggiungere una linea di rottura o di una parte di testo) e noi salvarlo, è riscrivere il fldSimple a qualcosa così:

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

Invece di aspettare qualcuno per risolvere il problema, ho semplicemente cercato di fare una prima bozza di attuazione. Ho effettivamente modificato il metodo UpdateCustomPropertyValue (...). In realtà ho aggiunto il codice del primo foreach. Il secondo foreach era già lì e si applica al documento creato da 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)); 
       } 
      } 
} 
Problemi correlati