zoukankan      html  css  js  c++  java
  • PPT文件流转为图片,并压缩成ZIP文件输出到指定目录

    实现流程:

    接收InputStream流->复制流->InputStream流转为PPT->PPT转为图片->所有图片压缩到一个压缩文件下

    注意:

    1.PPT文件分为2003和2007版本,即PPT和pptx格式。

    因为PPT存在这两种格式,所以在不确定接收的InputStream流是由PPT格式还是PPTX格式转化而来的情况下,只能把这两种情况都考虑进去,实现兼容。

    2.InputStream流是不可以复用的

    因为PPT处理方式不同,在使用过一种处理方式后,另一种方式再使用InputStream流时会报stream closed异常或是识别不到文件格式的错误。

    我的解决办法就是copy,进入方法前先把InputStream复制两份放到全局静态变量里。

    3.PPT转图片,文字可能会变成□□□,需要先把PPT的文字统一格式。

    下面是代码实现类

      1 package com.bs.test;
      2 
      3 import java.awt.Color;
      4 import java.awt.Dimension;
      5 import java.awt.Graphics2D;
      6 import java.awt.geom.Rectangle2D;
      7 import java.awt.image.BufferedImage;
      8 import java.io.ByteArrayInputStream;
      9 import java.io.ByteArrayOutputStream;
     10 import java.io.File;
     11 import java.io.FileInputStream;
     12 import java.io.FileOutputStream;
     13 import java.io.IOException;
     14 import java.io.InputStream;
     15 import java.util.ArrayList;
     16 import java.util.List;
     17 import java.util.zip.ZipEntry;
     18 import java.util.zip.ZipOutputStream;
     19 import javax.imageio.ImageIO;
     20 import org.apache.poi.hslf.usermodel.HSLFSlide;
     21 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
     22 import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
     23 import org.apache.poi.hslf.usermodel.HSLFTextRun;
     24 import org.apache.poi.xslf.usermodel.XMLSlideShow;
     25 import org.apache.poi.xslf.usermodel.XSLFShape;
     26 import org.apache.poi.xslf.usermodel.XSLFSlide;
     27 import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
     28 import org.apache.poi.xslf.usermodel.XSLFTextRun;
     29 import org.apache.poi.xslf.usermodel.XSLFTextShape;
     30 
     31 public class PPTInputStreamtoZipFile {
     32 
     33     private static File FILE;
     34 
     35     // inputstream 不能复用,需要复制两个
     36 
     37     private static InputStream INPUTSTREAM_1;
     38 
     39     private static InputStream INPUTSTREAM_2;
     40 
     41     private static String PPTName;
     42 
     43     /**
     44      * 将PPT输入流转换成zip压缩文件
     45      * 
     46      * @param ZipFilePath
     47      *            输出压缩文件路径+文件名
     48      *            如:"C:\Users\Administrator\Desktop\ppt_test\success1.zip"
     49      * @param pptName
     50      *            ppt文件名
     51      * @param InputStream
     52      *            输入PPT流
     53      * @param imageFormatNameString
     54      *            //图片转化的格式字符串 ,如:"jpg"、"jpeg"、"bmp" "png" "gif" "tiff"
     55      * @param times
     56      *            生成图片放大的倍数,倍数越高,清晰度越高
     57      * @return 图片名列表
     58      */
     59     public static List<String> convert(String ZipFilePath, String pptName, InputStream InputStream,
     60             String imageFormatNameString, int times)throws Exception{
     61         // 复制
     62         ByteArrayOutputStream baos = cloneInputStream(InputStream);
     63         INPUTSTREAM_1 = new ByteArrayInputStream(baos.toByteArray());
     64         INPUTSTREAM_2 = new ByteArrayInputStream(baos.toByteArray());
     65 
     66         PPTName = pptName;
     67         FILE = new File(ZipFilePath);
     68         List<String> imgList = new ArrayList<>();
     69         List<String> imgNamesList = new ArrayList<String>();// PPT转成图片后所有名称集合
     70         HSLFSlideShow oneHSLFSlideShow = null;
     71         XMLSlideShow xmlSlideShow = null;
     72         Dimension onePPTPageSize = null;
     73         List<HSLFSlide> HSLFSlideList = null;
     74         List<XSLFSlide> XSLFSlideList = null;
     75 
     76         // 创造一个zip格式的文件
     77         FileOutputStream zipOut;
     78         zipOut = new FileOutputStream(FILE);
     79         ZipOutputStream zipOutputStream = new ZipOutputStream(zipOut);
     80 
     81         try {
     82             oneHSLFSlideShow = new HSLFSlideShow(INPUTSTREAM_1);
     83             // 获取PPT每页的大小(宽和高度)
     84             onePPTPageSize = oneHSLFSlideShow.getPageSize();
     85             // 获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转为一张张的播放片
     86             HSLFSlideList = oneHSLFSlideShow.getSlides();
     87             // 下面循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作
     88             for (int i = 0; i < HSLFSlideList.size(); i++) {
     89                 // 这几个循环只要是设置字体为宋体,防止中文乱码,
     90                 List<List<HSLFTextParagraph>> oneTextParagraphs = HSLFSlideList.get(i).getTextParagraphs();
     91                 for (List<HSLFTextParagraph> list : oneTextParagraphs) {
     92                     for (HSLFTextParagraph hslfTextParagraph : list) {
     93                         List<HSLFTextRun> HSLFTextRunList = hslfTextParagraph.getTextRuns();
     94                         for (int j = 0; j < HSLFTextRunList.size(); j++) {
     95                             // 设置字体大小
     96                             Double size = HSLFTextRunList.get(j).getFontSize();
     97                             if ((size <= 0) || (size >= 26040)) {
     98                                 HSLFTextRunList.get(j).setFontSize(20.0);
     99                             }
    100                             // 设置字体样式为宋体
    101                             HSLFTextRunList.get(j).setFontFamily("宋体");
    102 
    103                         }
    104                     }
    105 
    106                 }
    107                 // 创建BufferedImage对象,图像的尺寸为原来的每页的尺寸*倍数times
    108                 BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width * times,
    109                         onePPTPageSize.height * times, BufferedImage.TYPE_INT_RGB);
    110                 Graphics2D oneGraphics2D = oneBufferedImage.createGraphics();
    111                 // 设置转换后的图片背景色为白色
    112                 oneGraphics2D.setPaint(Color.white);
    113                 oneGraphics2D.scale(times, times);// 将图片放大times倍
    114                 oneGraphics2D
    115                         .fill(new Rectangle2D.Float(0, 0, onePPTPageSize.width * times, onePPTPageSize.height * times));
    116                 HSLFSlideList.get(i).draw(oneGraphics2D);
    117                 // 设置图片的存放路径和图片格式,注意生成的图片路径为绝对路径,最终获得各个图像文件所对应的输出流对象
    118                 String imgName = PPTName + "_" + (i + 1) + "." + imageFormatNameString;
    119                 imgNamesList.add(imgName);// 将图片名称添加的集合中
    120                 imgList.add(imgName);
    121                 ByteArrayOutputStream os = new ByteArrayOutputStream();
    122                 ImageIO.write(oneBufferedImage, imageFormatNameString, os);
    123                 compressFile(os.toByteArray(), zipOutputStream, imgName);
    124             }
    125         } catch (Exception e) {
    126             xmlSlideShow = new XMLSlideShow(INPUTSTREAM_2);
    127             // 获取PPT每页的大小(宽和高度)
    128             onePPTPageSize = xmlSlideShow.getPageSize();
    129             // 获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转为一张张的播放片
    130             XSLFSlideList = xmlSlideShow.getSlides();
    131             // 下面循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作
    132             for (int i = 0; i < XSLFSlideList.size(); i++) {
    133                 // 这几个循环只要是设置字体为宋体,防止中文乱码,
    134                 for (XSLFShape shape : XSLFSlideList.get(i).getShapes()) {
    135                     if (shape instanceof XSLFTextShape) {
    136                         XSLFTextShape txtshape = (XSLFTextShape) shape;
    137                         for (XSLFTextParagraph textPara : txtshape.getTextParagraphs()) {
    138                             List<XSLFTextRun> textRunList = textPara.getTextRuns();
    139                             for (XSLFTextRun textRun : textRunList) {
    140                                 textRun.setFontFamily("宋体");
    141                             }
    142                         }
    143                     }
    144                 }
    145                 // 创建BufferedImage对象,图像的尺寸为原来的每页的尺寸*倍数times
    146                 BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width * times,
    147                         onePPTPageSize.height * times, BufferedImage.TYPE_INT_RGB);
    148                 Graphics2D oneGraphics2D = oneBufferedImage.createGraphics();
    149                 // 设置转换后的图片背景色为白色
    150                 oneGraphics2D.setPaint(Color.white);
    151                 oneGraphics2D.scale(times, times);// 将图片放大times倍
    152                 oneGraphics2D
    153                         .fill(new Rectangle2D.Float(0, 0, onePPTPageSize.width * times, onePPTPageSize.height * times));
    154                 XSLFSlideList.get(i).draw(oneGraphics2D);
    155                 // 设置图片的存放路径和图片格式,注意生成的图片路径为绝对路径,最终获得各个图像文件所对应的输出流对象
    156                 String imgName = PPTName + "_" + (i + 1) + "." + imageFormatNameString;
    157                 imgNamesList.add(imgName);// 将图片名称添加的集合中
    158                 imgList.add(imgName);
    159                 ByteArrayOutputStream os = new ByteArrayOutputStream();
    160                 ImageIO.write(oneBufferedImage, imageFormatNameString, os);
    161                 compressFile(os.toByteArray(), zipOutputStream, imgName);
    162             }
    163         } finally {
    164 
    165             zipOutputStream.close();
    166         }
    167         return imgList;
    168     }
    169 
    170     /**
    171      * 检查是否为ppt文件
    172      * 
    173      * @param file
    174      * @return
    175      */
    176     public static boolean checkIsPPTFile(File file) {
    177         boolean isppt = false;
    178         String filename = file.getName();
    179         String suffixname = null;
    180         if (filename != null && filename.indexOf(".") != -1) {
    181             suffixname = filename.substring(filename.lastIndexOf("."));
    182             if (suffixname.equals(".ppt") || suffixname.equals(".pptx")) {
    183                 isppt = true;
    184             }
    185             return isppt;
    186         } else {
    187             return isppt;
    188         }
    189     }
    190 
    191     /*
    192      * copy InputStream
    193      * 
    194      */
    195     private static ByteArrayOutputStream cloneInputStream(InputStream input) {
    196         try {
    197             ByteArrayOutputStream baos = new ByteArrayOutputStream();
    198             byte[] buffer = new byte[1024];
    199             int len;
    200             while ((len = input.read(buffer)) > -1) {
    201                 baos.write(buffer, 0, len);
    202             }
    203             baos.flush();
    204             return baos;
    205         } catch (IOException e) {
    206             e.printStackTrace();
    207             return null;
    208         }
    209     }
    210 
    211     /**
    212      * 将byte数组数据写入文件
    213      * @param byteIn 数据
    214      * @param zipOutputStream 输出流
    215      * @param imgName 文件名
    216      */
    217     public static void compressFile(byte[] byteIn, ZipOutputStream zipOutputStream, String imgName) {
    218         try {
    219             ZipEntry zipEntry1 = new ZipEntry(imgName);
    220             zipOutputStream.putNextEntry(zipEntry1);
    221             zipOutputStream.write(byteIn, 0, byteIn.length);
    222         } catch (Exception e) {
    223         }
    224     }
    225 
    226     public static void main(String[] args) throws Exception {
    227 
    228         InputStream iStream = new FileInputStream("C:\Users\Administrator\Desktop\ppt_test\test.pptx");
    229 
    230         convert("C:\Users\Administrator\Desktop\ppt_test\success4.zip", "test_ppt", iStream, "jpg", 8);
    231     }
    232 }
    View Code
  • 相关阅读:
    RocketMQ主从搭建
    Spring Cloud Sleuth
    Spring Cloud Eureka
    Nacos配置中心使用
    Nacos注册中心使用
    Nacos快速入门
    Nginx配置SSL
    并发工具类
    关于类的线程安全
    Docker 入门学习笔记(一)
  • 原文地址:https://www.cnblogs.com/zh-peng/p/10710135.html
Copyright © 2011-2022 走看看