ppt转换成pdf文件

最近用到了,记一下;
ppt转pdf分为两种情况: 小于2007版本的 .ppt格式(2003) 与大于2007版本的 .pptx格式(2007)
.ppt格式为 二进制文件
.pptx格式为xml格式,在java中有不同的jar包需要使用

引入 jar

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.6</version>
</dependency>

代码

package cc.vace.cloud.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTextShape;
import org.apache.poi.xslf.usermodel.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import java.util.Objects;

/**
 * @author vace cc
 */
public class PptUtil {
    public static void main(String[] args) throws IOException, DocumentException {

        FileInputStream inputStream0 = new FileInputStream("F:\\file\\text.ppt");
        FileInputStream inputStream1 = new FileInputStream("F:/file/text.pptx");
        FileOutputStream outputStream0 = new FileOutputStream("F:\\file\\text0.pdf");
        FileOutputStream outputStream1 = new FileOutputStream("F:/file/text1.pdf");
        pptToPdf(inputStream0, outputStream0);
        pptxToPdf(inputStream1,outputStream1);
    }

    /**
     * ppt二进制文件转pdf
     *
     * @param pptIs ppt原文件流
     * @param pdfOs pdf 输出文件流
     * @return true
     * @throws IOException io
     * @throws DocumentException doc
     */
    public static boolean pptToPdf(InputStream pptIs, OutputStream pdfOs) throws IOException, DocumentException {
        Document doc = new Document();
        HSLFSlideShow hslfSlideShow = null;
        PdfWriter pdfWriter = null;
        try {
            hslfSlideShow = new HSLFSlideShow(pptIs);
            Dimension dimension = hslfSlideShow.getPageSize();
            pdfWriter = PdfWriter.getInstance(doc, pdfOs);
            doc.open();
            PdfPTable pdfpTable = new PdfPTable(1);
            List<HSLFSlide> slides = hslfSlideShow.getSlides();
            // 设置ppt 为宋体,否则转pdf时会乱码
            for (HSLFSlide slide : slides) {
                slide.getShapes().stream()
                        .filter(shape -> shape instanceof HSLFTextShape)
                        .map(shape -> (HSLFTextShape) shape)
                        .forEach(shapeH -> shapeH.getTextParagraphs().forEach(paragraph -> paragraph.getTextRuns().forEach(textRun -> textRun.setFontFamily("宋体"))));

                BufferedImage bufferedImage = new BufferedImage((int)dimension.getWidth(), (int)dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = bufferedImage.createGraphics();
                graphics.setPaint(Color.white);
                graphics.setFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));
                slide.draw(graphics);
                graphics.dispose();
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                image.scalePercent(50f);
                // 写入单元格
                pdfpTable.addCell(new PdfPCell(image, true));
                doc.add(image);
            }
            System.out.println("---------- 转换成功 -------------");
            return true;
        } catch (Throwable e) {
            e.printStackTrace();
            System.out.println("---------- 转换失败 -------------");

            throw e;
        } finally {
            doc.close();
            if (!Objects.isNull(hslfSlideShow)) {
                hslfSlideShow.close();
            }
            if (null != pdfWriter) {
                pdfWriter.close();
            }
        }
    }

    /**
     * pptx XML文件转pdf
     * @param pptIs ppt原文件流
     * @param pdfOs pdf 输出文件流
     * @return true
     * @throws IOException io
     */
    public static boolean pptxToPdf(InputStream pptIs, OutputStream pdfOs) throws IOException {
        Document doc = new Document();
        XMLSlideShow slideShow = null;
        PdfWriter pdfWriter = null;
        try {
            slideShow = new XMLSlideShow(pptIs);
            pdfWriter = PdfWriter.getInstance(doc,pdfOs);
            Dimension dimension = slideShow.getPageSize();
            doc.open();
            PdfPTable pdfpTable = new PdfPTable(1);
            List<XSLFSlide> slides = slideShow.getSlides();
            for (XSLFSlide slide : slides) {
                // 设置字体
                slide.getShapes().stream()
                        .filter(shape -> shape instanceof XSLFTextShape)
                        .map(shape -> (XSLFTextShape) shape)
                        .forEach(shapeH -> shapeH.getTextParagraphs().forEach(paragraph -> paragraph.getTextRuns().forEach(textRun -> textRun.setFontFamily("宋体"))));
                BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = bufferedImage.createGraphics();
                graphics.setPaint(Color.white);
                graphics.setFont(new Font("宋体", Font.PLAIN, 12));
                slide.draw(graphics);
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                image.scalePercent(50f);
                pdfpTable.addCell(new PdfPCell(image, true));
                doc.add(image);
            }
            if (slides.size() == 0) {
                BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_ARGB);
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                pdfpTable.addCell(new PdfPCell(image, true));
                doc.add(image);
            }
            System.out.println("---------- 转换成功 -------------");
            return true;
        }catch (Throwable e) {
            e.printStackTrace();
//            throw e;
            return false;
        }finally {
            doc.close();
            if (!Objects.isNull(slideShow)) {
                slideShow.close();
            }
            if (pdfWriter != null) {
                pdfWriter.close();
            }
        }
    }

}


