标签:
文档在线预览在项目中早就完成了,后来又经过了一次优化。但是一直都没时间去记录遇到的问题,文档在线预览的详细步骤可以参考http://blog.csdn.net/u013614451/article/details/24261503,感谢博主写了这么好的文章帮助我完成了项目中主要的模块。下面是文档转换的工具类DocConvert.java,并标注出我修改的部分。
package com.he.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; 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.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.UUID; import com.artofsolving.jodconverter.DocumentConverter; import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection; import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter; /** * doc docx格式转换 */ public class DocConverter { private static final int environment = 1;// 环境 1:windows 2:linux private String fileString;// (只涉及pdf2swf路径问题) private String outputPath = "";// 输入路径 ,如果不设置就输出在默认的位置 private String fileName; private File pdfFile; private File swfFile; private File docFile; private String tempName; private String extName ; public DocConverter(String fileString,String outputPath) { ini(fileString,outputPath); } /** * 重新设置file * * @param fileString */ public void setFile(String fileString,String outputPath) { ini(fileString,outputPath); } /** * 初始化 * * @param fileString */ private void ini(String fileString,String outputPath) { this.fileString = fileString; fileName=fileString.substring(0,fileString.lastIndexOf(".")); //获取文件路径 this.tempName = fileString.substring(fileString.lastIndexOf("/")+1).hashCode()+""; //转换后的文件名以要转换文件名的hash值命名 this.extName = fileString.substring(fileString.lastIndexOf(".")); //获取后缀名 //如果文件是txt的,则先对其编码成utf-8格式, if(".txt".equalsIgnoreCase(extName)){ docFile = new File(copyFile2(fileString, outputPath+"/"+tempName+".txt")); }else{ docFile = new File(fileString); } //这中情况主要是为了解决文件名相同但是格式不相同的文件,比如123.doc和123.pdf文件 //如果是123.pdf格式,则直接以文件名创建pdf文件对象 //如果是123.doc格式,则应该先将文件名改了, //如果不改,在利用openOffice转换时会首先判断123.pdf是否存在,如果存在就不会转换了,导致123.doc并没有转换 if(".pdf".equals(extName)){ pdfFile = new File(fileName+".pdf"); }else{ pdfFile = new File(outputPath+"/"+tempName + ".pdf"); } swfFile = new File(outputPath+"/"+tempName + ".swf"); } /** * 转为PDF * * @param file */ private void doc2pdf() throws Exception { if (docFile.exists()) { if (!pdfFile.exists()) { OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100); try { connection.connect(); DocumentConverter converter = new OpenOfficeDocumentConverter(connection); converter.convert(docFile, pdfFile); // close the connection connection.disconnect(); //如果文件是txt文件,将复制后的文件删除 if(".txt".equalsIgnoreCase(extName)){ if(docFile.exists()){ docFile.delete(); } } System.out.println("****pdf转换成功,PDF输出:" + pdfFile.getPath()+ "****"); } catch (java.net.ConnectException e) { e.printStackTrace(); System.out.println("****swf转换器异常,openoffice服务未启动!****"); throw e; } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) { e.printStackTrace(); System.out.println("****swf转换器异常,读取转换文件失败****"); throw e; } catch (Exception e) { e.printStackTrace(); throw e; } } else { System.out.println("****已经转换为pdf,不需要再进行转化****"); } } else { System.out.println("****swf转换器异常,需要转换的文档不存在,无法转换****"); } } /** * 转换成 swf */ @SuppressWarnings("unused") private void pdf2swf() throws Exception { if (pdfFile.exists()) { Runtime r = Runtime.getRuntime(); if (!swfFile.exists()) { if (environment == 1) {// windows环境处理 try { Process p = r.exec("D:/SWFTools/pdf2swf.exe "+ pdfFile.getPath() + " -o "+ swfFile.getPath() + " -T 9"); System.out.print(loadStream(p.getInputStream())); System.err.print(loadStream(p.getErrorStream())); System.out.print(loadStream(p.getInputStream())); System.err.println("****swf转换成功,文件输出:" + swfFile.getPath() + "****"); } catch (IOException e) { e.printStackTrace(); throw e; } } else if (environment == 2) {// linux环境处理 try { Process p = r.exec("pdf2swf " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9"); System.out.print(loadStream(p.getInputStream())); System.err.print(loadStream(p.getErrorStream())); System.err.println("****swf转换成功,文件输出:" + swfFile.getPath() + "****"); } catch (Exception e) { e.printStackTrace(); throw e; } } //文件不是pdf文档,并且文件存在才将pdf文件删除 if (!".pdf".equalsIgnoreCase(extName) && pdfFile.exists()) { pdfFile.delete(); } } else { System.out.println("****pdf不存在,无法转换****"); } } else { System.out.println("****swf已经存在不需要转换****"); } } /** * 把txt文件按照其原来的编码读出来,然后再以utf-8的编码写到一个新的txt文件中去,将utf-8文件转换成pdf,就不会乱码 * @param sourceFile 要读取的文件 * @param targetFile 目标文件 * @return */ @SuppressWarnings("unused") private String copyFile2(String sourceFile,String targetFile){ //获取txt原始编码 String charSet = EncodingDetect.getJavaEncode(sourceFile); return EncodingDetect.readFile(sourceFile, charSet, targetFile); } static String loadStream(InputStream in) throws IOException { int ptr = 0; in = new BufferedInputStream(in); StringBuffer buffer = new StringBuffer(); while ((ptr = in.read()) != -1) { buffer.append((char) ptr); } return buffer.toString(); } /** * 转换主方法 */ @SuppressWarnings("unused") public boolean conver() { if (swfFile.exists()) { System.out.println("****swf转换器开始工作,该文件已经转换为swf****"); return true; } if (environment == 1) { System.out.println("****swf转换器开始工作,当前设置运行环境windows****"); } else { System.out.println("****swf转换器开始工作,当前设置运行环境linux****"); } try { //如果文件本身就是pdf文件,就不需要经过OpenOffice转换 if(".pdf".equalsIgnoreCase(extName)){ pdf2swf(); }else{ doc2pdf(); pdf2swf(); } } catch (Exception e) { e.printStackTrace(); return false; } if (swfFile.exists()) { return true; } else { return false; } } /** * 返回文件路径 * * @param s */ public String getswfPath() { if (swfFile.exists()) { String tempString = swfFile.getPath(); tempString = tempString.replaceAll("\\\\", "/"); return tempString; } else { return ""; } } /** * 设置输出路径 */ public void setOutputPath(String outputPath) { this.outputPath = outputPath; if (!outputPath.equals("")) { String realName = fileName.substring(fileName.lastIndexOf("/"), fileName.lastIndexOf(".")); if (outputPath.charAt(outputPath.length()) == ‘/‘) { swfFile = new File(outputPath + realName + ".swf"); } else { swfFile = new File(outputPath + realName + ".swf"); } } } public static void main(String[] args) { DocConverter d = new DocConverter("D:/排序算法汇总.pdf","D:"); d.conver(); } }
这个问题我开始是将要转换成的SWF文件以UUID命名,后来发现每次预览文件都得转换,很影响效率,同时也会使项目中转换的swf文件越来越多,浪费空间。最后想到每个文件夹中不会出现相同的文件名(包括后缀名),那就可以用文件名的hash值作为转换后SWF文件的文件名,这样就解决了中文名问题和文件只需要转换一次就能多次预览。具体代码实现是红色标记部分。
原文中并没有考虑这种情况,但是项目中大多数文件都是PDF格式的。PDF文档不需要经过OpenOffice转换,可以直接转换成SWF格式,而且原文中将PDF格式转换成SWF格式后就把PDF文件删除,所以我们先要判断文件的格式再删文件,这个问题的具体解决代码可以看灰色部分的标记和注解
这个问题原文中有解答,EncodingDetect类也可以在原文中下载。具体代码可以看黄色部分标记。
在线预览是通过flexPaper实现的,flexPaper是由js写的,js只能读取项目中的路径,无法读取绝对路径。一开始我是把所有转换的的文件存放在项目下,但是老板说这样不好,如果以后项目更新转换的文件就没了,而且把文件都存到项目中去会使项目占得空间越来越大,最好是保存到项目外的路径中去,老板的要求大于一切,我疯狂百度最后找到了思路。把文件以流的形式传到界面上去。
创建一个DocConvertServlet.java类,主要是将要预览的文件转换成流,并传到界面去。在web.xml中配置好
package com.he.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DocConvertServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); OutputStream out = resp.getOutputStream(); //要预览的文件路径,可以动态赋值 InputStream is = new FileInputStream(new File("D:/1463730867.swf")); int len = 0; byte[] b = new byte[1024]; while((len=is.read(b))>0){ out.write(b, 0, len); } is.close(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
web.xml中代码
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>docConverServlet</servlet-name> <servlet-class>com.he.util.DocConvertServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>docConverServlet</servlet-name> <url-pattern>/docConverServlet</url-pattern> </servlet-mapping> </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% // String swfFilePath=session.getAttribute("swfpath").toString(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/flexpaper_flash.js"></script> <script type="text/javascript" src="js/flexpaper_flash_debug.js"></script> <script type="text/javascript" src="js/jquery.progressbar.min.js"></script> < <style type="text/css" media="screen"> html, body { height:100%; } body { margin:0; padding:0; overflow:auto; } #flashContent { display:none; } </style> <title>文档在线预览系统</title> </head> <body> <div style="position:absolute;left:50px;top:10px;" id="test"> <a id="viewerPlaceHolder" style="width:820px;height:650px;display:block"></a> <script type="text/javascript"> var fp = new FlexPaperViewer( ‘FlexPaperViewer‘, ‘viewerPlaceHolder‘, { config : { /*将路径改为请求Servlet地址*/ SwfFile : escape("${pageContext.request.contextPath}/docConverServlet"), Scale : 0.6, ZoomTransition : ‘easeOut‘, ZoomTime : 0.5, ZoomInterval : 0.2, FitPageOnLoad : true, FitWidthOnLoad : false, FullScreenAsMaxWindow : false, ProgressiveLoading : false, MinZoomSize : 0.2, MaxZoomSize : 5, SearchMatchAll : false, InitViewMode : ‘Portrait‘, ViewModeToolsVisible : true, ZoomToolsVisible : true, NavToolsVisible : true, CursorToolsVisible : true, SearchToolsVisible : true, localeChain: ‘en_US‘ }}); </script> </div> <script type="text/javascript"> </script> </body> </html>
在浏览器地址中输入http://localhost:8080/ctcesims/documentView.jsp,就能得到我们想要的结果了。不管是音频文件还是视频文件都可以采取这种办法。
在老板告诉我需要做个文档在线预览的时候,我觉得自己根本无法完成,这么难的东西,我怎么做的出来。但是项目是自己的,自己不去研究没人去帮你研究。经过自己的努力最终还是做出来了,并且不断在优化同时也兴奋了一把。在做一个东西的时候首先要给自己建立信心,相信自己能够完成才会有更大的动力去研究才能做到最好。
这个模块还有个问题没有解决,就是第一次预览需要的时间比较长,我想做一个加载中的提示框没有做出来,因为我不知道文档什么时候才加载完成,虽然可以通过ajax完成这个功能,但是感觉没必要用到ajax。
Java实现文档在线预览(openoffice+swfTools+FlexPaper)
标签:
原文地址:http://www.cnblogs.com/duoluomengxing/p/4912325.html