package cn.hls.xjx.util.ossUtil;
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.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
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.XSLFSlide;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import cn.hls.xjx.constant.Constant;
import cn.hls.xjx.util.Dfs2FileUtil;
import cn.hls.xjx.util.UserFlagUtil;
import sun.plugin2.util.SystemUtil;
/**
* @Description: ppt只转为image
* @author: fuxb
* @date:2020年7月22日 下午4:17:02
* @version 1.0
*/
public class PPTToImagesUtil {
private static String imgSuffixName = "png";
private static Logger logger= LoggerFactory.getLogger(PPTToImagesUtil.class);
private static String separator= File.separator;
private static String imageDir = separator+"pptImages"+separator;
/**
* @Description: ppt只转为image 支持ppt,pptx 其他格式返回false
* @author fuxb
* @date 2020年7月22日 下午4:32:49
* @param inputStream
* @param fileName 文件名称 a.ppt
* @param contextPath 项目的绝对路径 E:\test
* @return map flag true-转换成功 false-转换失败
*/
public static Map<String,Object> pptTtoImages(InputStream inputStream,String fileName,String contextPath) throws IOException{
Map<String,Object> result = new HashMap<>();
contextPath = contextPath.replace("\\",separator)+imageDir;
if(fileName.endsWith(".pptx")){
logger.info("pptx转图片开始");
result = PPTToImagesUtil.converPPTXtoImage(inputStream,contextPath);
logger.info("pptx转图片结束");
}else if(fileName.endsWith(".ppt")){
logger.info("pptx转图片开始");
result = PPTToImagesUtil.converPPTtoImage(inputStream,contextPath);
logger.info("pptx转图片结束");
}else{
logger.error("ppt转image失败,只支持ppt,pptx格式的文件!");
result.put("flag",false);
return result;
}
result.put("flag",true);
return result;
}
/**
* @Description: 将PPTX 文件转换成image
* 转换成后需要将存放图片的文件夹删除掉
* @author fuxb
* @date 2020年7月22日 下午4:34:19
* @param inputStream
* @return Map<String,Object> newFile-生成的图片所在的文件夹 imgUrlList-生成的图片绝对路径集合
*/
public static Map<String,Object> converPPTXtoImage(InputStream inputStream,String absolutePath) throws IOException{
Map<String,Object> result = new HashMap<>();
//上传后的图片路径集合
List<String> imgUrls = new ArrayList<>();
FileOutputStream orignalPPTFileOutStream=null;
XMLSlideShow oneSlideShow=null;
try{
oneSlideShow=new XMLSlideShow(inputStream);
//获取PPT每页的尺寸大小(宽和高度)
Dimension onePPTPageSize=oneSlideShow.getPageSize();
//获取PPT文件中的所有PPT页面,并转换为一张张播放片
List<XSLFSlide> pptPageXSLFSLiseList= oneSlideShow.getSlides();
String xmlFontFormat="<xml-fragment xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"+
"<a:rPr lang=\"zh-CN\" altLang=\"en-US\" dirty=\"0\" smtClean=\"0\"> "+
"<a:latin typeface=\"+mj-ea\"/> "+
"</a:rPr>"+
"</xml-fragment>";
logger.info("生成的图片路径是"+absolutePath);
File newFile = new File(absolutePath);
for (int i = 0; i < pptPageXSLFSLiseList.size(); i++) {
//设置中文为宋体,解决中文乱码问题
CTSlide oneCTSlide=pptPageXSLFSLiseList.get(i).getXmlObject();
CTGroupShape oneCTGroupShape=oneCTSlide.getCSld().getSpTree();
List<CTShape> oneCTShapeList=oneCTGroupShape.getSpList();
for (CTShape ctShape : oneCTShapeList) {
CTTextBody oneCTTextBody = ctShape.getTxBody();
if(null==oneCTTextBody){
continue;
}
CTTextParagraph[] oneCTTextParagraph= oneCTTextBody.getPArray();
CTTextFont oneCTTextFont=null;
try {
oneCTTextFont=CTTextFont.Factory.parse(xmlFontFormat);
} catch (XmlException e) {
e.printStackTrace();
}
for (CTTextParagraph ctTextParagraph : oneCTTextParagraph) {
CTRegularTextRun[] onrCTRegularTextRunArray=ctTextParagraph.getRArray();
for (CTRegularTextRun ctRegularTextRun : onrCTRegularTextRunArray) {
CTTextCharacterProperties oneCTTextCharacterProperties =ctRegularTextRun.getRPr();
if(oneCTTextCharacterProperties != null){
oneCTTextCharacterProperties.setLatin(oneCTTextFont);
}
}
}
}
//创建BufferedImage 对象,图像尺寸为原来的PPT的每页尺寸
BufferedImage oneBufferedImage=new BufferedImage(onePPTPageSize.width, onePPTPageSize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D oneGraphics2D = oneBufferedImage.createGraphics();
//将PPT文件中的每个页面中的相关内容画到转换后的图片中
pptPageXSLFSLiseList.get(i).draw(oneGraphics2D);
//设置图片的存放路径和图片格式,注意生成的文件路径为绝对路径,最终获得各个图像文件所对应的输出流的对象
String imgName=(i+1)+"_"+UserFlagUtil.getShortUUID()+"."+imgSuffixName;
if (!newFile.exists() && !newFile.isDirectory()){
newFile.mkdir();
}
orignalPPTFileOutStream=new FileOutputStream(absolutePath+imgName);
//将转换后的各个图片文件保存在输出流目录中
ImageIO.write(oneBufferedImage, imgSuffixName, orignalPPTFileOutStream);
imgUrls.add(absolutePath+imgName);
}
result.put("newFile", newFile);
result.put("imgUrlList", imgUrls);
} finally{
try {
if(inputStream!=null){
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(orignalPPTFileOutStream!=null){
orignalPPTFileOutStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* @Description: 将PPT 文件转换成image
* 转换成后需要将存放图片的文件夹删除掉
* @author fuxb
* @date 2020年7月22日 下午4:34:19
* @param inputStream
* @return Map<String,Object> newFile-生成的图片所在的文件夹 imgUrlList-生成的图片绝对路径集合
*/
public static Map<String,Object> converPPTtoImage(InputStream inputStream,String absolutePath) throws IOException{
Map<String,Object> result = new HashMap<String, Object>();
//上传后的图片路径集合
List<String> imgUrls = new ArrayList<>();
FileOutputStream orignalPPTFileOutStream=null;
HSLFSlideShow oneHSLFSlideShow=null;
try{
oneHSLFSlideShow=new HSLFSlideShow(inputStream);
//获取PPT每页的大小(宽和高度)
Dimension onePPTPageSize= oneHSLFSlideShow.getPageSize();
//获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转为一张张的播放片
List<HSLFSlide> pptPageSlideList=oneHSLFSlideShow.getSlides();
File newFile = new File(absolutePath);
//下面循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作
for (int i = 0; i <pptPageSlideList.size(); i++) {
//这几个循环只要是设置字体为宋体,防止中文乱码,
List<List<HSLFTextParagraph>> oneTextParagraphs=pptPageSlideList.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++) {
/*
* 如果PPT在WPS中保存过,则 HSLFTextRunList.get(j).getFontSize();的值为0或者26040,
* 因此首先识别当前文本框内的字体尺寸是否为0或者大于26040,则设置默认的字体尺寸。
*/
//设置字体大小
Double size= HSLFTextRunList.get(j).getFontSize();
if((size<=0)||(size>=26040)){
HSLFTextRunList.get(j).setFontSize(20.0);
}
//设置字体样式为宋体
//String family=HSLFTextRunList.get(j).getFontFamily();
HSLFTextRunList.get(j).setFontFamily("宋体");
}
}
}
//创建BufferedImage对象,图像的尺寸为原来的每页的尺寸
BufferedImage oneBufferedImage=new BufferedImage(onePPTPageSize.width, onePPTPageSize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D oneGraphics2D=oneBufferedImage.createGraphics();
//设置转换后的图片背景色为白色
oneGraphics2D.setPaint(Color.white);
oneGraphics2D.fill(new Rectangle2D.Float(0,0,onePPTPageSize.width,onePPTPageSize.height));
pptPageSlideList.get(i).draw(oneGraphics2D);
//设置图片的存放路径和图片格式,注意生成的图片路径为绝对路径,最终获得各个图像文件所对应的输出流对象
String imgName=(i+1)+"_"+UserFlagUtil.getShortUUID()+"."+imgSuffixName;
if (!newFile.exists() && !newFile.isDirectory()){
newFile.mkdir();
}
orignalPPTFileOutStream=new FileOutputStream(absolutePath+imgName);
//转换后的图片文件保存的指定的目录中
ImageIO.write(oneBufferedImage, imgSuffixName, orignalPPTFileOutStream);
imgUrls.add(absolutePath+imgName);
}
result.put("newFile", newFile);
result.put("imgUrlList", imgUrls);
}finally{
try {
if(inputStream!=null){
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(orignalPPTFileOutStream!=null){
orignalPPTFileOutStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/*
* @Description: 生成image的名称
* @author fuxb
* @date 2020年7月22日 下午4:49:31
* @return
*/
public static String getImageName(){
return UserFlagUtil.getShortUUID()+"."+imgSuffixName;
}
}