0

有谁知道我们如何使用 Apache POI 在 powerpoint 模板(ppxt)中为文本(文本大纲)添加大纲?到目前为止,我收集到的是XSLFTextRun类没有get/ set针对给定运行元素的文本大纲的方法。

因此,我只能保留以下字体/文本样式:

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

是否可以添加文本大纲?

任何帮助/建议将不胜感激。

4

1 回答 1

1

Apache poi使用底层ooxml-schemas类。这些是从Office Open XML标准自动生成的。所以它们比高级XSLF课程更完整。当然,它们不太方便。

因此,如果某些方面没有在高级XSLF类中实现,我们可以获取底层CT类并使用它们来实现。万一XSLFTextRun我们可以得到CTRegularTextRun对象。然后我们可以查看是否已经有运行属性。如果没有,我们添加一个。然后我们看看是否已经有大纲设置。如果是这样,我们取消设置它,因为我们想将它设置为新的。然后我们设置一个新的大纲。这只是一条具有特殊颜色的线。那条线由CTLineProperties对象表示。所以我们需要有方法来创建、设置CTLineProperties和获取。CTLinePropertiesXSLFTextRunCTLinePropertiesXSLFTextRun

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

使用 current 测试和工作apache poi 5.0.0

于 2021-05-29T13:39:17.913 回答