After all, I had to create paragraphs manually. Basically, I split the replace string to an array and create a new paragraph for each array element. Here is the code:
protected void replaceElementInParagraphs(List<XWPFParagraph> xwpfParagraphs,
Map<String, String> replacedMap) {
if (!searchInParagraphs(xwpfParagraphs, replacedMap)) {
replaceElementInParagraphs(xwpfParagraphs, replacedMap);
}
}
private boolean searchInParagraphs(List<XWPFParagraph> xwpfParagraphs, Map<String, String> replacedMap) {
for(XWPFParagraph xwpfParagraph : xwpfParagraphs) {
List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();
for(XWPFRun xwpfRun : xwpfRuns) {
String xwpfRunText = xwpfRun.getText(xwpfRun.getTextPosition());
for(Map.Entry<String, String> entry : replacedMap.entrySet()) {
if (xwpfRunText != null && xwpfRunText.contains(entry.getKey())) {
if (entry.getValue().contains("\n")) {
String[] paragraphs = entry.getValue().split("\n");
entry.setValue("");
createParagraphs(xwpfParagraph, paragraphs);
return false;
}
xwpfRunText = xwpfRunText.replaceAll(entry.getKey(), entry.getValue());
}
}
xwpfRun.setText(xwpfRunText, 0);
}
}
return true;
}
private void createParagraphs(XWPFParagraph xwpfParagraph, String[] paragraphs) {
if(xwpfParagraph!=null){
for (int i = 0; i < paragraphs.length; i++) {
XmlCursor cursor = xwpfParagraph.getCTP().newCursor();
XWPFParagraph newParagraph = document.insertNewParagraph(cursor);
newParagraph.setAlignment(xwpfParagraph.getAlignment());
newParagraph.getCTP().insertNewR(0).insertNewT(0).setStringValue(paragraphs[i]);
newParagraph.setNumID(xwpfParagraph.getNumID());
}
document.removeBodyElement(document.getPosOfParagraph(xwpfParagraph));
}
}