背景:现在项目需要做一个类似百度文库的在线预览功能,在网上找了下很多人推荐使用FlexPaper,所以今天尝试学习了FlexPaper顺便集成到现有的框架中
由于网上目前的说的都不是很详细,所以现在记录在此,希望对需要的人有所帮助
准备:1. FlexPaper_2.2.4.zip 下载地址:http://flexpaper.devaldi.com/download/
2.swftools 下载地址:http://www.swftools.org/download.html
3.openoffice4.1 下载地址http://www.openoffice.org/download/index.html
4.OpenDocument文档转换器 JODConverter 下载地址:http://sourceforge.net/projects/jodconverter/files/
备注:现在貌似sourceforge.net访问不是很稳定被高墙堵在外面了,需要爬墙,我这边由于使用的是maven工程所以直接就在仓库中下载了
现有系统架构:SpringMVC+springSecurity
步骤:1.安装swftools 首先我们要安装swftools作用是将pdf转换为swf文件以便flexpaper播放,这个windows环境下载下来的就是一个exe直接next就行了
2.安装openOffice 是开源免费的文字处理软件,它可以将office文档转成pdf文件
安装完openoffice后必须启动其server,以命令行方式启动openoffice server。进入cmd命令行提示符D:\Program Files\OpenOffice.org 3\program\
键入如下命令:
soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" –nofirststartwizard
备注:由于我本机环境是win8的今天在安装的时候都是默认安装在c盘后来在进行openoffice启动的时候服务一直无法启动后来发现可能由于win8对于c盘安全权限的问题后来重装后在d盘重新命令执行,ok服务启动
上述准备工作完成后我们来进行开发,首先我们写一个Controller ,主要是预览跳转链接用的
package com.cmcc.zysoft.web.controller; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.cmcc.zysoft.sysmanage.common.BaseController; import com.cmcc.zysoft.web.util.DocConverter; /** * * @ClassName: DocConverterController * @Description: TODO文档转换跳转类 * @author [email protected] * @date 2014年6月28日 下午6:37:04 * */ @RequestMapping("pc/docConverterController") @Controller public class DocConverterController extends BaseController { @Value("${upload.file.path}") private static String path; private static Logger _logger = LoggerFactory .getLogger(DocConverterController.class); @RequestMapping("/docPrvew.htm") public String docUplod(HttpServletRequest request,String fileName) { String fileString =request.getServletContext().getRealPath("")+path+fileName; //String fileString = request.getServletContext().getRealPath("")+"/resources/downLoad/11.doc"; //暂时路径是写死进行测试的,等后面上传后从上传路径进行查找 DocConverter d = new DocConverter(fileString); d.conver(); // 调用getswfPath()方法,打印转换后的swf文件路径 _logger.info(d.getswfPath()); // 生成swf相对路径,以便传递给flexpaper播放器 String swfpath ="/resources/downLoad" + d.getswfPath().substring(d.getswfPath().lastIndexOf("/")); _logger.info(swfpath); request.getSession().setAttribute("swfpath", swfpath); //model.addAttribute("swfpath", swfpath); return "flexPaper/documentView"; } }
在这个controller中我们可以看到调用了DocConverter 这个类,这个类主要是对pdf进行转换的类,所以比较重要也是成功与否的关键
在前面我们知道OpenOffice需要用命令行启动服务,但是上线后不能使用cmd来进行操作吧,所以在DocConverter,在网上找了JavaCallOpenoffice利用程序进行自启动
package com.cmcc.zysoft.web.util; import java.io.BufferedInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; /** * * @ClassName: DocConverter * @Description: TODO felx生成方法 * @author [email protected] * @date 2014年6月28日 下午6:37:27 * */ 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 Process process = null; private static Logger _logger = LoggerFactory.getLogger(DocConverter.class); public DocConverter(String fileString) { ini(fileString); JavaCallOpenoffice();// 启动openoffice } /** * 重新设置file * * @param fileString */ public void setFile(String fileString) { ini(fileString); } /** * 初始化 * * @param fileString */ private void ini(String fileString) { this.fileString = fileString; fileName = fileString.substring(0, fileString.lastIndexOf(".")); docFile = new File(fileString); pdfFile = new File(fileName + ".pdf"); swfFile = new File(fileName + ".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(); _logger.info("****pdf转换成功,PDF输出:" + pdfFile.getPath() + "****"); } catch (java.net.ConnectException e) { e.printStackTrace(); _logger.info("****swf转换器异常,openoffice服务未启动!****"); throw e; } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) { e.printStackTrace(); _logger.info("****swf转换器异常,读取转换文件失败****"); throw e; } catch (Exception e) { e.printStackTrace(); throw e; } } else { _logger.info("****已经转换为pdf,不需要再进行转化****"); } } else { _logger.info("****swf转换器异常,需要转换的文档不存在,无法转换****"); } DistorySoffice();// 每次转换成功后都关闭下openoffice } /** * 自启动openoffice方法 */ public void JavaCallOpenoffice() { Runtime rn = Runtime.getRuntime(); Process p = null; try { File file = new File("d:\\openoprenoffice.bat"); if (false == file.exists()) { _logger.info("。。。。。。。。。。"); FileWriter writer = new FileWriter("d:\\openoprenoffice.bat "); writer.write("@echo off "); writer.write("\r\n "); writer.write("D:"); writer.write("\r\n "); // D:\\Program Files\\OpenOffice 4\\program: openoffice的安装路径路径 writer.write("cd D:\\Program Files (x86)\\OpenOffice 4\\program"); writer.write("\r\n "); writer.write("soffice -headless -accept=" + "socket,host=127.0.0.1,port=8100;urp;" + " -nofirststartwizard"); writer.write("\r\n "); writer.write("@echo on "); writer.close(); } p = rn.exec("cmd.exe /C d:\\openoprenoffice.bat"); } catch (Exception e1) { e1.printStackTrace(); } } /** * 关闭office的方法 */ public void DistorySoffice() { try { // 显示进程 process = Runtime.getRuntime().exec("tasklist"); Scanner in = new Scanner(process.getInputStream()); while (in.hasNextLine()) { String processString = in.nextLine(); if (processString.contains("soffice.exe")) { // 关闭soffice进程的命令 String cmd = "taskkill /f /im soffice.exe"; process = Runtime.getRuntime().exec(cmd); _logger.info("openoffice正常关闭......."); } } } catch (IOException e) { e.printStackTrace(); } } /** * 转换成 swf */ @SuppressWarnings("unused") private void pdf2swf() throws Exception { Runtime r = Runtime.getRuntime(); if (!swfFile.exists()) { if (pdfFile.exists()) { if (environment == 1) {// windows环境处理 try { Process p = r .exec("C:/Program Files (x86)/SWFTools/pdf2swf.exe " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9"); _logger.info(loadStream(p.getInputStream())); _logger.info(loadStream(p.getErrorStream())); _logger.info(loadStream(p.getInputStream())); _logger.info("****swf转换成功,文件输出:" + swfFile.getPath() + "****"); if (pdfFile.exists()) { pdfFile.delete(); } } 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"); _logger.info(loadStream(p.getInputStream())); _logger.info(loadStream(p.getErrorStream())); _logger.info("****swf转换成功,文件输出:" + swfFile.getPath() + "****"); if (pdfFile.exists()) { pdfFile.delete(); } } catch (Exception e) { e.printStackTrace(); throw e; } } } else { _logger.info("****pdf不存在,无法转换****"); } } else { _logger.info("****swf已经存在不需要转换****"); } } 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()) { _logger.info("****swf转换器开始工作,该文件已经转换为swf****"); return true; } if (environment == 1) { _logger.info("****swf转换器开始工作,当前设置运行环境windows****"); } else { _logger.info("****swf转换器开始工作,当前设置运行环境linux****"); } try { 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"); } } } }
后端写好后,那么我们来写前端,前端只有一个预览界面documentView.jsp,对应的几个flexPaper js文件是在下载的flexpaper包中直接copy过来的
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <%@ include file="/WEB-INF/views/common/homecommoncss.jsp"%> <base href="<%=basePath%>" /> <% String swfFilePath=basePath+session.getAttribute("swfpath").toString(); %> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <jsp:include page="/WEB-INF/views/common/commonjs.jsp" /> <script type="text/javascript" src="/resources/js/flexPaper/flexpaper_handlers_debug.js"></script> <script type="text/javascript" src="/resources/js/flexPaper/flexpaper_handlers.js"></script> <script type="text/javascript" src="/resources/js/flexPaper/flexpaper.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;"> <div id="documentViewer" class="flexpaper_viewer" style="width:870px;height:500px"></div> <script type="text/javascript"> $(‘#documentViewer‘).FlexPaperViewer( { config : { SWFFile : ‘<%=swfFilePath%>‘, 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‘, RenderingOrder : ‘flash‘, StartAtPage : ‘‘, ViewModeToolsVisible : true, ZoomToolsVisible : true, NavToolsVisible : true, CursorToolsVisible : true, SearchToolsVisible : true, WMode : ‘window‘, localeChain: ‘en_US‘ }} ); </script> </div> </body> </html>
其它:在操作过程由于我这个框架是采用了springSecurity 进行签权,所以我们在启动后出现了FlexPaperViewer.swf被拦截无法加载的错误,之后修改了file-security.xml中进行了一个不拦截的设置
代码如下
<security:filter-chain pattern="/security/**" filters="none" /> <security:filter-chain pattern="/**/*.swf" filters="none" />
最后我这边改造了下flexpaper.js文件的默认路径,改造后的代码如下,其中_jsDirectory 以及expressInstall 所指发路径为本人代码所在的flexpaper文件夹中的相关文件
if (_uDoc != null) { _SWFFile = FLEXPAPER.translateUrlByFormat(_uDoc,"swf"); } _SWFFile = (config.SwfFile!=null?config.SwfFile:_SWFFile); _SWFFile = (config.SWFFile!=null?config.SWFFile:_SWFFile); _PDFFile = (config.PDFFile!=null?config.PDFFile:_PDFFile); _IMGFiles = (config.IMGFiles!=null?config.IMGFiles:_IMGFiles); _IMGFiles = (config.PageImagePattern!=null?config.PageImagePattern:_IMGFiles); _JSONFile = (config.JSONFile!=null?config.JSONFile:_JSONFile); _jsDirectory = (config.jsDirectory!=null?config.jsDirectory:"resources/js/flexPaper/"); _cssDirectory = (config.cssDirectory!=null?config.cssDirectory:"css/"); _localeDirectory = (config.localeDirectory!=null?config.localeDirectory:"locale/"); if(_SWFFile!=null && _SWFFile.indexOf("{" )==0 && _SWFFile.indexOf("[*," ) > 0 && _SWFFile.indexOf("]" ) > 0){_SWFFile = escape(_SWFFile);} // split file fix window[instance] = flashembed(id, { src : _jsDirectory+"FlexPaperViewer.swf", version : [10, 0], expressInstall : _jsDirectory+"expressinstall.swf", wmode : _WMode },{
最后我们来看下效果怎样
ok,不足之处,希望多喷!
SpringMVC+springSecurity+flexPaper 配置--类似百度文库在线预览,布布扣,bubuko.com