java使用poi解析PPT,获取重要属性,包含形状每个点的具体x,y轴位置。
使用的是poi5.0的依赖
<!--Apache POI PPT依赖-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.0.0</version>
</dependency>
import org.apache.poi.sl.draw.geom.*;
import org.apache.poi.sl.usermodel.*;
import org.apache.poi.xslf.usermodel.*;
/**
* ppt解析 测试
* @param args
*/
public static void main (String[]args){
try {
// 读取 PPT 文件,文件路径更换为自己的
FileInputStream fis = new FileInputStream("C:\\Users\\ppt模板.pptx");
XMLSlideShow ppt = new XMLSlideShow(fis);
// 获取所有的幻灯片
XSLFSlide[] slides = ppt.getSlides().toArray(new XSLFSlide[0]);
ArrayList<Slides> slidesArrayList = new ArrayList<>();
// 遍历每张幻灯片并获取文本内容
for (XSLFSlide slide : slides) {
Slides slidesObject = new Slides();
//获取ppt背景色
// 获取背景
Background<?, ?> background = slide.getBackground();
if (background != null) {
PaintStyle paintStyle = background.getFillStyle().getPaint();
if (paintStyle instanceof PaintStyle.SolidPaint) {
// 背景是纯色
Color fillColor = slide.getBackground().getFillColor();
int red = fillColor.getRed();
int green = fillColor.getGreen();
int blue = fillColor.getBlue();
slidesObject.setFillColor("rgb("+ red + "," + green + "," + blue+")");
} else {
XSLFGradientPaint gradient = (XSLFGradientPaint) paintStyle;
if (Objects.nonNull(gradient)&&Objects.nonNull(gradient.getGradientColors())){
// 背景是渐变色
ColorStyle[] gradientColors = gradient.getGradientColors();
Color color1 = gradientColors[0].getColor();
Color color2 = gradientColors[1].getColor();
}
}
}
java.awt.Dimension pageSize = ppt.getPageSize();
int width = pageSize.width; //幻灯片宽度
int height = pageSize.height; //幻灯片高度
slidesObject.setWidth(width);
slidesObject.setHeight(height);
ArrayList<Object> shapesList = new ArrayList<>();
for (XSLFShape shape : slide.getShapes()) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;
TextShape textShapeObject = new TextShape();
//获取文本的对齐方式
if (shape instanceof XSLFTextBox) {
XSLFTextBox textBox = (XSLFTextBox) shape;
for (XSLFTextParagraph paragraph : textBox.getTextParagraphs()) {
for (XSLFTextRun run : paragraph.getTextRuns()) {
textShapeObject.setTextAlign(paragraph.getTextAlign().name());
}
}
}
//获取文本是横排还是竖排
org.apache.poi.sl.usermodel.TextShape.TextDirection textDirection = textShape.getTextDirection();
textShapeObject.setTextDirection(textDirection.name());
//获取形状的背景颜色
Color fill = textShape.getFillColor();
if (Objects.nonNull(fill)) {
int redFill = fill.getRed();
int greenFill = fill.getGreen();
int blueFill = fill.getBlue();
textShapeObject.setFill("rgb("+redFill + "," + greenFill + "," + blueFill+")");
} else {
//设置无颜色
textShapeObject.setFill("transparent");
}
textShapeObject.setText(textShape.getText());
if ("任意多边形 1".equals(textShape.getShapeName())) {
textShapeObject.setType("arbitraryPolygon");
} else {
//textShapeObject.setType(Objects.nonNull(textShape.getTextType()) ? textShape.getTextType().toString() : textShape.getShapeType().name());
textShapeObject.setType(Objects.nonNull(textShape.getTextType()) ? "" : textShape.getShapeType().name());
}
if (shape instanceof XSLFAutoShape) {
XSLFAutoShape autoShape = (XSLFAutoShape) shape;
// 获取形状的旋转角度
double angle = autoShape.getRotation();
textShapeObject.setAngle(angle);
CustomGeometry geometry = autoShape.getGeometry();
// 判断是否为可调整形状
IAdjustableShape adjustableShape = autoShape;
Rectangle2D anchor = autoShape.getAnchor();
Context context=new Context(geometry,anchor,adjustableShape);
Path2D.Double path2DPath = geometry.iterator().next().getPath(context);
List<Point> points=new ArrayList<>();
//如果是自定义图形
if (Objects.nonNull(path2DPath)) {
PathIterator iterator = path2DPath.getPathIterator(null);
double[] segment = new double[6];
while (!iterator.isDone()) {
int type = iterator.currentSegment(segment);
Point point=new Point();
switch (type) {
case PathIterator.SEG_MOVETO:
// Handle move-to segment
point.setX(segment[0]);
point.setY(segment[1]);
points.add(point);
break;
case PathIterator.SEG_LINETO:
// Handle line-to segment
point.setX(segment[0]);
if (ShapeType.TRIANGLE.name().equals(textShapeObject.getType())&&points.size()<2){
//三角形的x轴要用公式计算:第一个点的lineTo等于moveTo的x轴加lineto的x轴
point.setX(points.get(0).getX()+segment[0]);
}
point.setY(segment[1]);
points.add(point);
break;
case PathIterator.SEG_CUBICTO:
// Handle cubic curve segment
System.out.println("Curve to: " + segment[0] + ", " + segment[1] + ", " +
segment[2] + ", " + segment[3] + ", " + segment[4] + ", " + segment[5]);
break;
// 其他类型省略....
}
iterator.next();
}
}
textShapeObject.setPoints(points);
}
//获取文本的背景颜色
List<XSLFTextParagraph> textParagraphs = textShape.getTextParagraphs();
if (Objects.nonNull(textParagraphs.get(0)) && textParagraphs.get(0).getTextRuns().size() > 0) {
XSLFTextRun textRun = textParagraphs.get(0).getTextRuns().get(0);
String fontFamily = textRun.getFontFamily();
textShapeObject.setFontFamily(fontFamily);
Double fontSize = textRun.getFontSize();
textShapeObject.setFontSize(fontSize);
PaintStyle fontColor = textRun.getFontColor();
Color color = null;
if (Objects.nonNull(fontColor)) {
if (fontColor instanceof PaintStyle.SolidPaint) {
PaintStyle.SolidPaint solidPaint = (PaintStyle.SolidPaint) fontColor;
color = solidPaint.getSolidColor().getColor();
} else if (fontColor instanceof XSLFTexturePaint) {
// 一些大标题是该类型,暂无法获取大标题文字颜色
XSLFTexturePaint texturePaint = (XSLFTexturePaint) fontColor;
System.out.println("todo: XSLFTexturePaint ");
} else {
System.out.println("not match: " + fontColor.getClass());
}
}
String fontColorFill = "";
if (Objects.nonNull(color)) {
fontColorFill = "rgb("+color.getRed() + "," + color.getGreen() + "," + color.getBlue()+ ")";
} else {
//设置无颜色
fontColorFill = "transparent";
}
textShapeObject.setFontColor(fontColorFill);
} else {
textShapeObject.setFontColor("transparent");
}
Rectangle2D anchor = textShape.getAnchor();
// 获取形状位置
textShapeObject.setId(textShape.getShapeId());// 矩形的id
textShapeObject.setWidth(anchor.getWidth());// 宽度
textShapeObject.setHeight(anchor.getHeight());// 高度
textShapeObject.setLeft(anchor.getX()); // 左边距
textShapeObject.setTop(anchor.getY()); // 左边距
shapesList.add(textShapeObject);
} else if (shape instanceof XSLFPictureShape) {
XSLFPictureShape pictureShape = (XSLFPictureShape) shape;
PictureShape pictureShapeObject = new PictureShape();
pictureShapeObject.setPictureType("picture");// 设置类型为图片
pictureShapeObject.setPictureId(pictureShape.getShapeId());// 图片形状的ID
pictureShapeObject.setPictureWidth(pictureShape.getAnchor().getWidth());// 图片宽度
pictureShapeObject.setPictureHeight(pictureShape.getAnchor().getHeight());// 图片高度
pictureShapeObject.setPictureLeft(pictureShape.getAnchor().getX());// 左边距
pictureShapeObject.setPictureTop(pictureShape.getAnchor().getY());// 顶边距
pictureShapeObject.setPictureOriginalFileName(pictureShape.getPictureData().getFileName());// 原始文件
pictureShapeObject.setPictureFormat(pictureShape.getPictureData().suggestFileExtension());// 图像格式(例如,JPEG、PNG)
//将图片byte转为base64
PictureData pictureData = pictureShape.getPictureData();
byte[] imageData = pictureData.getData();
PictureData.PictureType type = pictureData.getType();
String extension = type.extension;
String filePrefix="";
switch (extension){
case".jpg":
filePrefix="data:image/jpeg;base64,";
break;
case".png": filePrefix="data:image/png;base64,";
break;
case".gif":
filePrefix="data:image/gif;base64,";
break;
default:filePrefix="";
}
String base64String = filePrefix+Base64.getEncoder().encodeToString(imageData);
pictureShapeObject.setPictureData(base64String);
shapesList.add(pictureShapeObject);
} else if (shape instanceof PlaceableShape) {
//解析形状
PlaceableShape placeableShape = (PlaceableShape) shape;
PptPlaceableShape pptPlaceableShape = new PptPlaceableShape();
pptPlaceableShape.setId(shape.getShapeId());
pptPlaceableShape.setRotation(placeableShape.getRotation());
Rectangle2D anchor = ((PlaceableShape) shape).getAnchor();
Rectangle2D bounds2D = anchor.getBounds2D();
pptPlaceableShape.setWidth(bounds2D.getWidth());// 宽度
pptPlaceableShape.setHeight(bounds2D.getHeight());// 高度
pptPlaceableShape.setLeft(bounds2D.getX()); // 左边距
pptPlaceableShape.setTop(bounds2D.getY()); // 顶边距
shapesList.add(pptPlaceableShape);
} else if (shape instanceof XSLFConnectorShape) {
XSLFConnectorShape line = (XSLFConnectorShape) shape;
// work with Line
}
}
slidesObject.setShapes(shapesList);
slidesArrayList.add(slidesObject);
}
System.out.println("json对象" +
JSON.toJSON(slidesArrayList));
// 5. 将JSON对象保存到文件或进行其他操作
ppt.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
自定义的配置类,返回给前端。
@Data
/**
* PPT解析类
*/
public class Slides implements Serializable {
//版本号
private String version;
//背景颜色
private String fillColor;
//幻灯片宽度
private int width;
//幻灯片高度
private int height;
//shapes集合
private List<Object> shapes;
}
@Data
public class PptPlaceableShape implements Serializable {
// 顶边距
private double top;
// 左边距
private double left;
// 宽度
private double width;
// id
private int id;
private String type;
// 高度
private double height;
// 形状的旋转角度
private double rotation;
// 形状的填充前景色
private String fillForegroundColor;
// 形状的填充背景色
private String fillBackgroundColor;
// 形状的线宽
private int lineWidth;
// 形状的线条颜色,rgb
private String lineColor;
}
@Data
public class Point implements Serializable {
//x轴
private double x;
//y轴
private double y;
}
//ppt文本解析
@Data
public class TextShape implements Serializable {
// 顶边距
private double top;
// 左边距
private double left;
// 宽度
private double width;
private String text;
// 矩形的id
private int id;
private String type;
// 高度
private double height;
// 文本字体颜色,rgb
private String fontColor;
// 文本背景颜色,rgb
private String fill;
// 文本方向:HORIZONTAL,VERTICAL,VERTICAL_270,STACKED
private String textDirection; // 文本方向:HORIZONTAL,VERTICAL,VERTICAL_270,STACKED
//字体大小
private Double fontSize;
//文本对齐方式:
private String textAlign;
//获取形状的旋转角度
private double angle;
//获取文本字体
private String fontFamily;
//获取文本字体
private List<Point> points;
}