Как добавить текстовые контуры к тексту в Powerpoint через Apache POI:
Есть ли у кого-нибудь идеи, как мы можем добавить контуры к тексту (текстовый контур) в шаблонах PowerPoint (ppxt) с помощью Apache POI? До сих пор я понял, что у класса XSLFTextRun нет метода для
И поэтому я мог сохранить только следующие стили шрифта / текста:
def fontStyles(textBox: XSLFTextBox, textRun: XSLFTextRun): Unit = {
val fontFamily = textRun.getFontFamily
val fontColor = textRun.getFontColor
val fontSize = textRun.getFontSize
val fontBold = textRun.isBold
val fontItalic = textRun.isItalic
val textAlign = textRun.getParagraph.getTextAlign
textBox.getTextParagraphs.foreach { p =>
p.getTextRuns.foreach { tr =>
tr.setFontFamily(fontFamily)
tr.setFontColor(fontColor)
tr.setFontSize(fontSize)
tr.setBold(fontBold)
tr.setItalic(fontItalic)
tr.getParagraph.setTextAlign(textAlign)
}
}
}
Можно ли добавить контур текста?
Любая помощь / предложения будут очень признательны.
1 ответ
Apache poi
использует лежащие в основе
ooxml-schemas
классы. Они автоматически генерируются из
Office Open XML
стандарт. Таким образом, они более полны, чем классы высокого уровня. Конечно, они намного менее удобны.
Так что, если что-то не реализовано на высоком уровне
XSLF
классы, мы можем получить базовый
CT
классы и сделайте это с помощью тех. В случае если мы можем получить
CTRegularTextRun
объект. Затем мы можем посмотреть, есть ли уже свойства запуска. Если нет, мы добавляем один. Затем смотрим, есть ли уже наброски. Если это так, мы снимаем его, потому что хотим установить его заново. Затем мы устанавливаем новый контур. Это просто линия особого цвета. Эта линия представлена объектом. Итак, нам нужны методы для создания этого, чтобы установить и получить
CTLineProperties
из
XSLFTextRun
.
Полный пример с использованием
Java
код:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import java.awt.Rectangle;
public class PPTXTextRunOutline {
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties createSolidFillLineProperties(java.awt.Color color) {
// create new CTLineProperties
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties
= org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties.Factory.newInstance();
// set line solid fill color
lineProperties.addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
return lineProperties;
}
static void setOutline(XSLFTextRun run, org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, add one.
if (ctRegularTextRun.getRPr() == null) ctRegularTextRun.addNewRPr();
// Is there outline set already? If so, unset it, because we are creating it new.
if (ctRegularTextRun.getRPr().isSetLn()) ctRegularTextRun.getRPr().unsetLn();
// set a new outline
ctRegularTextRun.getRPr().setLn(lineProperties);
}
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties getOutline(XSLFTextRun run) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, return null.
if (ctRegularTextRun.getRPr() == null) return null;
// get outline, may be null
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = ctRegularTextRun.getRPr().getLn();
// make a copy to avoid orphaned exceptions or value disconnected exception when set to its own XML parent
if (lineProperties != null) lineProperties = (org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties)lineProperties.copy();
return lineProperties;
}
// your method fontStyles taken to Java code
static void fontStyles(XSLFTextRun templateRun, XSLFTextShape textShape) {
String fontFamily = templateRun.getFontFamily();
PaintStyle fontColor = templateRun.getFontColor();
Double fontSize = templateRun.getFontSize();
boolean fontBold = templateRun.isBold();
boolean fontItalic = templateRun.isItalic();
TextParagraph.TextAlign textAlign = templateRun.getParagraph().getTextAlign();
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = getOutline(templateRun);
for (XSLFTextParagraph paragraph : textShape.getTextParagraphs()) {
for (XSLFTextRun run : paragraph.getTextRuns()) {
run.setFontFamily(fontFamily);
if(run != templateRun) run.setFontColor(fontColor); // set PaintStyle has the issue which I am avoiding by using a copy of the underlying XML
run.setFontSize(fontSize);
run.setBold(fontBold);
run.setItalic(fontItalic);
run.getParagraph().setTextAlign(textAlign);
setOutline(run, lineProperties);
}
}
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow(new FileInputStream("./PPTXIn.pptx"));
XSLFSlide slide = slideShow.getSlides().get(0);
//as in your code, get a template text run and set its font style to all other runs in text shape
if (slide.getShapes().size() > 0) {
XSLFShape shape = slide.getShapes().get(0);
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;
XSLFTextParagraph paragraph = null;
if(textShape.getTextParagraphs().size() > 0) paragraph = textShape.getTextParagraphs().get(0);
if (paragraph != null) {
XSLFTextRun run = null;
if(paragraph.getTextRuns().size() > 0) run = paragraph.getTextRuns().get(0);
if (run != null) {
fontStyles(run, textShape);
}
}
}
}
//new text box having outlined text from scratch
XSLFTextBox textbox = slide.createTextBox();
textbox.setAnchor(new Rectangle(100, 300, 570, 80));
XSLFTextParagraph paragraph = null;
if(textbox.getTextParagraphs().size() > 0) paragraph = textbox.getTextParagraphs().get(0);
if(paragraph == null) paragraph = textbox.addNewTextParagraph();
XSLFTextRun run = paragraph.addNewTextRun();
run.setText("Test text outline");
run.setFontSize(60d);
run.setFontColor(java.awt.Color.YELLOW);
setOutline(run, createSolidFillLineProperties(java.awt.Color.BLUE));
FileOutputStream out = new FileOutputStream("./PPTXOit.pptx");
slideShow.write(out);
out.close();
}
}
Протестировано и работает на текущих
apache poi 5.0.0
.