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的文字统一格式。
下面是代码实现类
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文件输出到指定目录的更多相关文章
- vue-webpack项目自动打包压缩成zip文件批处理
为什么需要这个? 使用vue框架开发项目,npm run build这个命令会一直用到,如果需要给后端发包,那你还要打包成zip格式的压缩包,特别是项目提测的时候,一天可能要执行重复好几次,所以才有了 ...
- Vue -- webpack 项目自动打包压缩成zip文件
这段时间用 Vue2.0 开发项目,每次打包都会用到 npm run build 命令,但是每次部署时给后端发包都要手动zip压缩,这样一两次还行,但遇到项目板块测试和临时加急功能测试的时候,一天可能 ...
- linux下压缩成zip文件解压zip文件
linux zip命令的基本用法是: zip [参数] [打包后的文件名] [打包的目录路径] linux zip命令参数列表: -a 将文件转成ASCII模式 -F 尝试修复损坏 ...
- .net 生成html文件后压缩成zip文件并下载
这里只做一个简单的实例 public ActionResult Index() { string path = Server.MapPath("/test/");//文件输出目录 ...
- vue -- vue-cli webpack项目打包后自动压缩成zip文件
用vue2.0开发项目,使用npm run build 命令 ,但是只会生成dist文件夹,以下是生成zip压缩包方法 1,插件安装 webpack插件安装 filemanager-webpack-p ...
- asp.net 把图片压缩成zip之后再进行下载
//这是导出的js方法 function fundaochu() { var data = "keyword=GetImageListdaochu&type=daochu&m ...
- Java实现将文件或者文件夹压缩成zip
最近碰到个需要下载zip压缩包的需求,于是我在网上找了下别人写好的zip工具类.但找了好多篇博客,总是发现有bug.因此就自己来写了个工具类. 这个工具类的功能为: ( ...
- java实现将文件压缩成zip格式
以下是将文件压缩成zip格式的工具类(复制后可以直接使用): zip4j.jar包下载地址:http://www.lingala.net/zip4j/download.php package util ...
- 【转】Java实现将文件或者文件夹压缩成zip
转自:https://www.cnblogs.com/zeng1994/p/7862288.html package com.guo.utils; import java.io.*; import j ...
随机推荐
- & 引用
核心: 对引用的操作与对变量直接操作完全一样注意点: 引用并非是地址运算符 编译器一般将引用看作是const指针,即只占用指针大小空间 引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量.使 ...
- Note | LaTeX
目录 一.TeX家族 1. TeX - LaTeX 2. pdfTeX - pdfLaTeX 3. XeTeX - XeLaTeX 4. CTeX - MiKTeX - TeX Live 二.入门 1 ...
- 可遇不可求的Question之error: Failed dependencies: MySQLconflicts 错误篇
error: Failed dependencies: MySQLconflicts 错误提示: error: Failed dependencies: ...
- 利用ONENET平台透传电脑截图
这个仅供技术学习了 可以用在远程监控等行业,不用传统工具用的公网ip等比较坑爹的东西 还是比较方便的 需要的话请联系微信nbdx123
- 某公司的C#面试题
1. 请简述值类型与引用类型的区别 答: 可参考http://www.cnblogs.com/JimmyZhang/archive/2008/01/31/1059383.html 2.C#中所有引用类 ...
- NLP常用术语解析
分词(Segment):中英文都存在分词的问题,不过相对来说,英文单词与单词之间本来就有空格进行分割,所以处理起来相对方便.但是中文书写是没有分隔符的,所以分词的问题就比较突出.分词常用的手段可以是基 ...
- maya2019卸载/安装失败/如何彻底卸载清除干净maya2019注册表和文件的方法
maya2019提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装maya2019失败提示maya2019安装未完成,某些产品无法安装,也有时候想重新安装maya ...
- Javascript多线程
最近项目中要用一个倒计时,但是当弹窗的时候倒计时会被阻塞,所以我想到使用Javascript多线程解决该问题. 虽然JavaScript是单线程的,但是通过worker可以让Javascript另外开 ...
- 关于elasticsearch function_score的使用
最近做新闻推荐系统,新闻搜索采用的是elasticsearch引擎,为了使推荐更接近用户偏好,搜索时使用了function_score功能对文档进行了重新打分,改变排序规则.以下介绍关于functio ...
- location匹配
=/ 表示精确匹配 www.sensetime.com/ ~ :表示做正则表达式匹配,区分字符大小写 ~* : 表示做正则表达式匹配,不区分大小写 ^~: URI的左半部分匹配,不区分大小写 匹配优 ...