简体   繁体   English

用 Apache POI 替换 XSLFTextRun 中的单词

[英]Replace a word in a XSLFTextRun with Apache POI

I am using Apache POI to modify a pptx.我正在使用 Apache POI 来修改 pptx。 I am trying to replace one word in a XSLFTextShape while keeping the formatting of the other words in the XSLFTextShape.我正在尝试替换 XSLFTextShape 中的一个单词,同时保留 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.这是替换我想要的单词,但同一 XSLFTextShape 中其他单词的格式已更改。 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.例如:如果我在同一个 XSLFTextShape 中有一个红色的单词,即使我没有更改该单词中的任何内容,该单词的颜色也会更改为黑色。

Therefore I tried to replace the word in the XSLFTextRun.因此我尝试替换 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));如果我添加行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.但是在调试时,我看到textShape.getText()在这一行之前和之后给出了相同的结果。

Thanks for your help!谢谢你的帮助!

Next example work:下一个示例工作:

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);
}

For example I'm used:例如我用过:

  • org.apache.poi:poi-ooxml:5.0.0 org.apache.poi:poi-ooxml:5.0.0
  • org.apache.commons:commons-lang3:3.9 org.apache.commons:commons-lang3:3.9

Pictures before and after:之前和之后的照片:
在此处输入图像描述 在此处输入图像描述

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).好的,所以我以某种方式(不是很好)解决方法使它工作:我保存每个段落的文本和样式,删除形状中的文本,然后添加带有 textruns 的新段落(包括样式)。 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());
        });
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM