简体   繁体   中英

Apache POI XSLF remove shadow from text on the slide

I got the pptx file with simple presentation. It has background image, white text on it and this text has shadow. I need to simplify presentation and remove all this things (set backgroun to white, font color to black and remove shadows)

Change bachground and font colors are pretty straightforward, like this

        SlideShow ppt = SlideShowFactory.create(inputStream);
        List<Slide> slides= ppt.getSlides();
        for (int i = 0; i< slides.size(); i++) {
            Slide slide = slides.get(i);
            ((XSLFSlide)slide).getBackground().setFillColor(Color.white);
            XSLFTextShape[] shapes = ((XSLFSlide) slide).getPlaceholders();
            for (XSLFTextShape textShape : shapes) {
                List<XSLFTextParagraph> textparagraphs = textShape.getTextParagraphs();
                for (XSLFTextParagraph para : textparagraphs) {
                    List<XSLFTextRun> textruns = para.getTextRuns();
                    for (XSLFTextRun incomingTextRun : textruns) {
                        incomingTextRun.setFontColor(Color.black);
                }
            }

But i can't figure out how to remove shadows. Here is examle before and after前 后

I tried to call getShadow() method on TextShape, but it's null, in XSLFTextRun there is no methods to manage text shadows. For HSLF i saw that there is setShadowed() for TextRun . But how to deal with shadows in XSLF?

Thanks!

UPDATE:

Thanks Axel Richter for really valuable answer. In my doc i found two cases with shadowed text.

  1. First one is as Axel described, solution is to clean shadow from CTRegularTextRun. Also i find out that XSLFTextParagraph.getTextRuns() may contain LineBreak objects, so before casting XSLFTextRun.getXMLObject() - it's good idea to check that it's instance of CTRegularTextRun and not CTTextLineBreak

Code:

private void clearShadowFromTextRun(XSLFTextRun run) {
    if (run.getXmlObject() instanceof CTRegularTextRun) {
        CTRegularTextRun cTRun = (CTRegularTextRun) run.getXmlObject();
        if (cTRun.getRPr() != null) {
            if (cTRun.getRPr().getEffectLst() != null) {
                if (cTRun.getRPr().getEffectLst().getOuterShdw() != null) {
                    cTRun.getRPr().getEffectLst().unsetOuterShdw();
                }
            }
        }
    }
}
  1. Second case - SlideMaster contains some styles definitions for body and title. So if we want remove all shadows competely - we should clear them too.

Code:

private void clearSlideMastersShadowStyles(XMLSlideShow ppt) {
    List<XSLFSlideMaster> slideMasters = ppt.getSlideMasters();
    for (XSLFSlideMaster slideMaster : slideMasters) {
        CTSlideMaster ctSlideMaster = slideMaster.getXmlObject();
        if (ctSlideMaster.getTxStyles() != null) {
            if (ctSlideMaster.getTxStyles().getTitleStyle() != null) {
                clearShadowsFromStyle(ctSlideMaster.getTxStyles().getTitleStyle());
            }
            if (ctSlideMaster.getTxStyles().getBodyStyle() != null) {
                clearShadowsFromStyle(ctSlideMaster.getTxStyles().getBodyStyle());
            }
            if (ctSlideMaster.getTxStyles().getOtherStyle() != null) {
                clearShadowsFromStyle(ctSlideMaster.getTxStyles().getOtherStyle());
            }
        }
    }
}

private void clearShadowsFromStyle(CTTextListStyle ctTextListStyle) {
        if (ctTextListStyle.getLvl1PPr() != null) {
            if (ctTextListStyle.getLvl1PPr().getDefRPr() != null)
                if (ctTextListStyle.getLvl1PPr().getDefRPr().getEffectLst() != null)
                    if (ctTextListStyle.getLvl1PPr().getDefRPr().getEffectLst().getOuterShdw() != null)
                        ctTextListStyle.getLvl1PPr().getDefRPr().getEffectLst().unsetOuterShdw();
        }
//same stuff for other 8 levels. Ugly uhh...
    }

Settings of text shadow is not yet implemented in XSLFTextRun . But of course they are set in the XML .

A run having shadowed text looks like:

<a:r>
 <a:rPr lang="de-DE" smtClean="0" dirty="0" b="1">
  <a:effectLst>
   <a:outerShdw dir="2700000" algn="tl" dist="38100" blurRad="38100">
    <a:srgbClr val="000000">
     <a:alpha val="43137"/>
    </a:srgbClr>
   </a:outerShdw>
  </a:effectLst>
 </a:rPr>
 <a:t>The text...</a:t>
</a:r>

As you see there is a rPr ( run properties) having a effectLst having a outerShdw element. We can use ooxml-schemas classes and methods to set and unset this.

...
      incomingTextRun.setFontColor(Color.black);

      org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun cTRun = (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)incomingTextRun.getXmlObject();
      if (cTRun.getRPr() != null) {
       if (cTRun.getRPr().getEffectLst() != null) {
        if (cTRun.getRPr().getEffectLst().getOuterShdw() != null) {
         cTRun.getRPr().getEffectLst().unsetOuterShdw();
        }
       }
      }
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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