ppt转换成pdf文件

news2024/11/23 22:46:56

最近用到了,记一下;
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.coloradmin.cn/o/1304921.html

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

相关文章

MacOS 12 开放指定端口 指定ip访问

MacOS 12 开放指定端口 指定ip访问 在 macOS 上开放一个端口&#xff0c;并指定只能特定的 IP 访问&#xff0c;你可以使用 macOS 内置的 pfctl&#xff08;Packet Filter&#xff09;工具来实现。 以下是一些基本的步骤&#xff1a; 1、 编辑 pf 配置文件&#xff1a; 打开 /…

Dockerfile创建镜像--LNMP+wordpress

实验准备&#xff1a; nginx&#xff1a;172.111.0.10 docker-nginx mysql&#xff1a;172.111.0.20 docker-mysql php&#xff1a;172.111.0.30 docker-php 自定义网段&#xff1a;172.111.0.0/16mkdir nginx mysql php mv nginx-1.22.0.tar.gz wordpress-6.4.2-zh_CN.ta…

数据结构之选择排序

目录 直接选择排序 选择排序的时间复杂度 堆排序 向上调整算法 向下调整算法 向上调整算法建立堆 向下调整算法建立堆 堆排序整体代码 堆排序的时间复杂度 直接选择排序 在之前讲插入排序时&#xff0c;我们讲了这样的一个应用场景&#xff0c;我们在斗地主摸牌时&…

PyInstaller 打包 Python 脚本为 .exe 可执行文件闪退、No Model named XXX问题

文章目录 前言.exe 可执行文件闪退No Model named XXXPython 环境问题查看当前python路径查看当前python环境使用的site-package路径 个人简介 前言 在上一篇文章中&#xff0c;我们介绍了如何将 Python 脚本打包为 .exe 可执行文件&#xff0c;但有时候打包生成的 .exe 文件会…

慢SQL诊断

最近经常遇到技术开发跑来问我慢SQL优化相关工作&#xff0c;所以干脆出几篇SQL相关优化技术月报&#xff0c;我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到&#xff0c;尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…

阿里云cdn设置相同的域名路径访问不同的oss目录

1.设置回源配置&#xff0c;添加回源URL改写 2.设置跨域&#xff0c;cdn的跨域优先oss 3.回源设置

前端 三种解决跨域问题 jsonp 、CORS、代理服务器 解决跨域全家桶

我的报错情况是 后端接口是3000 前端本地接口是8080&#xff0c;最后出现跨域 1.什么是跨域&#xff1f; 首先跨域是一种安全机制&#xff0c;是在开发上线前考虑到的安全问题并且需要采取合适的手段去避免这个问题带来的程序错误,接口跨域可以后端处理,也可以前端处理&#x…

Docker的安装与简单操作命令

目录 前言 docker的安装 基础docker操作 容器管理 镜像管理 容器镜像封装与加载 前言 前文简单说明了容器技术出现的背景&#xff0c;与对docker做了结构上的介绍Container容器技术简介-CSDN博客https://blog.csdn.net/qq_72569959/article/details/134814887 讲到dock…

Day07 Liunx高级系统设计8-线程

概述 进程与线程 进程 : 系统分配资源的基本单位 , 可以简单理解为一个正在进行的程序 线程 : 操作系统调度的最小单位 , 就是一段代码的执行顺序 注意&#xff1a; 1, 一个进程必须要有一个线程 , 该线程被称为主线程 2, 一个进程可以有多个线程 , 除主线程外的其他线程都是…

玻色量子袁为出席中国移动第四届科技周量子计算算法与应用分论坛

9月12日&#xff0c;中国移动第四届科技周“量子计算算法与应用”分论坛在北京成功举办&#xff0c;中国移动研究院院长黄宇红发表致辞&#xff0c;中国移动未来研究院院长崔春风全程主持。玻色量子作为光量子计算领域真机测试与场景应用的标杆企业应邀出席&#xff0c;玻色量子…

散点图,何须图,折线图混放在一个echarts

散点图&#xff0c;何须图&#xff0c;折线图混放在一个echarts option {tooltip: {trigger: axis,axisPointer: {type: cross,crossStyle: {color: #999}}},legend: {data:[盒须图1,盒须图2,折线图,散点图]},xAxis: [{type: category,data: [周一,周二,周三,周四,周五,周六…

智能优化算法应用:基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.花授粉算法4.实验参数设定5.算法结果6.参考文…

vue3 + ts 防抖指令,节流指令,复制指令

vue3 ts 自定义指令 防抖指令&#xff0c;节流指令&#xff0c;复制指令 本文使用了 element-ui , element-plus 官网 源文件 https://admin.spicyboy.cn/#/directives/debounceDirect 新建 copy.ts 文件 &#xff08;复制指令&#xff09; import type { Directive, Di…

重新思考U-Net在医学超声图像分割中的应用(NU-net)

Rethinking the Unpretentious U-net for Medical Ultrasound Image Segmentation 摘要&#xff1a; 乳腺肿瘤分割是帮助我们描述和定位肿瘤区域的关键步骤之一。然而&#xff0c;乳腺肿瘤形态多变、边界模糊、强度分布相似&#xff0c;给乳腺肿瘤的准确分割带来了挑战。近年…

java系列-LinkedHashMap

1.插入新节点时&#xff0c;会将该节点加到链表尾部 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{/*** The head (eldest) of the doubly linked list.*/transient LinkedHashMapEntry<K,V> head;/*** The tail (young…

C语言数据结构-栈和队列

文章目录 1 栈的表示与实践1.1 栈的概念及结构1.2 定义数据结构1.3 初始化与销毁1.4 入栈1.5 出栈1.6 栈顶的数据1.7 栈的个数1.8 栈是否是空1.9 打印栈 2 队列的表示与实现2.1 队列的概念与结构2.2 队列的数据结构定义2.3 队列的初始化与销毁2.4 入队2.5 出队2.6 取队头数据2.…

enumerate()函数讲解+同时获取索引和对应的元素值+实例

enumerate()函数是Python内置函数&#xff0c;用于在遍历可迭代对象&#xff08;如列表、字符串、元组等&#xff09;时&#xff0c;同时获取索引和对应的元素值。 它的主要作用是在循环过程中方便地获取索引和元素。 下面以两个例子来进行介绍理解。 目录 一、例子1 二、例…

打造‘产业大数据综合服务平台’,助力智慧园区建设!

随着大数据、人工智能、云计算、物联网等新一代信息技术的发展与应用&#xff0c;我国各类型园区正在向“智慧园区”转型升级&#xff0c;逐步开启数字化、智能化的运营管理模式。智慧园区的建设不仅需要基础设施的智慧化&#xff0c;更要实现园区规划、运营、管理、服务的智慧…

plf::list原理分析

plf::list是一个比std::list性能要好的另外一种实现&#xff0c;根据作者的性能测试&#xff1a; 293% faster insertion 57% faster erasure 17% faster iteration 77% faster sorting 70% faster reversal 91% faster remove/remove_if 63% faster unique 811% faster clear …

Vue 3 + Tailwind CSS:打造现代化项目的完美组合

Vue 3 Tailwind CSS&#xff1a;打造现代化项目的完美组合 本篇教程将向你介绍如何将 Tailwind CSS 与 Vue 3 项目搭配使用&#xff0c;为你的项目提供现代化的 UI 呈现和开发体验。通过本文的逐步演示和示例代码&#xff0c;你将很快掌握在 Vue 3 中集成和使用 Tailwind CSS…