java实现ppt转图片、ppt转pdf

news/2024/11/26 4:25:07/

        最近做的需求需要实现在线预览ppt的功能,网上查了一遍,比较完美的方案都需要依赖第三方的服务或调用微软的在线接口,由于项目部署内网,同时为了不增加项目的复杂度,最终决定使用纯java实现,依赖 poi 将ppt 转成 png图片,然后再利用 itextpdf 将图片转成 pdf ,最后通过js实现预览。转换后的pdf效果图如下:

        目前存在一个确定是 ppt字体全部统一换成了 宋体 ,以解决中文有些情况下乱码的问题,本来想研究下能不更换字体的方式,但是没时间,暂时就这样了。有解决方案的同学还请赐教。

        下面直接上代码:

        maven 依赖大致如下:

        <!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>xdocreport</artifactId><version>2.0.2</version></dependency><!--pdf start--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.1</version></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.18</version></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.18</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.xmlgraphics</groupId><artifactId>batik-bridge</artifactId><version>1.12</version></dependency><!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator --><dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency><!--end-->

 java 工具类

package com.fmi110.common.utils;import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import com.ruoyi.common.exception.BusinessException;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.xslf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.*;
import java.util.ArrayList;
import java.util.List;/*** @author fmi110* @description ppt 转图片;图片转pdf 工具* @date 2021/8/19 20:16*/public class PPTUtil {protected static final Logger log = LoggerFactory.getLogger(PPTUtil.class);public static int width  = 720;public static int height = 540;public static void PPTtoImage(String filePath, String fileName) throws Exception {File f = new File(filePath + fileName);if (f.exists()) {if (f.getName().endsWith(".pptx") || f.getName().endsWith(".PPTX")) {pptx2Image(filePath, fileName);} else {ppt2Image(filePath, fileName);}} else {throw new BusinessException("文档不存在");}}/*** 将pptx转换为图片,直接保存在内存中,ppt很大时可能会oom!!!** @param is ppt 输入流* @return* @throws IOException*/public static List<byte[]> pptx2Image(InputStream is) throws IOException {// 获取系统可用字体GraphicsEnvironment e          = GraphicsEnvironment.getLocalGraphicsEnvironment();String[]            fontNames  = e.getAvailableFontFamilyNames();List                availFonts = CollectionUtils.arrayToList(fontNames);XMLSlideShow ppt      = new XMLSlideShow(is);Dimension    pgsize   = ppt.getPageSize();int          pageSize = ppt.getSlides().size();List<byte[]> imgList  = new ArrayList<>(pageSize);log.info("ppt 总页数:{}, 尺寸: width={},height={}", pageSize, pgsize.width, pgsize.height);for (int i = 0; i < pageSize; i++) {//防止中文乱码for (XSLFShape shape : ppt.getSlides().get(i).getShapes()) {if (shape instanceof XSLFTextShape) {XSLFTextShape tsh = (XSLFTextShape) shape;for (XSLFTextParagraph p : tsh) {for (XSLFTextRun r : p) {String fontFamily = r.getFontFamily();//log.info(">>>>>原始ppt字体:{}", fontFamily);fontFamily = "宋体";//log.info(">>>>>ppt字体修改为:{}", fontFamily);r.setFontFamily(fontFamily);
//                            if (!availFonts.contains(fontFamily)) {
//                                fontFamily = "宋体";
//                                log.info(">>>>>ppt字体修改为:{}", fontFamily);
//                                r.setFontFamily(fontFamily);
//                            }}}}}BufferedImage img      = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);Graphics2D    graphics = img.createGraphics();// clear the drawing areagraphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));// renderppt.getSlides().get(i).draw(graphics);// save the outputByteArrayOutputStream out = new ByteArrayOutputStream();javax.imageio.ImageIO.write(img, "png", out);imgList.add(out.toByteArray());IOUtils.closeQuietly(out);}if (is != null) {IOUtils.closeQuietly(is);}return imgList;}/*** 将pptx转成图片,保存在同一目录的image目录下** @param filePath ppt文件路径* @param fileName ppt 文件名* @throws IOException*/public static void pptx2Image(String filePath, String fileName) throws Exception {// 获取系统可用字体GraphicsEnvironment e          = GraphicsEnvironment.getLocalGraphicsEnvironment();String[]            fontNames  = e.getAvailableFontFamilyNames();List                availFonts = CollectionUtils.arrayToList(fontNames);FileInputStream is  = new FileInputStream(filePath + fileName);XMLSlideShow    ppt = new XMLSlideShow(is);Dimension pgsize   = ppt.getPageSize();int       pageSize = ppt.getSlides().size();log.info("ppt 总页数:{}, 尺寸: width={},height={}", pageSize, pgsize.width, pgsize.height);for (int i = 0; i < pageSize; i++) {//防止中文乱码for (XSLFShape shape : ppt.getSlides().get(i).getShapes()) {if (shape instanceof XSLFTextShape) {XSLFTextShape tsh = (XSLFTextShape) shape;for (XSLFTextParagraph p : tsh) {for (XSLFTextRun r : p) {String fontFamily = r.getFontFamily();//log.info(">>>>>原始ppt字体:{}", fontFamily);fontFamily = "宋体";//log.info(">>>>>ppt字体修改为:{}", fontFamily);r.setFontFamily(fontFamily);
//                            if (!availFonts.contains(fontFamily)) {
//                                fontFamily = "宋体";
//                                log.info(">>>>>ppt字体修改为:{}", fontFamily);
//                                r.setFontFamily(fontFamily);
//                            }}}}}BufferedImage img      = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);Graphics2D    graphics = img.createGraphics();// clear the drawing areagraphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));// renderppt.getSlides().get(i).draw(graphics);// save the outputString pptname    = fileName.substring(0, fileName.lastIndexOf("."));String newimgPath = filePath + "image/" + pptname + "/";File   imgPath    = new File(newimgPath);if (!imgPath.exists()) {//图片目录不存在则创建imgPath.mkdirs();}String           file = newimgPath + (i + 1) + ".png";FileOutputStream out  = new FileOutputStream(file);javax.imageio.ImageIO.write(img, "png", out);IOUtils.closeQuietly(out);}if (is != null) {IOUtils.closeQuietly(is);}}/*** 将ppt转换为图片,直接保存在内存中,ppt很大时可能会oom!!!** @param is ppt 输入流* @return* @throws IOException*/public static List<byte[]> ppt2Image(InputStream is) throws IOException {// 获取系统可用字体GraphicsEnvironment e          = GraphicsEnvironment.getLocalGraphicsEnvironment();String[]            fontNames  = e.getAvailableFontFamilyNames();List                availFonts = CollectionUtils.arrayToList(fontNames);HSLFSlideShow ppt      = new HSLFSlideShow(new HSLFSlideShowImpl(is));Dimension     pgsize   = ppt.getPageSize();int           pageSize = ppt.getSlides().size();List<byte[]>  imgList  = new ArrayList<>(pageSize);log.info("ppt 总页数:{}, 尺寸: width={},height={}", pageSize, pgsize.width, pgsize.height);for (int i = 0; i < pageSize; i++) {//防止中文乱码for (HSLFShape shape : ppt.getSlides().get(i).getShapes()) {if (shape instanceof HSLFTextShape) {HSLFTextShape tsh = (HSLFTextShape) shape;for (HSLFTextParagraph p : tsh) {for (HSLFTextRun r : p) {String fontFamily = r.getFontFamily();//log.info(">>>>>原始ppt字体:{}", fontFamily);fontFamily = "宋体";//log.info(">>>>>ppt字体修改为:{}", fontFamily);r.setFontFamily(fontFamily);
//                            if (!availFonts.contains(fontFamily)) {
//                                fontFamily = "宋体";
//                                log.info(">>>>>ppt字体修改为:{}", fontFamily);
//                                r.setFontFamily(fontFamily);
//                            }}}}}BufferedImage img      = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);Graphics2D    graphics = img.createGraphics();// clear the drawing areagraphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));// renderppt.getSlides().get(i).draw(graphics);// save the outputByteArrayOutputStream out = new ByteArrayOutputStream();javax.imageio.ImageIO.write(img, "png", out);imgList.add(out.toByteArray());IOUtils.closeQuietly(out);}if (is != null) {IOUtils.closeQuietly(is);}return imgList;}/*** 将ppt转成图片,保存在同一目录的image目录下** @param filePath ppt文件路径* @param fileName ppt 文件名* @throws IOException*/public static void ppt2Image(String filePath, String fileName) throws IOException {// 获取系统可用字体GraphicsEnvironment e          = GraphicsEnvironment.getLocalGraphicsEnvironment();String[]            fontNames  = e.getAvailableFontFamilyNames();List                availFonts = CollectionUtils.arrayToList(fontNames);HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl(filePath + fileName));Dimension pgsize = ppt.getPageSize();for (int i = 0; i < ppt.getSlides().size(); i++) {//防止中文乱码for (HSLFShape shape : ppt.getSlides().get(i).getShapes()) {if (shape instanceof HSLFTextShape) {HSLFTextShape tsh = (HSLFTextShape) shape;for (HSLFTextParagraph p : tsh) {for (HSLFTextRun r : p) {String fontFamily = r.getFontFamily();//log.info(">>>>>原始ppt字体:{}", fontFamily);fontFamily = "宋体";//log.info(">>>>>ppt字体修改为:{}", fontFamily);r.setFontFamily(fontFamily);
//                            if (!availFonts.contains(fontFamily)) {
//                                fontFamily = "宋体";
//                                log.info(">>>>>ppt字体修改为:{}", fontFamily);
//                                r.setFontFamily(fontFamily);
//                            }}}}}BufferedImage img      = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);Graphics2D    graphics = img.createGraphics();// clear the drawing areagraphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));// renderppt.getSlides().get(i).draw(graphics);// save the outputString pptname    = fileName.substring(0, fileName.lastIndexOf("."));String newimgPath = filePath + "image/" + pptname + "/";File   imgPath    = new File(newimgPath);if (!imgPath.exists()) {//图片目录不存在则创建imgPath.mkdirs();}String           file = newimgPath + (i + 1) + ".png";FileOutputStream out  = new FileOutputStream(file);javax.imageio.ImageIO.write(img, "png", out);IOUtils.closeQuietly(out);//resizeImage(filename, filename, width, height);}}/**** 功能 :调整图片大小* @param srcImgPath 原图片路径* @param distImgPath  转换大小后图片路径* @param width   转换后图片宽度* @param height  转换后图片高度*/public static void resizeImage(String srcImgPath, String distImgPath,int width, int height) throws IOException {File          srcFile = new File(srcImgPath);Image         srcImg  = ImageIO.read(srcFile);BufferedImage buffImg = null;buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);buffImg.getGraphics().drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0,0, null);ImageIO.write(buffImg, "JPEG", new File(distImgPath));}/*** 将图片转换成pdf** @return* @throws Exception*/public static byte[] img2PDF(List<byte[]> images) throws Exception {//        Document              doc    = new Document();
//        Document doc = new Document(PageSize.A4, 0, 0, 36.0F, 36.0F);//普通a4com.itextpdf.text.Rectangle pageSize = new com.itextpdf.text.Rectangle(0, 0, width, height); // 自定义页面大小Document                    doc      = new Document(pageSize, 0, 0, 0, 0);log.info(">>>>A4尺寸:width={},height={}", pageSize.getWidth(), pageSize.getHeight());ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();PdfWriter.getInstance(doc, pdfOut);doc.open();float scale = pageSize.getWidth() / width;for (byte[] image : images) {com.itextpdf.text.Image pic = com.itextpdf.text.Image.getInstance(image);pic.setScaleToFitLineWhenOverflow(true);// pic.scaleAbsolute(width, height);pic.scaleToFit(pageSize.getWidth(), height * scale);doc.add(pic);}doc.close();byte[] pdf = pdfOut.toByteArray();IOUtils.closeQuietly(pdfOut);return pdf;}/*** ppt转化为pdf* @param is ppt 输入流* @return pdf 字节文件* @throws Exception*/public static byte[] ppt2PDF(InputStream is) throws Exception {return img2PDF(ppt2Image(is));}/*** pptx转化为pdf* @param is pptx 输入流* @return pdf 字节文件* @throws Exception*/public static byte[] pptx2PDF(InputStream is) throws Exception {return img2PDF(pptx2Image(is));}/*** 图片转pdf** @param img* @param descfolder* @return* @throws Exception*/public static String img2PDF(String imagePath, BufferedImage img, String descfolder) throws Exception {String pdfPath = "";try {//图片操作com.itextpdf.text.Image image = null;File                    file  = new File(descfolder);if (!file.exists()) {file.mkdirs();}pdfPath = descfolder + "/" + System.currentTimeMillis() + ".pdf";String   type = imagePath.substring(imagePath.lastIndexOf(".") + 1);Document doc  = new Document(null, 0, 0, 0, 0);//更换图片图层BufferedImage bufferedImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);bufferedImage.getGraphics().drawImage(img, 0, 0, img.getWidth(), img.getHeight(), null);bufferedImage = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), null).filter(bufferedImage, null);//图片流处理doc.setPageSize(new com.itextpdf.text.Rectangle(bufferedImage.getWidth(), bufferedImage.getHeight()));log.info(bufferedImage.getWidth() + "()()()()()" + bufferedImage.getHeight());ByteArrayOutputStream out  = new ByteArrayOutputStream();boolean               flag = ImageIO.write(bufferedImage, type, out);byte[]                b    = out.toByteArray();image = com.itextpdf.text.Image.getInstance(b);//写入PDFlog.info("写入PDf:" + pdfPath);FileOutputStream fos = new FileOutputStream(pdfPath);PdfWriter.getInstance(doc, fos);doc.open();doc.add(image);doc.close();} catch (IOException e) {e.printStackTrace();} catch (BadElementException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();}return pdfPath;}public static void mergePDF(String[] files, String desfolder, String mergeFileName) throws Exception {PDFMergerUtility mergePdf = new PDFMergerUtility();for (String file : files) {if (file.toLowerCase().endsWith("pdf"))mergePdf.addSource(file);}mergePdf.setDestinationFileName(desfolder + "/" + mergeFileName);mergePdf.mergeDocuments();log.info("merge over");}public static void main(String[] args) throws Exception {// 读入PPT文件String filePath = "D:/test/";String fileName = "docker.pptx";List<byte[]> images = pptx2Image(new FileInputStream(new File(filePath + fileName)));// 输出图片for (int i = 1; i <= images.size(); i++) {String path = filePath + i + ".png";FileOutputStream output = new FileOutputStream(path);IOUtils.write(images.get(i-1), output);IOUtils.closeQuietly(output);}// 输出pdfbyte[]           pdf = pptx2PDF(new FileInputStream(new File(filePath + fileName)));FileOutputStream out = new FileOutputStream("D:/test/docker.pdf");IOUtils.write(pdf, out);IOUtils.closeQuietly(out);}}

执行工具类main函数后测试的效果:

参考文章:

https://blog.csdn.net/huoji555/article/details/88339039

https://www.cnblogs.com/chenpi/p/5534595.html

https://zhanglf.blog.csdn.net/article/details/106853803?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.control


http://www.ppmy.cn/news/502890.html

相关文章

利用python将PDF转为PPT(课件专用)

利用python将PDF转为PPT(课件专用) 前言&#xff1a;课程中老师经常会将课件作为PDF发放而非PPT&#xff0c;而现有的PDF阅读器一般不支持添加修改等操作&#xff0c;所以显得十分麻烦&#xff0c;考虑将PDF转换为PPT格式&#xff0c;方便进行操作。 注意&#xff1a;这里并不是…

PPT怎么转PDF?将Powerpoint(PPT)转换为PDF方法分享

当您在PowerPoint中创建精美的演示文稿时&#xff0c;您不仅想给观众留下深刻的印象&#xff0c;还希望它能够方便地打包&#xff0c;并且文件格式起着重要作用。虽然PPTX是一种广泛传播的格式&#xff0c;但PDF始终是一个安全的选择。以下是有关如何使用在线工具将PowerPoint演…

怎么用Python批量将ppt转换为pdf

这是一个Python脚本&#xff0c;能够批量地将微软Powerpoint文件&#xff08;.ppt或者.pptx&#xff09;转换为pdf格式。 使用说明 1、将这个脚本跟PPT文件放置在同一个文件夹下。 2、运行这个脚本。 全部代码 import comtypes.client import os def init_powerpoint(): powe…

对比学习初认识

这篇文章我们通过SimCLR模型来对对比学习技术有一个认知。 1.什么是对比学习系统 根据上面这个图&#xff0c;来介绍下怎么做一个抽象的对比学习系统。以一个图像为例子&#xff0c;通过自动构造正例或负例&#xff0c;形成图片的两个view&#xff0c;通过encoder把它们编码&a…

手机PDF如何转PPT

在办公方案交流之后&#xff0c;PDF格式文档大多数是不能直接编辑的&#xff0c;所以为了后期方便修改或编辑&#xff0c;很多时候会把PDF文件转换为PPT格式&#xff0c;那么手机怎样将PDF转换为PPT格式呢&#xff1f;小编今天就和大家分享一个简单的方法&#xff0c;一起来看看…

python ppt转图片_ppt一键转图片和pdf

日常工作中经常会需要把 ppt 页面转化成图片&#xff0c;通常我们都是对 ppt 页面截图或者使用 office 工具手动将 ppt 页面保存为图片&#xff0c;如果只有一两页 ppt 需要转化就还好&#xff0c;如果有批量的 ppt 需要处理的话那肯定不能手动来处理了&#xff0c;所以我们今天…

教你怎么免费的将PDF转换成PPT

将PDF文件转换成PPT文件是一种非常有用的技能&#xff0c;因为它可以帮助您将一个PDF文件中的文本、图片和其他内容转换成一个幻灯片演示文稿&#xff0c;这样您可以更方便地展示和分享它。虽然有很多商业软件可以帮助您完成这项任务&#xff0c;但是在本文中&#xff0c;我们将…

pdf转ppt在线转换免费网页版

不知道大家有没有这样的经历&#xff0c;自己想PDF格式转为PPT&#xff0c;但是需要收费。很是苦恼&#xff0c;今天就分享一个我自己用过得免费的PDF转PPT的网站。 1&#xff0c;打开浏览器搜索界面&#xff0c;用“speedpdf在线转换”作为关键词进行搜索&#xff0c;找到并进…