1. 程式人生 > >java 使用poi將PPT轉為圖片,線上預覽PPT

java 使用poi將PPT轉為圖片,線上預覽PPT

線上預覽PPT,我的思路為java 使用poi將PPT轉為圖片,圖片儲存到指定的資料夾下面,然後返回生成的圖片名稱集合,將圖片路徑遍歷到前臺的html標籤上,用HTML前臺模仿畫一個PPT框架,操作圖片地址路徑從而實現模擬線上預覽的效果;前臺程式碼省略,如下是後臺的一個工具類,拿去直接可以用(但前提是不要忘記匯入POI jar包哦!!),使用哪些jar包也寫在下面了,寫在這裡,後面自己在用時方便,也為後人方便吧

package com;

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.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.hslf.extractor.PowerPointExtractor;
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.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
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;

/**
 * PPT轉image工具類
 * 使用的Apache poi-3.14的版本  依賴第三方jar包:poi-3.14-20160307.jar、poi-ooxml-3.14-20160307.jar、
 * 										poi-ooxml-schemas-3.14-20160307.jar、poi-scratchpad-3.14-20160307.jar、xmlbeans-2.6.0.jar
 * @author yds 
 * @date 2017-03-22
 *
 */
public class ConverPPTFileToImageUtil {
	

	/**
	 * 將PPTX 檔案轉換成image
	 * @param orignalPPTFileName  //PPTX檔案路徑 如:d:/demo/demo1.pptx
	 * @param targetImageFileDir //轉換後的圖片儲存路徑 如:d:/demo/pptxImg
	 * @param imageFormatNameString //圖片轉化的格式字串 ,如:"jpg"、"jpeg"、"bmp" "png" "gif" "tiff"
	 * @return Map<String,Object>
	 * 	key: converReturnResult   型別:boolean 轉化結果 true 代表轉換成功,false 代表轉換失敗
	 * 	key:imgNames			  型別:List<String> 轉換成功後圖片的全部名稱集合
	 * 	注:獲取“imgNames”圖片名稱集合時,請先判斷“converReturnResult” 是否為true;如果有一張轉換失敗則為false
	 */
	@SuppressWarnings("resource")
	public static  Map<String,Object> converPPTXtoImage(String orignalPPTFileName,String targetImageFileDir,
			String imageFormatNameString){
		Map<String,Object> map=new HashMap<String, Object>();
		boolean converReturnResult=true;//是否全部轉成功
		List<String> imgNamesList=new ArrayList<String>();//PPT轉成圖片後所有名稱集合
		
		
		FileInputStream orignalPPTFileInputStream=null;
		FileOutputStream orignalPPTFileOutStream=null;
		XMLSlideShow oneSlideShow=null;
		
		try{
			try {
				orignalPPTFileInputStream=new FileInputStream(orignalPPTFileName);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				converReturnResult=false;
				map.put("converReturnResult", converReturnResult);
				return map;
			}
			
			try {
				oneSlideShow=new XMLSlideShow(orignalPPTFileInputStream);
			} catch (IOException e) {
				e.printStackTrace();
				converReturnResult=false;
				map.put("converReturnResult", converReturnResult);
				return map;
			}
			//獲取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>";  
			
			
			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();
							 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);
				 /**
				  * 設定圖片的存放路徑和圖片格式,注意生成的檔案路徑為絕對路徑,最終獲得各個影象檔案所對應的輸出流的物件
				  */
				 
				 try {
					 String imgName=(i+1)+"_"+UUID.randomUUID().toString()+"."+imageFormatNameString;
					 imgNamesList.add(imgName);//將圖片名稱新增的集合中
					 
					 orignalPPTFileOutStream=new FileOutputStream(targetImageFileDir+imgName);
//					orignalPPTFileOutStream=new FileOutputStream(targetImageFileDir+(i+1)+"_"+UUID.randomUUID().toString()+"."+imageFormatNameString);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
					converReturnResult=false;
					map.put("converReturnResult", converReturnResult);
					return map;
				}
				 
				 //將轉換後的各個圖片檔案儲存帶指定的目錄中
				 try {
					ImageIO.write(oneBufferedImage, imageFormatNameString, orignalPPTFileOutStream);
				} catch (IOException e) {
					e.printStackTrace();
					converReturnResult=false;
					map.put("converReturnResult", converReturnResult);
					return map;
				}
				 
				
			}
			
			
		} finally{
			try {
				if(orignalPPTFileInputStream!=null){
					orignalPPTFileInputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				if(orignalPPTFileOutStream!=null){
					orignalPPTFileOutStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			map.put("converReturnResult", converReturnResult);
			map.put("imgNames", imgNamesList);
		}
		
		
		
		return map;
	}
	
	
	/**
	 * 將PPT 檔案轉換成image
	 * @param orignalPPTFileName  //PPT檔案路徑 如:d:/demo/demo1.ppt
	 * @param targetImageFileDir //轉換後的圖片儲存路徑 如:d:/demo/pptImg
	 * @param imageFormatNameString //圖片轉化的格式字串 ,如:"jpg"、"jpeg"、"bmp" "png" "gif" "tiff"
	 * @return Map<String,Object>
	 * 	key: converReturnResult   型別:boolean 轉化結果 true 代表轉換成功,false 代表轉換失敗
	 * 	key:imgNames			  型別:List<String> 轉換成功後圖片的全部名稱集合
	 * 	注:獲取“imgNames”圖片名稱集合時,請先判斷“converReturnResult” 是否為true;如果有一張轉換失敗則為false
	 */
	@SuppressWarnings("resource")
	public static Map<String,Object> converPPTtoImage(String orignalPPTFileName,String targetImageFileDir,
			String imageFormatNameString){
		Map<String,Object> map=new HashMap<String, Object>();
		boolean converReturnResult=true;//是否全部轉成功
		List<String> imgNamesList=new ArrayList<String>();//PPT轉成圖片後所有名稱集合
		
		
		FileInputStream orignalPPTFileInputStream=null;
		FileOutputStream orignalPPTFileOutStream=null;
		HSLFSlideShow  oneHSLFSlideShow=null;
		
		
		try{
			try {
				orignalPPTFileInputStream=new FileInputStream(orignalPPTFileName);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				converReturnResult=false;
				map.put("converReturnResult", converReturnResult);
				return map;
			}
			
			try {
				oneHSLFSlideShow=new HSLFSlideShow(orignalPPTFileInputStream);
			} catch (IOException e) {
				e.printStackTrace();
				converReturnResult=false;
				map.put("converReturnResult", converReturnResult);
				return map;
			}
			//獲取PPT每頁的大小(寬和高度)
			Dimension  onePPTPageSize= oneHSLFSlideShow.getPageSize();
			
			//獲得PPT檔案中的所有的PPT頁面(獲得每一張幻燈片),並轉為一張張的播放片
			List<HSLFSlide> pptPageSlideList=oneHSLFSlideShow.getSlides();
			//下面迴圈的主要功能是實現對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);
				 /**
				  * 設定圖片的存放路徑和圖片格式,注意生成的圖片路徑為絕對路徑,最終獲得各個影象檔案所對應的輸出流物件
				  */
				 try {
					 
					 String imgName=(i+1)+"_"+UUID.randomUUID().toString()+"."+imageFormatNameString;
					 imgNamesList.add(imgName);//將圖片名稱新增的集合中
					 
					orignalPPTFileOutStream=new FileOutputStream(targetImageFileDir+imgName);
					
				} catch (FileNotFoundException e) {
					e.printStackTrace();
					converReturnResult=false;
					map.put("converReturnResult", converReturnResult);
					return map;
				}
				/**
				 * 轉換後的圖片檔案儲存的指定的目錄中
				 */
				 
				 try {
					ImageIO.write(oneBufferedImage, imageFormatNameString, orignalPPTFileOutStream);
//					throw new IOException();
				} catch (IOException e) {
					e.printStackTrace();
					converReturnResult=false;
					map.put("converReturnResult", converReturnResult);
					return map;
				}
				
				
			}
			
			
			
			
		}finally{
			try {
				if(orignalPPTFileInputStream!=null){
					orignalPPTFileInputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				if(orignalPPTFileOutStream!=null){
					orignalPPTFileOutStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			map.put("converReturnResult", converReturnResult);
			map.put("imgNames", imgNamesList);
		}
	
		
		
		return map;
	}
	
	
	 /**
	  * 直接抽取幻燈片的全部內容
	  * @param filePath
	  * @return
	  * @throws IOException
	  */
    @SuppressWarnings("resource")
	public static String readppt2003Text(String filePath) {
    	
    	 PowerPointExtractor extractor=null;;
		try {
			File file = new File(filePath);
			 FileInputStream fin=new FileInputStream(file);
			extractor = new PowerPointExtractor(fin);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
        return extractor.getText();
    }
    
    
 // 讀取pptx
    @SuppressWarnings("resource")
	public  static String readPPTX2007Text(String file) {
         try {
			return new XSLFPowerPointExtractor(POIXMLDocument.openPackage(file)).getText();
		} catch (XmlException e) {
			e.printStackTrace();
		} catch (OpenXML4JException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;   
    }
	
	
	
	public static void main(String[] args) {
		/*
		 //PPT呼叫示例
//		Map<String,Object> map=	ConverPPTFileToImageUtil.converPPTtoImage("E:\\ppt\\oracle SQL語法大全(第一課).ppt", "E:\\ppt\\pptimg\\", "jpg");
		//PPTX呼叫示例
		Map<String,Object> map=ConverPPTFileToImageUtil.converPPTXtoImage("E:\\ppt\\PMS2.0介面設計培訓-20130507.pptx", "E:\\ppt\\pptimg\\", "jpg");
		boolean converReturnResult=(Boolean) map.get("converReturnResult");
		System.out.println("converReturnResult:"+converReturnResult);
		if(converReturnResult){//如果全部轉換成功,則為true;如果有一張轉換失敗,則為fasle
			@SuppressWarnings("unchecked")
			List<String> imgNames=(List<String>) map.get("imgNames");
			for (String imgName : imgNames) {
				System.out.println(imgName);
			}
			
		}*/
//		String content=readppt200Text("E:\\ppt\\oracle SQL語法大全(第一課).ppt");
//		String content=readPPT2007("E:\\ppt\\7第七講(13-14).pptx");
		String content=readPPTX2007Text("E:\\ppt\\PMS2.0介面設計培訓-20130507.pptx");
		System.out.println(content);
	}
		
		
		

}