2016-05-30 14 views
0

Ich versuche, mergemafields in Word-Datei mit meinen Daten zu ersetzen, die OpenXML verwenden.MergeField mit OpenXMl füllen

Ich denke, es gibt kein Problem im Code als manchmal funktioniert es gut in einigen Vorlagen und manchmal die Mergefields wird nicht ersetzt.

Gibt es ein Problem beim Einfügen Mergefields in Word-Vorlage? Ich weiß nicht, was das Problem ist.

Unten ist der Code, den ich verwenden:

public void Fill_Document_Fields(Dictionary<string, string> Fields, string FilePath) 
    { 
     try 
     { 
      using (WordprocessingDocument Doc = WordprocessingDocument.Open(FilePath, true)) 
      { 
       foreach (FieldCode field in Doc.MainDocumentPart.RootElement.Descendants<FieldCode>()) 
       { 
        string FieldName =string.Empty; 
        try 
        { 
         FieldName = field.Text.Trim().Split(' ')[2]; 
        } 
        catch 
        { 
         FieldName = field.Text.Trim(); 
        } 


        foreach (Run run in Doc.MainDocumentPart.Document.Descendants<Run>()) 
        { 
         foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + FieldName + "»")) 
         { 
          string itemValue; 
          if (Fields.TryGetValue(txtFromRun.Text, out itemValue)) 
          { 
           txtFromRun.Text = itemValue; 
          } 
         } 
        } 

       } 
      } 
     } 
     catch 
     { 
     } 
    } 

Antwort

0

Ihr Code funktioniert nur mit ‚SimpleField‘, Sie Code in der Tat überhaupt nicht richtig, weil man «Field» mit Ihrem eigenen Wert, der Wert zu ersetzen Ersetzen wird auch ein Mergefield sein.

Wenn Sie die xml hinter dem Dokument anschaut, kann man sehen, dass zu diesem ähnlich ist:

<w:fldSimple w:instr=" MERGEFIELD TestFoo \* MERGEFORMAT "> 
    <w:r w:rsidR="00C44AC1"> 
     <w:rPr> 
      <w:noProof /> 
     </w:rPr> 
     <w:t>«TestFoo»</w:t> 
    </w:r> 
</w:fldSimple> 

In diesem Moment Sie Element ersetzen 'w: t' («TestFoo») mit dem Wert (foo) und das Ergebnis ist so etwas wie:

<w:fldSimple w:instr=" MERGEFIELD TestFoo \* MERGEFORMAT "> 
    <w:r w:rsidR="00C44AC1"> 
     <w:rPr> 
      <w:noProof /> 
     </w:rPr> 
     <w:t>Foo</w:t> 
    </w:r> 
</w:fldSimple> 

wie Sie sehen können, ist Ihr Wert noch innerhalb des mergefield Element.

In diesem Fall (SimpleField) müssen Sie das Element 'fldSimple' finden und das Attribut 'instr' mit einem Regex lesen, um den Mergefield-Wert zu extrahieren. Wenn Sie mergefield durch Ihren Wert ersetzen möchten, müssen Sie das fldSimple-Element durch das Textelement im run-Element ersetzen.

Die zweite Implementierung von Mergefield ist der FieldChar.

<w:r> 
    <w:fldChar w:fldCharType="begin" /> 
</w:r> 
<w:r> 
    <w:instrText xml:space="preserve"> MERGEFIELD TestFoo \* MERGEFORMAT </w:instrText> 
</w:r> 
<w:r> 
    <w:fldChar w:fldCharType="separate" /> 
</w:r> 
<w:r w:rsidR="00FA6E12"> 
    <w:rPr> 
    <w:noProof /> 
    </w:rPr> 
    <w:t>«TestFoo»</w:t> 
</w:r> 
<w:r> 
    <w:rPr> 
    <w:noProof /> 
    </w:rPr> 
    <w:fldChar w:fldCharType="end" /> 
</w:r> 

In diesem Fall Sie fldChar Element mit fldCharType attr gleich beginnen finden müssen, müssen Sie alle Knoten durchlaufen, bis Sie fldCharType attr Wert gleich Ende finden.

Zwischen den Werten 'begin' und 'end' müssen Sie den Wert in instrText Element finden und lesen.

Wenn Sie Ihren Wert ersetzen möchten, müssen Sie alle Elemente, die zwischen den Werten 'begin' und 'end' gefunden werden, durch das Textelement im run-Element ersetzen.

Ich denke, dass mit doxx mergemfield als FieldChar geschrieben und mit Dotx als SimpleField geschrieben werden.

Jetzt kann ich kein Beispiel Code schreiben, ich hoffe, dass ich Ihnen geholfen habe.

Entschuldigung für mein Englisch, Bye