实现流程:

接收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的文字统一格式。

下面是代码实现类

 package com.bs.test;

 import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.imageio.ImageIO;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.hslf.usermodel.HSLFTextRun;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.apache.poi.xslf.usermodel.XSLFTextShape; public class PPTInputStreamtoZipFile { private static File FILE; // inputstream 不能复用,需要复制两个 private static InputStream INPUTSTREAM_1; private static InputStream INPUTSTREAM_2; private static String PPTName; /**
* 将PPT输入流转换成zip压缩文件
*
* @param ZipFilePath
* 输出压缩文件路径+文件名
* 如:"C:\\Users\\Administrator\\Desktop\\ppt_test\\success1.zip"
* @param pptName
* ppt文件名
* @param InputStream
* 输入PPT流
* @param imageFormatNameString
* //图片转化的格式字符串 ,如:"jpg"、"jpeg"、"bmp" "png" "gif" "tiff"
* @param times
* 生成图片放大的倍数,倍数越高,清晰度越高
* @return 图片名列表
*/
public static List<String> convert(String ZipFilePath, String pptName, InputStream InputStream,
String imageFormatNameString, int times)throws Exception{
// 复制
ByteArrayOutputStream baos = cloneInputStream(InputStream);
INPUTSTREAM_1 = new ByteArrayInputStream(baos.toByteArray());
INPUTSTREAM_2 = new ByteArrayInputStream(baos.toByteArray()); PPTName = pptName;
FILE = new File(ZipFilePath);
List<String> imgList = new ArrayList<>();
List<String> imgNamesList = new ArrayList<String>();// PPT转成图片后所有名称集合
HSLFSlideShow oneHSLFSlideShow = null;
XMLSlideShow xmlSlideShow = null;
Dimension onePPTPageSize = null;
List<HSLFSlide> HSLFSlideList = null;
List<XSLFSlide> XSLFSlideList = null; // 创造一个zip格式的文件
FileOutputStream zipOut;
zipOut = new FileOutputStream(FILE);
ZipOutputStream zipOutputStream = new ZipOutputStream(zipOut); try {
oneHSLFSlideShow = new HSLFSlideShow(INPUTSTREAM_1);
// 获取PPT每页的大小(宽和高度)
onePPTPageSize = oneHSLFSlideShow.getPageSize();
// 获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转为一张张的播放片
HSLFSlideList = oneHSLFSlideShow.getSlides();
// 下面循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作
for (int i = 0; i < HSLFSlideList.size(); i++) {
// 这几个循环只要是设置字体为宋体,防止中文乱码,
List<List<HSLFTextParagraph>> oneTextParagraphs = HSLFSlideList.get(i).getTextParagraphs();
for (List<HSLFTextParagraph> list : oneTextParagraphs) {
for (HSLFTextParagraph hslfTextParagraph : list) {
List<HSLFTextRun> HSLFTextRunList = hslfTextParagraph.getTextRuns();
for (int j = 0; j < HSLFTextRunList.size(); j++) {
// 设置字体大小
Double size = HSLFTextRunList.get(j).getFontSize();
if ((size <= 0) || (size >= 26040)) {
HSLFTextRunList.get(j).setFontSize(20.0);
}
// 设置字体样式为宋体
HSLFTextRunList.get(j).setFontFamily("宋体"); }
} }
// 创建BufferedImage对象,图像的尺寸为原来的每页的尺寸*倍数times
BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width * times,
onePPTPageSize.height * times, BufferedImage.TYPE_INT_RGB);
Graphics2D oneGraphics2D = oneBufferedImage.createGraphics();
// 设置转换后的图片背景色为白色
oneGraphics2D.setPaint(Color.white);
oneGraphics2D.scale(times, times);// 将图片放大times倍
oneGraphics2D
.fill(new Rectangle2D.Float(0, 0, onePPTPageSize.width * times, onePPTPageSize.height * times));
HSLFSlideList.get(i).draw(oneGraphics2D);
// 设置图片的存放路径和图片格式,注意生成的图片路径为绝对路径,最终获得各个图像文件所对应的输出流对象
String imgName = PPTName + "_" + (i + 1) + "." + imageFormatNameString;
imgNamesList.add(imgName);// 将图片名称添加的集合中
imgList.add(imgName);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(oneBufferedImage, imageFormatNameString, os);
compressFile(os.toByteArray(), zipOutputStream, imgName);
}
} catch (Exception e) {
xmlSlideShow = new XMLSlideShow(INPUTSTREAM_2);
// 获取PPT每页的大小(宽和高度)
onePPTPageSize = xmlSlideShow.getPageSize();
// 获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转为一张张的播放片
XSLFSlideList = xmlSlideShow.getSlides();
// 下面循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作
for (int i = 0; i < XSLFSlideList.size(); i++) {
// 这几个循环只要是设置字体为宋体,防止中文乱码,
for (XSLFShape shape : XSLFSlideList.get(i).getShapes()) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape txtshape = (XSLFTextShape) shape;
for (XSLFTextParagraph textPara : txtshape.getTextParagraphs()) {
List<XSLFTextRun> textRunList = textPara.getTextRuns();
for (XSLFTextRun textRun : textRunList) {
textRun.setFontFamily("宋体");
}
}
}
}
// 创建BufferedImage对象,图像的尺寸为原来的每页的尺寸*倍数times
BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width * times,
onePPTPageSize.height * times, BufferedImage.TYPE_INT_RGB);
Graphics2D oneGraphics2D = oneBufferedImage.createGraphics();
// 设置转换后的图片背景色为白色
oneGraphics2D.setPaint(Color.white);
oneGraphics2D.scale(times, times);// 将图片放大times倍
oneGraphics2D
.fill(new Rectangle2D.Float(0, 0, onePPTPageSize.width * times, onePPTPageSize.height * times));
XSLFSlideList.get(i).draw(oneGraphics2D);
// 设置图片的存放路径和图片格式,注意生成的图片路径为绝对路径,最终获得各个图像文件所对应的输出流对象
String imgName = PPTName + "_" + (i + 1) + "." + imageFormatNameString;
imgNamesList.add(imgName);// 将图片名称添加的集合中
imgList.add(imgName);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(oneBufferedImage, imageFormatNameString, os);
compressFile(os.toByteArray(), zipOutputStream, imgName);
}
} finally { zipOutputStream.close();
}
return imgList;
} /**
* 检查是否为ppt文件
*
* @param file
* @return
*/
public static boolean checkIsPPTFile(File file) {
boolean isppt = false;
String filename = file.getName();
String suffixname = null;
if (filename != null && filename.indexOf(".") != -1) {
suffixname = filename.substring(filename.lastIndexOf("."));
if (suffixname.equals(".ppt") || suffixname.equals(".pptx")) {
isppt = true;
}
return isppt;
} else {
return isppt;
}
} /*
* copy InputStream
*
*/
private static ByteArrayOutputStream cloneInputStream(InputStream input) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
} catch (IOException e) {
e.printStackTrace();
return null;
}
} /**
* 将byte数组数据写入文件
* @param byteIn 数据
* @param zipOutputStream 输出流
* @param imgName 文件名
*/
public static void compressFile(byte[] byteIn, ZipOutputStream zipOutputStream, String imgName) {
try {
ZipEntry zipEntry1 = new ZipEntry(imgName);
zipOutputStream.putNextEntry(zipEntry1);
zipOutputStream.write(byteIn, 0, byteIn.length);
} catch (Exception e) {
}
} public static void main(String[] args) throws Exception { InputStream iStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\ppt_test\\test.pptx"); convert("C:\\Users\\Administrator\\Desktop\\ppt_test\\success4.zip", "test_ppt", iStream, "jpg", 8);
}
}

