Font formatting is lost after updating content control text using Java

Hi @tahir.manzoor
I am facing one problem when I replace contain control tag with value as string the contain control font is changed.
But my expected output is when i replace contain control tag with my value that time i need it can take font of contain control tag.
exm.
if my contain control tag font is “times new roman” then when I replace my value it will also be as “times new roman”
But now it takes some default font.

PFA
Test_new.zip (42.5 KB)

@rabinintig

Please use the following code example to get the desired output. Hope this helps you.

Document doc  = new Document(MyDir + "input.docx");

NodeCollection<StructuredDocumentTag> contentControlCollection = doc.getChildNodes( NodeType.STRUCTURED_DOCUMENT_TAG, true);
for (StructuredDocumentTag sdt : contentControlCollection)
{
    if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.BLOCK)
    {
        Paragraph para = (Paragraph) sdt.getFirstChild();
        para.getRuns().get(0).setText("New Text");
    }
}
doc.save(MyDir + "20.3.docx");

thanks @tahir.manzoor
But if my input file like this.
then it’s throw the exceptionnewTest.zip (13.8 KB)

code for MarkupLevel.INLINE

@rabinintig

In your case, you need to write the code according to content control type. We suggest you please read the following article. Hope this helps you.
Working with Content Control SDT

Please use the following code example. Hope this helps you.

Document doc  = new Document(MyDir + "newTest.docx");

NodeCollection<StructuredDocumentTag> contentControlCollection = doc.getChildNodes( NodeType.STRUCTURED_DOCUMENT_TAG, true);
for (StructuredDocumentTag sdt : contentControlCollection)
{
    if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.BLOCK)
    {
        Paragraph para = (Paragraph) sdt.getFirstChild();
        para.getRuns().get(0).setText("New Text");
    }
    if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.INLINE)
    {
        Run run = (Run) sdt.getFirstChild();
        run.setText("New Text of inline SDT");
    }
}
doc.save(MyDir + "20.3.docx");

@tahir.manzoor
above code throws exception
image.png (8.5 KB)
for input file newTest1.zip (13.9 KB)

@tahir.manzoor
Can u please help me to solve this problem.

@rabinintig

We suggest you please read about Aspose.Words’ DOM from here:
Aspose.Words Document Object Model

Please check the DOM image of your document. DOM.png (7.9 KB)
The first node of StructuredDocumentTag is BookmarkStart node. Please remove the bookmark as shown below to avoid the exception.

Document doc  = new Document(MyDir + "newTest1.docx");
doc.getRange().getBookmarks().get("_GoBack").remove();

Moreover, please check the code examples of Aspose.Words from Github repository.

@tahir.manzoor
Thanks for help.

hi @tahir.manzoor

I am facing another problem using this code.
Like,
if my contain control is blank then Run is returning null value

if (sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.INLINE)
{
Run newRun = (Run) sdt.getFirstChild(); // newRun returning null
newRun.setText(“New Text of inline SDT”);
}

I attached my input file.
PFAtest.zip (45.9 KB)

please help me to solve this issue.

hi @tahir.manzoor
sorry to say I am facing another problem to use this code
contain control value replace with old + new value
step to reproduce

  1. in .docx file I change AUTO12345 to AUTO11111
  2. same .docx file I use in code for replacing contain control
  3. when I replace contain control value with a new value (AUTO9999).
  4. it’s replaced with AUTO999911111 value

but my expacted output is it will replace with AUTO9999 value
PFA
test1.zip (35.8 KB)

@tahir.manzoor

previous code, before the font change problem i was using some code.it’s working fine for all the cases
for your reference i attached that code also.
please check if u change anything on this code then it will more batter for me.
previousCode.zip (787 Bytes)

@tahir.manzoor
can u please me to solve this problem.

@rabinintig

We are working over your query and will get back to you soon.

@tahir.manzoor
thanks

@tahir.manzoor
Any update on this issue.

@rabinintig

We suggest you please read the Aspose.Words document object model.

In your document, the content control has no children. So, you are getting the exception. You can avoid this exception using the following code example.

Document doc  = new Document(MyDir + "input.docx");

NodeCollection<StructuredDocumentTag> contentControlCollection = doc.getChildNodes( NodeType.STRUCTURED_DOCUMENT_TAG, true);
for (StructuredDocumentTag sdt : contentControlCollection)
{
    if(!sdt.hasChildNodes())
        continue;

    if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.BLOCK)
    {
        Paragraph para = (Paragraph) sdt.getFirstChild();
        para.getRuns().get(0).setText("Block Level text");
    }
    if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.INLINE)
    {
        Run run = (Run) sdt.getFirstChild();
        run.setText("inline SDT");
    }
}
doc.save(MyDir + "20.3.docx");

Please note that the content control has different level of markups and different types. You need to write the code according to SdtType and MarkupLevel.

@tahir.manzoor
sorry to say I am facing another problem to use this code
contain control value replace with old + new value
step to reproduce

  1. in .docx file I change AUTO12345 to AUTO11111
  2. same .docx file I use in code for replacing contain control
  3. when I replace contain control value with a new value (AUTO9999).
  4. it’s replaced with AUTO999911111 value

but my expacted output is it will replace with AUTO9999 value
PFA
test1.zip (35.8 KB)

contain control value replace with old + new value
step to reproduce

  1. in .docx file I change AUTO12345 to AUTO11111
  2. same .docx file I use in code for replacing contain control
  3. when I replace contain control value with a new value (AUTO9999).
  4. it’s replaced with AUTO999911111 value

but my expected output is it will replace with new value (AUTO9999)
Please give me a solution with the existing code.
PFA
test1.zip (35.8 KB)

@rabinintig

The StructuredDocumentTag is composite node type. It may contain multiple child nodes. You can use one of the following approach to replace the text of content control.

  • Use Range.Replace method to replace the text.
  • Remove all children nodes of StructuredDocumentTag except the first Run node to preserve the font formatting of text.

Please check the following code snippet. Hope this helps you.

else if(sdt.getSdtType() == SdtType.RICH_TEXT && sdt.getLevel() == MarkupLevel.INLINE)
{
    //sdt.getRange().replace("AUTO11111", "AUTO999", new FindReplaceOptions());
    //OR 
    Run run = (Run) sdt.getFirstChild().deepClone(true);
    sdt.removeAllChildren();
    run.setText("AUTO999");
    sdt.appendChild(run);
}

thanks @tahir.manzoor
The code is working fine as expected.
But I am facing only one problem.
The behavior of Contain control in “BLOCK” is expected but in “INLINE” is not expected.
In this case of “BLOCK” I can remove one by one character
But in this case of “INLINE” I can not remove one by one character ,in this case I have to remove whole data of Contain control then only i can add.
My expected behavior for INLINE is like BLOCK where I can remove one by one character from end and middle also.
PFA
Test2.zip (44.8 KB)