用 Apache POI 替换 XSLFTextRun 中的单词
Replace a word in a XSLFTextRun with Apache POI
我正在使用 Apache POI 修改 pptx。我试图替换 XSLFTextShape 中的一个词,同时保持 XSLFTextShape 中其他词的格式。
到目前为止我尝试的是以下内容:
private static void replaceText(XSLFTextShape textShape, String marker, String newText){
textShape.setText(textShape.getText().replace(marker, newText));
}
这是在替换我想要的词,但同一 XSLFTextShape 中其他词的格式已更改。例如:如果我在同一个 XSLFTextShape 中有一个红色的单词,即使我没有更改这个单词中的任何内容,该单词的颜色也会更改为黑色。
因此我尝试替换 XSLFTextRun 中的单词。这是我写的代码:
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();
}
我在 运行 这段代码时没有收到任何错误,但是这个词没有被替换,我真的不明白为什么。
如果我添加 textShape.setText(textShape.getText().replace(marker, newText));
行,它会被替换。但是在调试时,我看到 textShape.getText()
在这一行前后给出了相同的结果。
感谢您的帮助!
下一个示例工作:
private static void replace(XSLFTextParagraph paragraph, String searchValue, String replacement) {
List<XSLFTextRun> textRuns = paragraph.getTextRuns();
for (XSLFTextRun textRun : textRuns) {
if (hasReplaceableItem(textRun.getRawText(), searchValue)) {
String replacedText = StringUtils.replace(textRun.getRawText(), searchValue, replacement);
textRun.setText(replacedText);
break;
}
}
}
private static boolean hasReplaceableItem(String runText, String searchValue) {
return StringUtils.contains(runText, searchValue);
}
比如我用的:
- org.apache.poi:poi-ooxml:5.0.0
- org.apache.commons:commons-lang3:3.9
前后图片:
好的,所以我通过一个(不是很好的)解决方法让它工作:
我正在保存每个段落的文本和样式,删除形状中的文本,然后添加带有文本(包括样式)的新段落。这是代码:
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());
});
});
}
我正在使用 Apache POI 修改 pptx。我试图替换 XSLFTextShape 中的一个词,同时保持 XSLFTextShape 中其他词的格式。
到目前为止我尝试的是以下内容:
private static void replaceText(XSLFTextShape textShape, String marker, String newText){
textShape.setText(textShape.getText().replace(marker, newText));
}
这是在替换我想要的词,但同一 XSLFTextShape 中其他词的格式已更改。例如:如果我在同一个 XSLFTextShape 中有一个红色的单词,即使我没有更改这个单词中的任何内容,该单词的颜色也会更改为黑色。
因此我尝试替换 XSLFTextRun 中的单词。这是我写的代码:
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();
}
我在 运行 这段代码时没有收到任何错误,但是这个词没有被替换,我真的不明白为什么。
如果我添加 textShape.setText(textShape.getText().replace(marker, newText));
行,它会被替换。但是在调试时,我看到 textShape.getText()
在这一行前后给出了相同的结果。
感谢您的帮助!
下一个示例工作:
private static void replace(XSLFTextParagraph paragraph, String searchValue, String replacement) {
List<XSLFTextRun> textRuns = paragraph.getTextRuns();
for (XSLFTextRun textRun : textRuns) {
if (hasReplaceableItem(textRun.getRawText(), searchValue)) {
String replacedText = StringUtils.replace(textRun.getRawText(), searchValue, replacement);
textRun.setText(replacedText);
break;
}
}
}
private static boolean hasReplaceableItem(String runText, String searchValue) {
return StringUtils.contains(runText, searchValue);
}
比如我用的:
- org.apache.poi:poi-ooxml:5.0.0
- org.apache.commons:commons-lang3:3.9
前后图片:
好的,所以我通过一个(不是很好的)解决方法让它工作: 我正在保存每个段落的文本和样式,删除形状中的文本,然后添加带有文本(包括样式)的新段落。这是代码:
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());
});
});
}