遇到的exception

遇见报错document 是空的

The document has no pages.

遇见这个问题,一般情况下是因为slide.draw报错了,但是catch捕获 不到,最后在执行完成之后报错,但此时的错是finally里异常关闭文件导致的,所以会报document has no pages 无法关闭
这里做几个问题点去切入

一、

首先要注意的是这里catch 的是Throwable 而不是Exception
因为当 slide.draw() 方法报错 是继承的Throwable 的异常,而不是Exception 的,所以使用Exception 去捕获异常的时候会失败

catch (Throwable e) {
   	e.printStackTrace();
   	throw e;
   	return false;
}

二、

针对jdk8以上的版本:如jdk11
报错

javax/xml/bind/JAXBException

需要添加额外的jar包

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.0.1</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.0.1</version>
</dependency>

如果上传的一个空ppt 则pdf文件一定是已损坏,有两种解决办法,一,初始化一个空的pdf
这里选择TYPE_INT_ARGB,这样底色就是空白的啦,如果使用TYPE_INT_RGB那就是一块黑

if (slides.size() == 0) {
                BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_ARGB);
                com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
                pdfpTable.addCell(new PdfPCell(image, true));
                doc.add(image);
            }

在这里插入图片描述

poi的5.X版本

这里介绍的poi适合4.X的版本,如果使用 5.X版本则需要加入xmlbeans包

<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>5.0.3</version>
</dependency>

完整的 5.X包:截止博主写文的时间,最新的poi版本如下

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>5.0.3</version>
        </dependency>

设置页面大小

当我们把上边的步骤实现之后,发现两个ppt 合成了一个pdf页面,想要一个pdf页面对应一个ppt页面
实现方式:

Documentnew 的 时候可以直接将页面的尺寸放进去
Document 可以使用 setPageSize来设置大小
setPageSize 有一个问题,setPageSize不会立即生效,导致我们在设置页面的时候,从第二页开始才会生效。 具体是bug还是故意这样设计的不清楚

代码实现:只列出 pptx格式的
ppt 转也是一样的

