Hello Team,
I tried upgrading the Aspose Words jar from version 2018 to 2025. While using the same code with both versions, I am encountering an issue in the latest jar.
In the 2018 jar version, the output is correct (please see attached output file – *
Output_Aspose_18.docx (127.0 KB)
*). However, when I use the 2025 jar version, the output is different (please see attached output file – *
Output_Aspose_25.docx (126.9 KB)
*).
Both tests were run using the same input file, but the results differ. The issue is specifically with the Title sequence number when replacing the placeholder SOWPH_Cancellation
:
- With the 2018 jar, the Title sequence number is correctly shown as 5.
- With the 2025 jar, the Title sequence number incorrectly shows as 1.
Please find the input file here
1.
FPS_Template.docx (142.7 KB)
Clause_Cancel_EN.docx (18.7 KB)
Below is the code snippet I am using for both versions:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Locale;
import java.util.regex.Pattern;
import com.aspose.words.Document;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.FindReplaceOptions;
import com.aspose.words.IReplacingCallback;
import com.aspose.words.ImportFormatMode;
import com.aspose.words.License;
import com.aspose.words.Node;
import com.aspose.words.NodeType;
import com.aspose.words.ReplaceAction;
import com.aspose.words.ReplacingArgs;
import com.aspose.words.Run;
public class AsposeTest {
public static void main(String[] args) throws Exception {
System.out.println("Hello and completed!!!");
Document targetDoc = new Document("D:\\ACA33\\Aspose\\FPS_Template.docx");
Document clauseDoc = new Document("D:\\ACA33\\Aspose\\Clause_Cancel_EN.docx");
ReplacingCallback callback = new ReplacingCallback(clauseDoc);
FindReplaceOptions options1 = new FindReplaceOptions(callback);
options1.setMatchCase(true);
targetDoc.getRange().replace("SOWPH_Cancellation", "", options1);
targetDoc.save("D:\\ACA33\\Aspose\\Output_Aspose_18.docx", com.aspose.words.SaveFormat.DOCX);
System.out.println("Hello and completed finish!!!");
}
public static final String ASPOSE_LICENSE_FILE_PATH = "D:\\dsplm\\products\\3dexperience\\3dspace\\win_b64\\code\\tomee\\webapps\\3dspace\\WebClient\\Aspose.Words.lic";
public static void initAsposeLicense() throws Exception {
System.out.println("SOW_WordReplace_mxJPO: initAsposeLicense==============START");
System.out.println("SOW_WordReplace_mxJPO: initAsposeLicense==============ASPOSE_LICENSE_FILE_PATH="
+ ASPOSE_LICENSE_FILE_PATH);
InputStream license = new FileInputStream(ASPOSE_LICENSE_FILE_PATH);
if (license != null) {
License manager = new License();
try {
manager.setLicense(license);
System.out.println("SOW_WordReplace_mxJPO: initAsposeLicense=============setLicense=Done");
} catch (Exception e) {
System.out.println("SOW_WordReplace_mxJPO:initAsposeLicense==============Error:unable to load the license");
}
} else {
System.out.println(
"SOW_WordReplace_mxJPO:initAsposeLicense==============Error:no Aspose.Words.lic license found.");
}
System.out.println("SOW_WordReplace_mxJPO:initAsposeLicense==============END");
}
static {
Locale previous = Locale.getDefault();
Locale.setDefault(Locale.US);
try {
AsposeTest.initAsposeLicense();
} catch (Exception e) {
System.err.println(
"SOW_Util_mxJPO:Error: while calling static initializer in " + SOW_Util_mxJPO.class + " class:");
e.printStackTrace();
// throw e;
} finally {
Locale.setDefault(previous);
}
}
static class ReplacingCallback implements IReplacingCallback {
Document doc1;
public ReplacingCallback(Document d) {
doc1 = d;
}
@Override
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();
// 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());
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);
}
//// to insert Document
DocumentBuilder builder = new DocumentBuilder((Document) e.getMatchNode().getDocument());
builder.moveTo((Run) runs.get(runs.size() - 1));
builder.insertDocument(doc1, ImportFormatMode.USE_DESTINATION_STYLES);
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.getParentNode().insertAfter(afterRun, run);
return afterRun;
}
}
}
Could you please help me resolve this issue in the 2025 jar?