【Java】使用Apache POI识别PPT中的图片和文字,以及对应的大小、坐标、颜色、字体等

本文介绍如何使用Apache POI识别PPT中的图片和文字,获取图片的数据、大小、尺寸、坐标,以及获取文字的字体、大小、颜色、坐标。

官方文档:https://poi.apache.org/components/slideshow/xslf-cookbook.html

官方文档和网上的资料介绍的很少,很多元素,需要一点点尝试才能获取到。

注意:本篇文章针对.pptx结尾的PPT文件

引入依赖:

xml 复制代码
 		<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>

核心代码:

java 复制代码
	private static final String FILE_PATH = "/Temp/PPT/test.pptx";
    private static final String OUTPUT_PATH = "/Temp/PPT/output/";
    private static final String RGBA_TEMPLATE = "rgba(%d,%d,%d,1)";

    public static void main(String[] args) {
        analysisPpt(FILE_PATH);
    }

    public static void analysisPpt(String filePath) {
        try {
            InputStream input = new FileInputStream(filePath);
            XMLSlideShow xss = new XMLSlideShow(input);
            //getSlides(); 返回幻灯片中找到的所有普通幻灯片
            List<XSLFSlide> xslfSlideList = xss.getSlides();
            for (XSLFSlide xslfSlide : xslfSlideList) {
                //HSLFShape表示工作表中包含的所有形状(幻灯片或注释)
                List<XSLFShape> shapes = xslfSlide.getShapes();
                handleShapes(shapes);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void handleShapes(final List<XSLFShape> shapes) throws Exception {
        for (XSLFShape shape : shapes) {
            if (shape instanceof XSLFGroupShape) {
                XSLFGroupShape groupShape = ((XSLFGroupShape) shape);
                // 对XSLFGroupShape进行递归处理
                handleShapes(groupShape.getShapes());
            } else if (shape instanceof XSLFTextShape) {
                XSLFTextShape xslfTextShape = ((XSLFTextShape) shape);
                List<XSLFTextParagraph> textParagraphs = xslfTextShape.getTextParagraphs();
                XSLFTextRun textRun = textParagraphs.get(0).getTextRuns().get(0);
                Rectangle2D anchor = xslfTextShape.getAnchor();
                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 fill = "";
                if (Objects.nonNull(color)) {
                    fill = String.format(RGBA_TEMPLATE, color.getRed(), color.getGreen(), color.getBlue());
                }
                System.out.printf("[text]: %s \n[font]: %s [size]: %s [x,y]: (%s,%s) [color]: %s \n", xslfTextShape.getText(),
                        textRun.getFontFamily(), textRun.getFontSize(), anchor.getX(), anchor.getY(), fill);
                System.out.println("----------------------------");
            } else if (shape instanceof XSLFPictureShape) {
                XSLFPictureShape xslfPictureShape = ((XSLFPictureShape) shape);
                XSLFPictureData pictureData = xslfPictureShape.getPictureData();
                // 图片数据
                byte[] data = pictureData.getData();
                savePicture(data, pictureData.getFileName());
                Dimension dimensionInPixels = pictureData.getImageDimensionInPixels();
                Rectangle2D anchor = xslfPictureShape.getAnchor();
                System.out.printf("[picture name]: %s: [size]: %s * %s [X,Y]: (%s,%s) \n", pictureData.getFileName(), dimensionInPixels.getWidth(),
                        dimensionInPixels.getHeight(), anchor.getX(), anchor.getY());
            } else {
                System.out.println("unknown shape:" + shape.getClass());
            }
        }
    }

    private static void savePicture(final byte[] data, final String fileName) throws IOException {
        FileOutputStream out = new FileOutputStream(OUTPUT_PATH + fileName);
        out.write(data);
        out.close();
    }
相关推荐
独泪了无痕9 小时前
探索Pinyin4j-Java中的拼音转换利器
java·后端
道尔柯南10 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
kingx311 小时前
Bugku 3122 谷歌小恐龙题解:纯离线逆向 Vault 的 AES-GCM 加密资源(附 Python 解密器)
java·逆向·ctf·bugku·aes-gcm
DevOpenClub13 小时前
职教高考控制线 API:招生类别枚举、筛选与空分数含义
java·数据库·高考
露天赏雪15 小时前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
天天被压力15 小时前
【A股分钟级高频数据完全手册 #06】北交所分钟级数据接口:京市股票Pro版最新分时
java·人工智能·python
天天被压力15 小时前
【A股分钟级高频数据完全手册 #05】指数历史分钟数据接口:Pro版沪深指数分时回放
java·人工智能·python
captain37615 小时前
▲统一功能——DispatcherServlet源码分析
java·spring·java-ee·log4j·maven
金銀銅鐵15 小时前
JDK 21 中 List.of 的实现细节:从 List12 到 ListN
java·后端·ai编程
yeccheng17 小时前
MySQL 索引超详解:从底层 B+ 树到面试高频考点
java·开发语言·jvm·mysql·面试