实现流程:
接收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 }