web 中在线预览office 是个头疼的问题。 今天项目刚好做完一个PPT在线预览的功能 在这里分享给大家 思路: 获取网络PPT 文件 将PPT每一页的幻灯片都转换成单张图片 用流输出到页面展示 1, 首先获取PPT格式 PPT格式无非两种 PPTX,PPT 2,获取PPT幻灯片页数传递到JSP中 3,JSP循环获取每页PPT 上代码: 首先获取在线PPT 文件 并且获取PPT幻灯片页数 /** * 本类应用了Apache POI系统库,POI 是 Apache 下的 Jakata 项目的一个子项目,主要用于提供 Java 操作 Microsoft Office 办公套件如 Excel,Word,Powerpoint 等文件的 API。 */ public class ConvertPPTFileToImage { public ConvertPPTFileToImage() { } /** * PPTX 格式的处理 * @param filePath 图片网络路径URL * @param page 页数 * @param orignalPPTFileName 文件名 * @param imageFormatNameString 创建图片格式 (JPG,PNG,JPEG...等等) * @param outputStream 输出 * @throws Exception * 本来字体是要设置成PPT的字体 但是上传到linux 时候linux需要自己上传字体 否则所有中文都会变成乱码 口口口 无法显示 所以这里只 * 使用宋体 *如果大家想用其他字体 同样也是 linux 服务器的情况下 请自己上传字体到linux 中避免中文无法显示 下面会介绍如何上传字体到linux 中 */ public static void convertPPTXtoImage(String filePath,int page,String orignalPPTFileName, String imageFormatNameString, OutputStream outputStream) throws Exception { /** * 多文件转码处理避免有中文或者特殊字符无法读取 */ InputStream orignalPPTFileInputStream =null; String encodeName=""; String igs[]=orignalPPTFileName.split("/"); for(int x=0;x<igs.length;x++){ if(x==igs.length-1){ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20"); }else{ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20")+"/"; } } URL url=new URL(filePath+encodeName); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); //使用get orignalPPTFileInputStream=conn.getInputStream(); //FileOutputStream orignalPPTFileOutputStream =null; /** * org.apache.poi.hslf, 这个包只支持 PowerPoint 2007 以前的 ppt 文档解析. 因为 Office 2007 的文件底层实现方案(OOXML)和以前的版本(OLE2)有根本的变化。 * 支持 office 2007 的包为: org.apache.poi.xslf */ XMLSlideShow oneSlideShow =null; try{ try { oneSlideShow = new XMLSlideShow(orignalPPTFileInputStream); } catch (IOException e) { e.printStackTrace(); } /** * 获得PPT每页的尺寸大小(宽和高度) */ Dimension onePPTPageSize = oneSlideShow.getPageSize(); /** * 获得PPT文件中的所有的PPT页面,并转换为一张张的播放片 */ XSLFSlide[] pptPageXSLFSlideArray = oneSlideShow.getSlides(); if(pptPageXSLFSlideArray.length<=0||page>=pptPageXSLFSlideArray.length){ return ; } /** * 下面的XML配置文件定义转换后的图片内的文字字体,否则将会出现转换后的图片内的中文为乱码 */ String xmlFontFormat1="<xml-fragment xmlns:a=\"http://schemas./drawingml/2006/main\" xmlns:r=\"http://schemas./officeDocument/2006/relationships\" xmlns:p=\"http://schemas./presentationml/2006/main\">"; String xmlFontFormat2="<a:rPr lang=\"zh-CN\" altLang=\"en-US\" dirty=\"0\" smtClean=\"0\"> "; String xmlFontFormat3="<a:latin typeface=\"+mj-ea\"/> "; String xmlFontFormat4="</a:rPr>"; String xmlFontFormat5="</xml-fragment>"; StringBuffer xmlFontFormatStringBuffer=new StringBuffer(); xmlFontFormatStringBuffer.append(xmlFontFormat1); xmlFontFormatStringBuffer.append(xmlFontFormat2); xmlFontFormatStringBuffer.append(xmlFontFormat3); xmlFontFormatStringBuffer.append(xmlFontFormat4); xmlFontFormatStringBuffer.append(xmlFontFormat5); /** *设置字体为宋体,解决中文乱码问题 */ CTSlide oneCTSlide=pptPageXSLFSlideArray[page].getXmlObject(); CTGroupShape oneCTGroupShape = oneCTSlide.getCSld().getSpTree(); CTShape[] oneCTShapeArray = oneCTGroupShape.getSpArray(); for (CTShape oneCTShape : oneCTShapeArray) { CTTextBody oneCTTextBody = oneCTShape.getTxBody(); if (null == oneCTTextBody){ continue; } CTTextParagraph[] oneCTTextParagraph = oneCTTextBody.getPArray(); CTTextFont oneCTTextFont =null; try { oneCTTextFont = CTTextFont.Factory.parse(xmlFontFormatStringBuffer.toString()); } catch (XmlException e) { e.printStackTrace(); } for (CTTextParagraph textParagraph : oneCTTextParagraph) { CTRegularTextRun[] oneCTRegularTextRunArray = textParagraph.getRArray(); for (CTRegularTextRun oneCTRegularTextRun : oneCTRegularTextRunArray) { CTTextCharacterProperties oneCTTextCharacterProperties=oneCTRegularTextRun.getRPr(); oneCTTextCharacterProperties.setLatin(oneCTTextFont); } } } /** * 创建BufferedImage对象,图象的尺寸为原来PPT的每页的尺寸 */ BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width, onePPTPageSize.height, BufferedImage.TYPE_INT_RGB); Graphics2D oneGraphics2D = oneBufferedImage.createGraphics(); /** * 将PPT文件中的每个页面中的相关内容画到转换后的图片中 */ pptPageXSLFSlideArray[page].draw(oneGraphics2D); /** * 设置图片的存放路径和图片的格式,注意生成的文件路径为绝对路径,最终获得各个图像文件所对应的输出流对象 */ try { ImageIO.write(oneBufferedImage, imageFormatNameString, outputStream); } catch (IOException e) { e.printStackTrace(); } //} } finally{ try { if(orignalPPTFileInputStream != null ){ orignalPPTFileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * PPT 格式的处理 * @param filePath 图片网络路径URL * @param page 页数 * @param orignalPPTFileName 文件名 * @param imageFormatNameString 创建图片格式 (JPG,PNG,JPEG...等等) * @param outputStream 输出 * @throws Exception * 本来是设置成PPT的字体 但是上传到linux 时候linux需要自己上传字体 否则所有中文都会变成乱码 口口口 无法显示 所以这里只使用宋体 * 如果大家想用其他字体 同样也是 linux 服务器的情况下 请自己上传字体到linux 中避免中文无法显示 下面会介绍如何上传字体到linux 中 */ public static void convertPPTtoImage(String filePath,int page,String orignalPPTFileName, String imageFormatNameString,OutputStream outputStream) throws Exception { /** * convertReturnResult代表转换的结果,返回 false则表示转换不成功 */ InputStream orignalPPTFileInputStream =null; String encodeName=""; String igs[]=orignalPPTFileName.split("/"); for(int x=0;x<igs.length;x++){ if(x==igs.length-1){ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20"); }else{ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20")+"/"; } } URL url=new URL(filePath+encodeName); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); orignalPPTFileInputStream=conn.getInputStream(); SlideShow oneSlideShow =null; try{ try { oneSlideShow = new SlideShow(orignalPPTFileInputStream); } catch (IOException e) { e.printStackTrace(); } /** * 获得PPT每页的尺寸大小(宽和高度) */ Dimension onePPTPageSize = oneSlideShow.getPageSize(); /** * 获得PPT文件中的所有的PPT页面(获得每一张幻灯片),并转换为一张张的播放片 */ Slide[] pptPageSlideArray = oneSlideShow.getSlides(); /** * 下面的循环的主要功能是实现对PPT文件中的每一张幻灯片进行转换和操作。 */ if(pptPageSlideArray.length<=0||page>=pptPageSlideArray.length){ return ; } TextRun[] textRunsArray = pptPageSlideArray[page].getTextRuns(); for (int textRunsArrayIndex = 0; textRunsArrayIndex < textRunsArray.length; textRunsArrayIndex++) { RichTextRun[] pptRichTextRunsArray = textRunsArray[textRunsArrayIndex].getRichTextRuns(); for (int pptRichTextRunsArrayIndex = 0; pptRichTextRunsArrayIndex < pptRichTextRunsArray.length; pptRichTextRunsArrayIndex++) { /**原来是直接设置为宋体,这样会使得转换后的图片上的文字与原PPT的文字不一致,应该改变为应用PPT本身的字体名 * pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontIndex(1); * pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontName("宋体"); */ /** * 获得某个文本框内的字体名字符串,并识别是否为null(未正确地获得相关的字体名字符串),则设置为默认的字体名——宋体 * 但如果PPT文件在WPS中保存过,则pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontSize()的值可能为0或者26040。因此, * 首先识别当前文本框内的字体尺寸是否为0或者大于26040,则设置默认的字体尺寸。 */ int currentFontSize = pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontSize(); if((currentFontSize <=0)||(currentFontSize >=26040)){ pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontSize(30); } String currentFontName=pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontName(); /** * 本来是设置成PPT的字体 但是上传到linux 时候linux需要自己上传字体 否则所有中文都会变成乱码 口口口 无法显示 所以这里只使用宋体 * 如果大家想用其他字体 同样也是 linux 服务器的情况下 请自己上传字体到linux 中避免中文无法显示 下面会介绍如何上传字体到linux 中 */ /* if(currentFontName == null){ */ int index = pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontIndex(); pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontIndex(1); pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontName("宋体"); //} /*else{ pptRichTextRunsArray[pptRichTextRunsArrayIndex].setFontName(currentFontName); }*/ /** * 应用 pptRichTextRunsArray[pptRichTextRunsArrayIndex].getText() 可以获得其中的文字 * int pptRichTextRunsNumberIndex = pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontIndex(); String fontNameForPPTText = pptRichTextRunsArray[pptRichTextRunsArrayIndex].getFontName(); */ } } /** * 下面的代码是获取某一页PPT中的第一个备注文字串 System.out.println("备注文字:" + pptPageSlideArray[pptPageSlideIndex].getNotesSheet().getTextRuns()[0].getText()); */ /** * 创建BufferedImage对象,图象的尺寸为原来PPT的每页的尺寸 */ BufferedImage oneBufferedImage = new BufferedImage(onePPTPageSize.width, onePPTPageSize.height, BufferedImage.TYPE_INT_RGB); Graphics2D oneGraphics2D = oneBufferedImage.createGraphics(); oneGraphics2D.setFont(new Font("宋体", Font.PLAIN, 12)); /** * 设置转换后的图片的背景颜色为白色 * oneGraphics2D.setPaint(Color.white); oneGraphics2D.fill(new Rectangle2D.Float(0, 0, onePPTPageSize.width ,onePPTPageSize.height)); */ pptPageSlideArray[page].draw(oneGraphics2D); /** * 图像文件的格式字符串为“jpg”、“jpeg”、"bmp"、"png"、 "gif"、"tiff"等,将转换后的各个图片文件保存到指定的目录中 */ try { ImageIO.write(oneBufferedImage, imageFormatNameString, outputStream); } catch (IOException e) { e.printStackTrace(); } } finally{ try { if(orignalPPTFileInputStream != null ){ orignalPPTFileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 检查文件是否为ppt或者pptx格式 * @param orignalPPTFileName需要转换的原始PPT的文件名称 * @return */ public static short checkOrignalFileFormat(String orignalPPTFileName) { /** * PPT格式的识别结果, =0 不是PPT或者PPTX的格式文件, =1 代表*.ppt 格式, =2 代表 *.pptx 格式 */ short pptORpptxFormatFile = 0; /** * 识别需要转换的原始PPT的文件是否为真正的PPT文件 */ String orignalPPTFileSuffixName = null; if (orignalPPTFileName != null && orignalPPTFileName.lastIndexOf(".") != -1) { /** * 获得需要转换的原始ppt或者pptx的文件扩展名,返回的结果应该为“ppt”或者"pptx"字符串 */ orignalPPTFileSuffixName = orignalPPTFileName.substring(orignalPPTFileName.lastIndexOf(".") ); /** * 识别是否为.ppt格式 */ if (".ppt".equals(orignalPPTFileSuffixName)) { pptORpptxFormatFile = 1; } /** * 识别是否为.pptx格式 */ else if (".pptx".equals(orignalPPTFileSuffixName)) { pptORpptxFormatFile = 2; } /** * 如果不是.ppt格式或者*.pptx格式,则表示为非法的文件格式,则不能进行转换,符合检测的结果编码为0 */ } return pptORpptxFormatFile; } /** * 判断文件是否存在 并且返回PPT幻灯片的页数 * @param filePath 文件路径URL * @param orignalPPTFileName 文件名 * @return * @throws Exception */ public static int getPPTImgCount(String filePath,String orignalPPTFileName) throws Exception{ /** * 对文件名转码处理 避免有中文和特殊字符时无法获取图片 */ SlideShow oneSlideShow =null; XMLSlideShow oneSlideShow2 =null; InputStream orignalPPTFileInputStream =null; String encodeName=""; String igs[]=orignalPPTFileName.split("/"); for(int x=0;x<igs.length;x++){ if(x==igs.length-1){ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20"); }else{ encodeName+=URLEncoder.encode(igs[x]).replace("+","%20")+"/"; } } URL url=new URL(filePath+encodeName); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); int state = conn.getResponseCode(); if( state!=200){ return 0; } orignalPPTFileInputStream=conn.getInputStream(); int count=0; switch(checkOrignalFileFormat(orignalPPTFileName)){ case 0: System.out.println("待转换的PPT文件不存在或者不是PPT和PPTX格式的文件!"); break; case 1: try { oneSlideShow = new SlideShow(orignalPPTFileInputStream); } catch (IOException e) { e.printStackTrace(); return 0; } count= oneSlideShow.getSlides().length; break; case 2: try { oneSlideShow2 = new XMLSlideShow(orignalPPTFileInputStream); } catch (IOException e) { e.printStackTrace(); return 0; } count = oneSlideShow2.getSlides().length; break; } return count; } } /** 获取PPT页数到JSP 创建图片 */ @RequestMapping(value = "ppts") public String get(HttpServletRequest request,int id,String isFav) throws Exception{ request.setAttribute("pptCount", ConvertPPTFileToImage.getPPTImgCount(uploadHelper, data.value.getCASE_INTRO_URL())); return "dtl"; } /** 获取PPT图片 page 为幻灯片页数 */ @RequestMapping(value = "loaddtlppt") public void loadDtlPpt(HttpServletRequest req,HttpServletResponse rsp,int page) throws Exception{ String loadPath= (String) req.getSession().getAttribute("loadPptUrl"); String imageFormatNameString ="jpeg"; rsp.setHeader("Pragma", "No-cache"); rsp.setHeader("Cache-Control", "No-cache"); rsp.setDateHeader("Expires", 0); // 指定生成的响应是图片 rsp.setContentType("image/jpeg"); switch(ConvertPPTFileToImage.checkOrignalFileFormat(loadPath)){ case 0: System.out.println("待转换的PPT文件不存在或者不是PPT和PPTX格式的文件!"); break; case 1: ConvertPPTFileToImage.convertPPTtoImage([自行改成PPT文件路径],page,[文件名], imageFormatNameString,rsp.getOutputStream()); break; case 2: ConvertPPTFileToImage.convertPPTXtoImage([自行改成PPT文件路径],page,[文件名],imageFormatNameString,rsp.getOutputStream()); break; } } -------------------------jsp 代码--------------------------- ppts.jsp html <c:forEach begin="1" end="${pptCount}" varStatus="status"> <img alt="方案详情" src="<c:url value="/${base}loaddtlppt?page=${status.index-1}" />&time=<%=System.currentTimeMillis()%>" /> </c:forEach> html end //--------------------------------------------------------------- 相关JAR 没有用mave 也可以直接下载 poi 包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.10-FINAL</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.11-beta3</version> </dependency> Linux 上传 字体 首先 找到 windows 下的字体 这里以宋体为例子 C:\Windows\Fonts\simsun.ttc 上传到 linux jar 的 font 目录下 $HOME_PATH/jar/lib/fonts/fallback 目录下 (如果fonts下没有 fallback 目录自己创建 然后重启tomcat 就可以了 ,注意 是 ttc 后缀 不是ttf) 就此完毕 希望能帮到大家 ---------------第一次写 |
|