Replace String with merge field in .doc

Hello,

I want to be able to replace string with merge field in .doc .
i came across following code . Is there a way to replace “abc” with mergefield instead?
FindReplaceOptions options = new FindReplaceOptions();
doc.getRange().replace(Pattern.compile("<<s.cr.d.adr>>"), “abc”, options);

Also i tried inserting a merge field in the .doc using following code from one of your examples .
But i just gets inserted as normal text . Please check the attachement output.JPG (18.6 KB)

public static void insertMF() throws Exception {
Document doc = new Document(“corp-gv-anmeldung-2019-210x.297-en_EDITED.doc”);
DocumentBuilder builder = new DocumentBuilder(doc);

  FieldMergeField field = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, false);

  field.setFieldName("Test1");
  field.isMapped(true);

  // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" }
  field.isVerticalFormatting(true);

  field.update();

  doc.save("output.doc");

}

@pratham.mittal

In this case, you need to implement IReplacingCallback interface. In IReplacingCallback.Replacing method, move the cursor to the matched node and insert field using DocumentBuilder.insertField method. Please check the code example shared in the following article.
How to Find and Highlight Text

Please ZIP and attach your input Word document here for testing. We will investigate the issue on our side and provide you more information.

ExtractPDF.zip (5.4 MB)

I tried the example from the link you have provided but din’t understand how exactly merge field will be added.
Please check method :replaceMF() from class insertMergeField in the attached ZIP
replaceMF() should replace string <<s.cr.d.adr>> with merge field <<s.cr.d.adr>>

Currently string <<s.cr.d.adr>> is replaced with no value.
Both input and output .doc are available in the zip .
Also i have noticed that the format, checkbox, font have changed in the output file replaceOutput.doc
Which should have remained same.

Also check method insertMF() in class insertMergeField which should insert a merge field in the the file. But instead it inserts just a string.

@pratham.mittal

Please use the following code example to replace the desired text with mail merge field. Hope this helps you.

public  void testcase() throws Exception
{
    Document doc = new Document(MyDir + "corp-gv-anmeldung-2019-210x.297-en_EDITED.doc");

    Document document = new Document(MyDir + "border.docx");
    FindReplaceOptions options = new FindReplaceOptions();
    options.setReplacingCallback(new ReplaceEvaluatorFindAndInsertMergefield());
    options.setDirection(FindReplaceDirection.BACKWARD);

    // We want the "your document" phrase to be highlighted.
    Pattern regex = Pattern.compile("<<.*?>>", Pattern.CASE_INSENSITIVE);
    doc.getRange().replace(regex, "", options);

    doc.save(MyDir + "out.java.docx");

}

class ReplaceEvaluatorFindAndInsertMergefield  implements IReplacingCallback {
    DocumentBuilder builder;
    public int replacing(ReplacingArgs e) throws Exception {
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.getMatchNode();

        if(builder == null)
            builder = new DocumentBuilder((Document) currentNode.getDocument());
        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.getMatchOffset() > 0)
            currentNode = splitRun((Run) currentNode, e.getMatchOffset());

        // This array is used to store all nodes of the match for further highlighting.
        ArrayList runs = new ArrayList();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.getMatch().group().length();
        while ((remainingLength > 0) && (currentNode != null) && (currentNode.getText().length() <= remainingLength)) {
            runs.add(currentNode);
            remainingLength = remainingLength - currentNode.getText().length();

            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do {
                currentNode = currentNode.getNextSibling();
            } while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
        }

        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0)) {
            splitRun((Run) currentNode, remainingLength);
            runs.add(currentNode);
        }

        String text = "";
        for (Run run : (Iterable<Run>) runs){
            text += run.getText();
        }

        text = text.replace("<<", "").replace(">>", "");
        builder.moveTo((Run)runs.get(0));
        builder.insertField("MERGEFIELD "+text+" \\* MERGEFORMAT");
        for (Run run : (Iterable<Run>) runs){
            run.remove();
        }
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;
    }

    /**
     * Splits text of the specified run into two runs. Inserts the new run just
     * after the specified run.
     */
    private Run splitRun(Run run, int position) throws Exception {
        Run afterRun = (Run) run.deepClone(true);
        afterRun.setText(run.getText().substring(position));
        //run.setText(run.getText().substring((0), (0) + (position)));
        run.setText(run.getText().substring(0, position));
        run.getParentNode().insertAfter(afterRun, run);
        return afterRun;
    }
}