PPT文件流转为图片,并压缩成ZIP文件输出到指定目录的更多相关文章

  1. vue-webpack项目自动打包压缩成zip文件批处理

    为什么需要这个? 使用vue框架开发项目,npm run build这个命令会一直用到,如果需要给后端发包,那你还要打包成zip格式的压缩包,特别是项目提测的时候,一天可能要执行重复好几次,所以才有了 ...

  2. Vue -- webpack 项目自动打包压缩成zip文件

    这段时间用 Vue2.0 开发项目,每次打包都会用到 npm run build 命令,但是每次部署时给后端发包都要手动zip压缩,这样一两次还行,但遇到项目板块测试和临时加急功能测试的时候,一天可能 ...

  3. linux下压缩成zip文件解压zip文件

    linux  zip命令的基本用法是: zip [参数] [打包后的文件名] [打包的目录路径] linux  zip命令参数列表: -a     将文件转成ASCII模式 -F     尝试修复损坏 ...

  4. .net 生成html文件后压缩成zip文件并下载

    这里只做一个简单的实例 public ActionResult Index() { string path = Server.MapPath("/test/");//文件输出目录 ...

  5. vue -- vue-cli webpack项目打包后自动压缩成zip文件

    用vue2.0开发项目,使用npm run build 命令 ,但是只会生成dist文件夹,以下是生成zip压缩包方法 1,插件安装 webpack插件安装 filemanager-webpack-p ...

  6. asp.net 把图片压缩成zip之后再进行下载

    //这是导出的js方法 function fundaochu() { var data = "keyword=GetImageListdaochu&type=daochu&m ...

  7. Java实现将文件或者文件夹压缩成zip

            最近碰到个需要下载zip压缩包的需求,于是我在网上找了下别人写好的zip工具类.但找了好多篇博客,总是发现有bug.因此就自己来写了个工具类.         这个工具类的功能为: ( ...

  8. java实现将文件压缩成zip格式

    以下是将文件压缩成zip格式的工具类(复制后可以直接使用): zip4j.jar包下载地址:http://www.lingala.net/zip4j/download.php package util ...

  9. 【转】Java实现将文件或者文件夹压缩成zip

    转自:https://www.cnblogs.com/zeng1994/p/7862288.html package com.guo.utils; import java.io.*; import j ...

随机推荐

  1. ota升级动画背景色修改

    https://wenku.baidu.com/view/0d63ad25192e45361066f549.html https://blog.csdn.net/huangyabin001/artic ...

  2. [BOT]自定义ViewPagerStripIndicator

    效果图 app中下面这样的控件很常见,像默认的TabHost表现上不够灵活,下面就简单写一个可以结合ViewPager切换内容显示,提供底部"滑动条"指示所显示页签的效果. 这里控 ...

  3. phpMyAdmin 4.7.x CSRF 漏洞利用

    作者:Ambulong phpMyAdmin是个知名MySQL/MariaDB在线管理工具,phpMyAdmin团队在4.7.7版本中修复了一个危害严重的CSRF漏洞(PMASA-2017-9),攻击 ...

  4. Java 实现网络图片的读取与下载

    //网络图片的下载,读取与删除 public static void fileDowAndDel(String httpurl){ try { URL url = new URL(httpurl); ...

  5. Java面试集合(一)

    前言 大家好,给大家带来Java面试集合(一)的概述,希望你们喜欢 一 1.Java按应用范围可划分几个版本? 答:Java按应用范围有三个版本,分别是JavaSE,JavaEE,JavaME. 2. ...

  6. cc、gcc、g++、CC的区别和联系

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  7. python3模块: os

    简介 os模块主要用于提供系统高级别的操作. 常用方法 os.access(path, mode) # 检验权限模式 os.chdir(path) # 改变当前工作目录 os.chflags(path ...

  8. 10-部署配置dashboard插件

    配置和安装 dashboard 官方文件目录:kubernetes/cluster/addons/dashboard 我们需要使用的yaml文件 $ ls *.yaml dashboard-contr ...

  9. window7利用Nexus搭建maven私有服务器

    下载地址 https://www.sonatype.com/oss-thank-you-win64.zip: cmd管理员运行命令 nexus.exe/install Nexus Service:(n ...

  10. 测试工具之Jmeter(各部件简单介绍)

    jmeter可以到官网下载: http://jakarta.apache.org/ 下载后解压即可使用,双击如下文件打开Jmeter界面: $JMETER_HOME\apache-jmeter-3.1 ...