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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp踩坑之项目:使用过滤器将时间格式化为特定格式

利用filters过滤器对数据直接进行格式化&#xff0c;注意&#xff1a;与method、onLoad、data同层级 <template><div><!-- orderInfo.time的数据为&#xff1a;2023-12-12 12:10:23 --><p>{{ orderInfo.time | formatDate }}</p> <!-- 2023-1…

springboot 集成Dubbo2.7.8 ,连接zookeeper 提示错误 zookeeper not connected

Dubbo 连接zookeeper时&#xff0c;提示“zookeeper not connected” java.lang.IllegalStateException: zookeeper not connectedat org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init>(CuratorZookeeperClient.java:83) ~[dubbo-2.7.8.jar:2.…

MySQL5 和 MySQL8 的配置区别 一些注意事项

1、使用命令行查看MySQL的版本 先保证你的mysql正在运行&#xff0c;假如用户名是root&#xff0c;密码是123456&#xff0c;运行下边的代码可以查看mysql的版本号。 mysql -uroot -p123456这里我的版本是5.7.19。也就是5版本的。 2、不同版本对应的数据库驱动jar包&#x…

Object Detection in 20 Years: A Survey(2019.5)

文章目录 Abstract1. Introduction1.1. Difference from other related reviews1.2. Difficulties and Challenges in Object Detection 2. OBJECT DETECTION IN 20 YEARS2.1. 目标检测路线图2.1.1. 里程碑:传统探测器&#xff08;粗略了解&#xff09;2.1.2. 里程碑:基于CNN的…

朴素贝叶斯

朴素贝叶斯 朴素贝叶斯理论贝叶斯决策理论条件概率全概率公式贝叶斯公式朴素贝叶斯 言论屏蔽新浪新闻分类朴素贝叶斯算法的优缺点 朴素贝叶斯算法是一种基于贝叶斯定理的有监督的机器学习算法&#xff0c;解决的是分类问题&#xff0c;如文本分类、垃圾邮件过滤、客户是否流失&…

CFS三层靶机内网渗透

CFS三层靶机内网渗透 一、靶场搭建1.基础参数信息2.靶场搭建2.1网卡配置2.2Target1配置2.2.1 网卡配置2.2.2 Target1 BT配置 2.3Target2配置2.3.1 网卡配置2.3.2 Target2 BT配置 2.4Target3配置 二、内网渗透Target11.1信息收集1.1.1IP收集1.1.2端口收集1.1.3目录收集 1.2 webs…

SQL错题集2

1.插入记录 用户1001在2021年9月1日晚上10点11分12秒开始作答试卷9001&#xff0c;并在50分钟后提交&#xff0c;得了90分&#xff1b; 用户1002在2021年9月4日上午7点1分2秒开始作答试卷9002&#xff0c;并在10分钟后退出了平台。 2.请把exam_record表中2021年9月1日之前开始作…

电子学会C/C++编程等级考试2023年03月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:最佳路径 如下所示的由正整数数字构成的三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最…

Linux之重谈文件和c语言文件接口

重谈文件 文件 内容 属性, 所有对文件的操作都是: a.对内容操作 b.对属性操作 关于文件 一&#xff1a; 即使文件的内容为空&#xff0c;该文件也会在磁盘上也会占空间&#xff0c;因为文件不仅仅只有内容还有文件对应的属性&#xff0c;文件的内容会占用空间, 文件的属性也…

Linux基本指令(2.0)

周边知识&#xff1a; 1.Linux中&#xff0c; 一切皆文件 构建大文件 输入如下shell命令 i1; while [ $i -le 10000]; do echo "hello Linux $i"; let i; done 此时大文件已经创建在big.txt 此时我们发现cat查看无法查看开始内容 我们使用more 当占满一屏之后就不…

Unity-Shader - 2DSprite描边效果

实现一个简单的2D精灵图描边效果&#xff0c;效果如下 实现思路&#xff1a; 可以通过判断该像素周围是否有透明度为 0的值&#xff0c;如果有&#xff0c;则说明该像素位于边缘。 所以我们需要打开alpha blend&#xff0c;即&#xff1a; Blend SrcAlpha OneMinusSrcAlpha&am…

leetcode:1422. 分割字符串的最大得分(python3解法)

难度&#xff1a;简单 给你一个由若干 0 和 1 组成的字符串 s &#xff0c;请你计算并返回将该字符串分割成两个 非空 子字符串&#xff08;即 左 子字符串和 右 子字符串&#xff09;所能获得的最大得分。 「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1…

Android 12.0 Folder文件夹全屏后文件夹图标列表居中时拖拽app到桌面的优化

1.概述 在12.0的系统rom产品开发中,在Launcher3中在目前的产品需求开发中,对于Launcher3中的文件夹Folder的布局UI 进行了定制化的需求要求把Folder修改为全屏,然后在中间显示文件夹图标的列表,这时候如果Folder是全屏的话,如果拖拽文件夹列表中的app图标,只有拖拽 到屏…

UEC++ 探索虚幻5笔记(捡金币案例) day12

吃金币案例 创建金币逻辑 之前的MyActor_One.cpp&#xff0c;直接添加几个资源拿着就用 //静态网格UPROPERTY(VisibleAnywhere, BlueprintReadOnly)class UStaticMeshComponent* StaticMesh;//球形碰撞体UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class USphereCompone…

JSON 语法详解:轻松掌握数据结构(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【代码随想录】算法训练计划39

dp 1、62. 不同路径 题目&#xff1a; 求路径方案多少个 思路&#xff1a; 这道题就有点dp了哈 func uniquePaths(m int, n int) int {//dp&#xff0c;写过,代表的是多少种// 初始化dp : make([][]int, m)for i : range dp {dp[i] make([]int, n)dp[i][0] 1 // 代表到…

用友NC Cloud FileParserServlet反序列化RCE漏洞复现

0x01 产品简介 用友 NC Cloud 是一种商业级的企业资源规划云平台,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,实现企业的数字化转型和业务流程优化。 0x02 漏洞概述 用友 NC Cloud FileParserServlet接口存在反序列化代码执行漏…

response应用

文章目录 [TOC](文章目录) response说明一、response文件下载二、待补充。。。 response说明 response是指HttpServletResponse,该响应有很多的应用&#xff0c;比如像浏览器输出消息&#xff0c;下载文件&#xff0c;实现验证码等。 一、response文件下载 1.创建一个javaw…

springboot整合swagger

1&#xff09;简介&#xff1a; 作为后端开放人员&#xff0c;最烦的事就是自己写接口文档和别人没有写接口文档&#xff0c;不管是前端还是后端开发&#xff0c;多多少少都会被接口文档所折磨&#xff0c;前端会抱怨后端没有及时更新接口文档&#xff0c;而后端又会觉得编写接…

备份和恢复Linux服务器上的HTTP配置

备份和恢复Linux服务器上的HTTP配置是一项重要的任务&#xff0c;它可以确保您的服务器在出现故障或配置错误时能够迅速恢复正常运行。下面我们将介绍如何备份和恢复Linux服务器上的HTTP配置。 备份HTTP配置 登录到Linux服务器上&#xff0c;并使用root权限。 备份HTTP配置文…