Apache POI XSLF удаляет тень из текста на слайде - PullRequest
0 голосов
/ 04 марта 2020

Я получил файл pptx с простой презентацией. Он имеет фоновое изображение, белый текст на нем, и этот текст имеет тень. Мне нужно упростить представление и убрать все эти вещи (установить backgroun на белый, цвет шрифта на черный и убрать тени)

Изменить цвета bachground и шрифта довольно просто, как это

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

Но я не могу понять, как удалить тени. Вот пример до и после Before After

Я пытался вызвать метод getShadow() в TextShape, но он нулевой, в XSLFTextRun нет методов для управления текстовыми тенями. Для HSLF я увидел, что есть setShadowed() для TextRun. Но как бороться с тенями в XSLF?

Спасибо!

ОБНОВЛЕНИЕ:

Спасибо Акселю Рихтеру за действительно ценный ответ. В моем do c я нашел два случая с затененным текстом.

  1. Первый, как описал Аксель, решение - очистить тень от CTRegularTextRun. Также я узнаю, что XSLFTextParagraph.getTextRuns() может содержать объекты LineBreak, поэтому перед приведением XSLFTextRun.getXMLObject() - неплохо проверить, что это экземпляр CTRegularTextRun, а не CTTextLineBreak

Код:

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();
                }
            }
        }
    }
}
Второй случай - SlideMaster содержит некоторые определения стилей для тела и заголовка. Поэтому, если мы хотим удалить все тени по-честному - мы должны их тоже очистить.

Код:

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...
    }

1 Ответ

2 голосов
/ 04 марта 2020

Настройки тени текста еще не реализованы в XSLFTextRun. Но, конечно, они установлены в XML.

Прогон с затененным текстом выглядит следующим образом:

<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>

Как вы видите, есть rPr (свойства прогона), имеющие effectLst с outerShdw элементом. Мы можем использовать ooxml-schemas классы и методы для установки и отмены этого.

...
      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();
        }
       }
      }
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...