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

猜你喜欢

转载自www.cnblogs.com/zh-peng/p/10710135.html