最近做的需求需要实现在线预览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

java实现ppt转图片、ppt转pdf相关推荐

  1. Java实现多个图片转化成PDF

    Java实现多个图片转化成PDF 依赖 <dependency><groupId>com.lowagie</groupId><artifactId>it ...

  2. java使用itextpdf将图片转换成pdf时DPI的问题

    在使用itext转换图片为PDF时,不论原文件的DPI为多少,转出的PDF的DPI均为72 使用Image类的setDpi方法也没用 解决方法如下 import com.itextpdf.text.* ...

  3. java使用itextpdf将图片转换成pdf的简单实例

    1.首先下载itextpdf包. 2.然后倒入到工程,并创建项目 源代码如下: public class Img2Pdf {public static void main(String[] args) ...

  4. java 转dwg转图片_dwg转pdf要怎么转换

    CAD中,CAD图纸的基本保存格式都是dwg格式的,有的时候我们就需要将图中的格式进行转换,那就是讲dwg转pdf.因为pdf格式的文件在查看的时候相对于来说是比较方便的.那么,在CAD中dwg转pd ...

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

    日常工作中经常会需要把 ppt 页面转化成图片,通常我们都是对 ppt 页面截图或者使用 office 工具手动将 ppt 页面保存为图片,如果只有一两页 ppt 需要转化就还好,如果有批量的 ppt ...

  6. ios开发html转图片,iOS | PPT 转图片(UIImage) 解决方案

    为了实现PPT 转 图片功能, 首先来看下,iOS系统 有哪些API可以实现PPT预览功能; iOS 预览PPT 3种方式: 1. UIWebView / wkwebView 通过 UIWebView ...

  7. 制作PPT模板图片排版的创意设计技巧有哪些?

    日常在PPT制作模板过程中,排版关系着整个ppt模板整体风格,今天ppt在线制作-ppt家园就来介绍一个创意的图片排版小技巧. PPT模板 幻灯片模板 PPT模版免费下载 PPT背景图片-PPT家园P ...

  8. Andorid 实现图片转成pdf的方法

    用java语言写的图片转换成pdf 主要介绍了三种图片压缩方法  保存下来 以后学习 参考http://download.csdn.net/download/u010118528/5212196 1 ...

  9. java ppt 转图片格式_Java PPT(X)转图片、PDF和SVG

    (一)简介: 工作中,PowerPoint文档有时需要被转换为PDF/图像文件来存档.因为PDF或图片的页面布局是固定的,很难被修改且能被大多数设备打开,所以PDF或者图片比起PowerPoint格式 ...

  10. Java 批量导出PPT为图片,并合并生成PDF

    Java 批量导出PPT为图片,并合并生成PDF 最近有小伙伴需要把PPT打印,但苦于PPT太多,浪费纸张,所以特别写了这个合并多张PPT到一张A4纸上并生成PDF方便打印的程序: 前期准备 把PPT ...

最新文章

  1. Catel(翻译)-为什么选择Catel
  2. 算法--无重复字符的最长字串(详细)
  3. mysql的left join和inner join的效率对比,以及如何优化
  4. Redux专题:实用
  5. Python使用aiohttp异步爬取糗事百科
  6. 线上Haproxy配置
  7. SpringBoot升级到2.3.x后返回message为空
  8. C语言实现字符串匹配KMP算法
  9. linux网卡IP同一网段,Linux下多网卡不同IP在同一网段的情况
  10. 启动报错 classnofoundexception org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  11. 用于构建高级媒体应用程序的工具
  12. Python数据可视化库——Matplotlib
  13. UnimplementedError: Fused conv implementation does not support grouped convolutions for now
  14. DTC标准故障码格式解析
  15. 计算机编程算法和数学有什么关系?
  16. 职称计算机考试题库word2003,全国职称计算机考试题库(Word2003模块)
  17. 路由器04--OPKG
  18. 冒犯有时是必要的:如何开启一段亲密关系?
  19. 几个常用的后台管理系统
  20. HEIC格式怎么转换?掌握这个方法,轻松实现!

热门文章

  1. 苹果CEO库克亚洲之行总结 未来挑战远大于机遇
  2. “IndentationError: unindent does not match any outer indentation level“ 错误解决
  3. Qt5+vs2017 UI界面添加新控件后,提示没有类成员
  4. Python+Django开发游戏充值管理后台
  5. 用html设计logo,网页设计中的logo设计方法
  6. python九九乘法表代码中的i+1的意思_python---九九乘法表代码
  7. [AI-Steering编程]九.路径跟随
  8. crontab 误删除恢复
  9. word文档怎么找回误删的文件_Word文档删除了怎么恢复?Word误删除恢复技巧
  10. 3小时GIS入门教程(一):为什么要学GIS