I am using Apache POI to modify a pptx. I am trying to replace one word in a XSLFTextShape while keeping the formatting of the other words in the XSLFTextShape .
What I tried so far is the following:
private static void replaceText(XSLFTextShape textShape, String marker, String newText){
textShape.setText(textShape.getText().replace(marker, newText));
}
This is replacing the word I want, but the formatting of the other words in the same XSLFTextShape is changed. For example: If I have a word in the same XSLFTextShape which is red, the color of this word is changed to black even though I am not changing anything in this word.
Therefore I tried to replace the word in the XSLFTextRun. This is the code I wrote:
private static void replaceText(XSLFTextShape textShape, String marker, String newText){
List<XSLFTextParagraph> textParagraphList = textShape.getTextParagraphs();
textParagraphList.forEach(textParagraph -> {
List<XSLFTextRun> textRunList = textParagraph.getTextRuns();
textRunList.forEach(textRun -> {
if(textRun.getRawText().contains(marker)){
textRun.setText(textRun.getRawText().replace(marker, newText));
}
});
});
//String text = textShape.getText();
//textShape.setText(textShape.getText().replace(marker, newText));
//String text2 = textShape.getText();
}
I am not getting any error when running this code, but the word is not replaced and I really don't get why.
If I add the line textShape.setText(textShape.getText().replace(marker, newText));
it is replaced. But while debugging, I see that textShape.getText()
gives the same result before and after this line.
Thanks for your help!
Ok, so I made it work somehow with a (not very nice) workaround: I am saving the text and style per paragraph, delete the text in the shape and then add new paragraphs with the textruns (including style). Here is the code:
private static void replaceTextButKeepStyle(XSLFTextShape textShape, final String marker, final String text) {
List<XSLFTextParagraph> textParagraphList = textShape.getTextParagraphs();
ArrayList<ArrayList<TextAndStyle>> textAndStylesTable = new ArrayList<>();
for (int i = 0; i < textParagraphList.size(); i++) {
ArrayList<TextAndStyle> textAndStylesParagraph = new ArrayList<>();
XSLFTextParagraph textParagraph = textParagraphList.get(i);
List<XSLFTextRun> textRunList = textParagraph.getTextRuns();
for (Iterator it2 = textRunList.iterator(); it2.hasNext(); ) {
Object object = it2.next();
XSLFTextRun textRun = (XSLFTextRun) object;
//get Color:
PaintStyle.SolidPaint solidPaint = (PaintStyle.SolidPaint) textRun.getFontColor();
int color = solidPaint.getSolidColor().getColor().getRGB();
//save text & styles:
TextAndStyle textAndStyle = new TextAndStyle(textRun.getRawText(), textRun.isBold(),
color, textRun.getFontSize());
//replace text if marker:
if (textAndStyle.getText().contains(marker)) {
textAndStyle.setText(textAndStyle.getText().replace(marker, text));
}
textAndStylesParagraph.add(textAndStyle);
}
textAndStylesTable.add(textAndStylesParagraph);
}
//delete text and add new text with correct styles:
textShape.clearText();
textAndStylesTable.forEach(textAndStyles -> {
XSLFTextParagraph textParagraph = textShape.addNewTextParagraph();
textAndStyles.forEach(textAndStyle -> {
TextRun newTextrun = textParagraph.addNewTextRun();
newTextrun.setText(textAndStyle.getText());
newTextrun.setFontColor(new Color(textAndStyle.getColorRgb()));
newTextrun.setBold(textAndStyle.isBold());
newTextrun.setFontSize(textAndStyle.getFontsize());
});
});
}