public static boolean pptxToPdf(InputStream pptIs, OutputStream pdfOs) throws IOException {
    Document doc = null;
    XMLSlideShow slideShow = null;
    PdfWriter pdfWriter = null;
    try {
        slideShow = new XMLSlideShow(pptIs);
        Dimension dimension = slideShow.getPageSize();

        BufferedImage bufferedImage0 = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_ARGB);
        com.itextpdf.text.Image image0 = com.itextpdf.text.Image.getInstance(bufferedImage0, null);
        com.itextpdf.text.Rectangle pageSize = new com.itextpdf.text.Rectangle(image0);
        //PageSize.A4.rotate()
        doc = new Document(pageSize);
        pdfWriter = PdfWriter.getInstance(doc,pdfOs);
        doc.open();
        PdfPTable pdfpTable = new PdfPTable(1);
        List<XSLFSlide> slides = slideShow.getSlides();
		// 如果是空ppt, 则生成默认一页
        if (slides.size() == 0) {
            doc.add(image0);
        }
        for (XSLFSlide slide : slides) {
            // 设置字体
            slide.getShapes().stream()
                    .filter(shape -> shape instanceof XSLFTextShape)
                    .map(shape -> (XSLFTextShape) shape)
                    .forEach(shapeH -> shapeH.getTextParagraphs().forEach(paragraph -> paragraph.getTextRuns().forEach(textRun -> textRun.setFontFamily("宋体"))));
            BufferedImage bufferedImage = new BufferedImage((int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = bufferedImage.createGraphics();
            graphics.setPaint(Color.white);
            graphics.setFont(new Font("宋体", Font.PLAIN, 12));
            slide.draw(graphics);
            com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(bufferedImage, null);
            image.scalePercent(90f);
            pdfpTable.addCell(new PdfPCell(image, true));

            doc.add(image);
        }
        System.out.println("---------- 转换成功 -------------");
        return true;
    }catch (Throwable e) {
        e.printStackTrace();
//            throw e;
        return false;
    }finally {
        doc.close();
        if (!Objects.isNull(slideShow)) {
            slideShow.close();
        }
        if (pdfWriter != null) {
            pdfWriter.close();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/221922.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 常见面试题

目录 1.MyBatis——概述1.1.什么是 ORM 框架&#xff1f;1.2.✨谈谈对 MyBatis 的理解。1.3.使用 MyBatis 相对于直接使用 SQL 有哪些优点&#xff1f;1.4.MyBatis 有什么优缺点&#xff1f;1.5.✨MyBatis 的分层结构是什么样的&#xff1f;1.6.✨MyBatis 的执行流程是什么样的…

这个柴油发电机大招,再不知道就晚了!

随着能源需求的不断增长和环境问题的日益凸显&#xff0c;柴油发电机在各个行业中扮演着关键的角色&#xff0c;为企业和社会提供可靠的电力支持。 然而&#xff0c;为了确保发电机的高效运行和延长其使用寿命&#xff0c;监控和维护变得至关重要。 客户案例 制造业 某制造业…

Java 控制台命令导入本地jar包到maven本地库中

1、新建POM文件&#xff0c;在maven库路径下创建POM文件 注意&#xff1a;这个路径需要与第2点导入命令中的grouoId、artifactId和version写法对应 Path&#xff1a;D:\RomanData\repository\com\sae\mail\1.0.0\mail-1.0.0.pom <?xml version"1.0" encoding&q…

电脑屏幕亮度怎么调?学会4个方法,轻松调节亮度!

“我总是感觉我电脑屏幕太暗了&#xff0c;有时候如果光线好一点&#xff0c;会看不清电脑屏幕。有什么可以把电脑调亮一点的简单方法吗&#xff1f;” 在我们的日常生活中&#xff0c;电脑已经成为我们工作、学习、娱乐不可或缺的工具。然而&#xff0c;长时间面对电脑屏幕可能…

删除误提交的 git commit

背景描述 某次的意外 commit 中误将密码写到代码中并且 push 到了 remote repo 里面, 本文将围绕这个场景讨论如何弥补. 模拟误提交操作 在 Gitee 创建一个新的 Repo, clone 到本地 git clone https://gitee.com/lpwm/myrepo.git创建两个文件, commit 后 push 到 remote 作…

2022年第十一届数学建模国际赛小美赛B题序列的遗传过程解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 B题 序列的遗传过程 原题再现&#xff1a; 序列同源性是指DNA、RNA或蛋白质序列之间的生物同源性&#xff0c;根据生命进化史中的共同祖先定义[1]。DNA、RNA或蛋白质之间的同源性通常根据它们的核苷酸或氨基酸序列相似性来推断。显著的相…

【EI征稿中|SPIE出版】 第四届传感器与信息技术国际学术会议(ICSI 2024)

第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09; 2024 4th International Conference on Sensors and Information Technology&#xff08;ICSI 2024&#xff09; 第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09;将于2024年1月5…

VS2019shi用动态链接库

.dll文件路径包含 C/C常规-------->附加包含目录 将动态库项目文件路径包含在附加包含目录。 .lib文件路径包含 连接器------------>输入------------------>附加依赖项 .lib文件名字输出附加依赖项 连接器------------>常规------------------>附加库目录 添加…

软著项目推荐 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

外包干了8个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

开源代驾上门预约小程序源码系统:预约代驾,出行更无忧 附带完整的搭建教程

随着人们生活水平的提高&#xff0c;越来越多的人选择代驾服务。为了方便用户预约代驾&#xff0c;罗峰来给大家分享一款开源代驾上门预约系统。该系统具有以下特色功能&#xff0c;让出行更加无忧。 以下是部分代码示例&#xff1a; 系统特色功能一览&#xff1a;​​​​​​…

【计算机网络笔记】物理层——信道与信道容量

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

理解依赖注入

1 回顾Spring IoC容器 1.1 Spring IoC容器 Web应用程序由大量的程序组件组成&#xff0c;这些组件一起工作完成业务逻辑的执行。 这些组件通常是一个依赖另一个&#xff0c;互相协作实现所需功能。 Spring提供容器&#xff0c;也就是IoC容器&#xff0c;来管理这些组件&…

万界星空科技MES系统在工业生产中的应用

万界星空科技MES系统在工业生产中的应用广泛。它适用于各类制造业&#xff0c;包括汽车制造、电子制造、注塑、能源化工、航天航空、食品加工、服装纺织、灯具、电线电缆、电机发动机、印刷包装等行业。 在汽车制造领域&#xff0c;MES系统可以实时追踪和控制整个生产过程&…

摄像头选型号指南

镜头选型工具 - HiTools - 海康威视 Hikvisionhttps://www.hikvision.com/cn/support/tools/hitools/cl8a9de13648c56d7f/ 1. 海康威视摄像头选型号指南 海康威视摄像头选型号指南-CSDN博客文章浏览阅读3.7k次。跟客服对话比跟AI对话好不了多少&#xff0c;能噎死人&#xff0…

graphics.h安装后依旧报错

问题解决一&#xff1a; 我在网上找了很多&#xff0c;都说找到graphics.h这个文件&#xff0c;放到include这个目录下&#xff0c;我照做了&#xff0c;然后 当我进行编译时&#xff0c;自动跳到graphics.h这个文件并出现一堆报错 问题解决二&#xff1a; 看一下这两个文件是…

【优选算法系列】【专题三二分查找】第二节.35. 搜索插入位置和69. x 的平方根

文章目录 前言一、搜索插入位置 1.1 题目描述 1.2 题目解析 1.2.1 算法原理 1.2.2 代码编写 1.2.3 题目总结二、x 的平方根 2.1 题目描述 2.2 题目解析 2.2.1 算法原理 2.2.2 代码编写 …

思腾云计算中心 | 5千平米超大空间,基础设施完善,提供裸金属GPU算力租赁业务

2021年&#xff0c;思腾合力全资收购包头市易慧信息科技有限公司&#xff0c;正式开启云计算业务。思腾云计算中心占地2400平米&#xff0c;位于包头市稀土高新区&#xff0c;毗邻多家知名企业&#xff0c;地理位置优越&#xff0c;交通便利&#xff0c;是区内重要的信息化产业…

深度学习火车票识别系统 计算机竞赛

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 图像识别 火车票识别系统 该项目较为新颖&#xff0c;适…

小航助学题库白名单竞赛考级蓝桥杯等考scratch(11级)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;