how can I put a content in a mergefield in docx

后端 未结 3 697
被撕碎了的回忆
被撕碎了的回忆 2021-01-13 15:18

I\'m developing a web application with asp.net and I have a file called Template.docx that works like a template to generate other reports. Inside this Template.docx I have

3条回答
  •  生来不讨喜
    2021-01-13 16:09

    I know this is an old post, but I could not get the accepted answer to work for me. The project linked would not even compile (which someone has already commented in that link). Also, it seems to use other Nuget packages like WPFToolkit.

    So I'm adding my answer here in case someone finds it useful. This only uses the OpenXML SDK 2.5 and also the WindowsBase v4. This works on MS Word 2010 and later.

    string sourceFile = @"C:\Template.docx";
    string targetFile = @"C:\Result.docx";
    File.Copy(sourceFile, targetFile, true);
    using (WordprocessingDocument document = WordprocessingDocument.Open(targetFile, true))
    {
        // If your sourceFile is a different type (e.g., .DOTX), you will need to change the target type like so:
        document.ChangeDocumentType(WordprocessingDocumentType.Document);
    
        // Get the MainPart of the document
        MainDocumentPart mainPart = document.MainDocumentPart;
        var mergeFields = mainPart.RootElement.Descendants();
    
        var mergeFieldName = "SenderFullName";
        var replacementText = "John Smith";
    
        ReplaceMergeFieldWithText(mergeFields, mergeFieldName, replacementText);                   
    
        // Save the document
        mainPart.Document.Save();
    
    }
    
    
    private void ReplaceMergeFieldWithText(IEnumerable fields, string mergeFieldName, string replacementText)
    {
        var field = fields
            .Where(f => f.InnerText.Contains(mergeFieldName))
            .FirstOrDefault();
    
        if (field != null)
        {
            // Get the Run that contains our FieldCode
            // Then get the parent container of this Run
            Run rFldCode = (Run)field.Parent; 
    
            // Get the three (3) other Runs that make up our merge field
            Run rBegin = rFldCode.PreviousSibling();
            Run rSep = rFldCode.NextSibling();
            Run rText = rSep.NextSibling();
            Run rEnd = rText.NextSibling();
    
            // Get the Run that holds the Text element for our merge field
            // Get the Text element and replace the text content 
            Text t = rText.GetFirstChild();
            t.Text = replacementText;
    
            // Remove all the four (4) Runs for our merge field
            rFldCode.Remove();
            rBegin.Remove();
            rSep.Remove();
            rEnd.Remove();
        }
    
    }
    

    What the code above does is basically this:

    • Identify the 4 Runs that make up the merge field named "SenderFullName".
    • Identify the Run that contains the Text element for our merge field.
    • Remove the 4 Runs.
    • Update the text property of the Text element for our merge field.

    UPDATE

    For anyone interested, here is a simple static class I used to help me with replacing merge fields.

提交回复
热议问题