仿百度文库方案,openoffice.org 3+swftools+flexpaper
(一)之 tomcat6.0+jdk1.6环境配置 本方案是笔者在网络上收集前人智慧,以及辛苦奋斗探索几周完成的成果。 由于网络上,大部分资料、文章都比较零碎、重复、不够全面。要寻找比较全面系统的介绍该方案的资料实属不易。 本文将从一个只会net、jsp零基础的开发者的角度,全面、琐碎的进行总结。 ? 什么叫仿百度文库方案? 用户上传一个文档,格式有可能是doc、docx、xls、ppt、pdf 等。其他用户在前台查看的却是一个swf格式的flash文档。 flash文档可以起到防止用户下载,以及良好的浏览体验。 具体流程: 1.调用openoffice.org 的系统服务将office文档转换为pdf 2.调用swftools将pdf转换为swf 3.前台使用flexpaper浏览swf文件 为什么不用flashpaper+net? flashpaper转换非常简单,直接就可以将office文档转换为swf文件。 但是,笔者在测试flashpaper转换时,只能将txt、ppt成功转换为swf。转换doc、xls时失败。 笔者查看进程时,发现转换doc、xls时,flashpaper的进程内存压根就没有变化跳动。笔者估计它吖的压根就没有进行转换。 奈何笔者道行浅薄,无法解决此问题。遂放弃此方案。也许,收费版的可以成功转换。 收费版直接无视,笔者只是一名IT民工。 asp+本方案 必须有服务器才可以配置java环境吧。笔者是先在asp上传文档后,在后台用response.write写一个ajax请求或iframe, 把完整的文档路径发送到文件转换器页面进行转换。 可能的形式如下: response.Write(“<iframe frameborder=0 framespacing=0 width=0 height=0 scrolling=no src=http://ip:8080/swfserver/DocConverter.jsp?upath=F:/网站根目录/uploaddoc /20120101.xls></iframe>”) 第一步,tomcat6.0+jdk1.6环境配置 由于笔者是个jsp零基础的菜鸟。先从开发运行环境配置起。 这里笔者下载的是安装版:apache-tomcat-6.0.26.exe,jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep_2008.exe 1.首先安装jdk,安装以后,需要配置环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量 (假定你的jdk安装在C:Program FilesJava): JAVA_HOME=C:Program FilesJavajdk1.6.0_10 classpath=.;%JAVA_HOME%libdt.jar;%JAVA_HOME%libtools.jar;??? (.;一定不能少,因为它代表当前路径) path=%JAVA_HOME%bin 接着可以写一个简单的java程序来测试JDK是否已安装成功:
public class Test{ public static void main(String args[]){ System.out.println(“This is a test program.”); } } 将上面的这段程序保存为文件名为Test.java的文件。 2.接下来安装Tomcat,安装以后,配置一下环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量 (假定你的tomcat安装在c:tomcat): CATALINA_HOME:C:Program FilesApache Software FoundationTomcat 6.0 CATALINA_BASE:C:Program FilesApache Software FoundationTomcat 6.0 TOMCAT_HOME: C:Program FilesApache Software FoundationTomcat 6.0 然后修改环境变量中的classpath,把tomat安装目录下的commonlib下的servlet.jar追加到classpath中去,修改后的classpath如下: classpath=.;%JAVA_HOME%libdt.jar;%JAVA_HOME%libtools.jar;%CATALINA_HOME%commonlibservlet-api.jar; 【注意最新版本的Tomcat中可能没有common这个文件夹了。所以servlet-api.jar应该的路径为%CATALINA_HOME%libservlet-api.jar; 请根据自己的情况自己修改!】 接着可以启动tomcat,在IE中访问http://localhost:8080,如果看到tomcat的欢迎页面的话说明安装成功了。 3.建立自己的jsp app目录 1.到Tomcat的安装目录的webapps目录,可以看到ROOT,examples,tomcat-docs之类Tomcat自带的的目录; 2.在webapps目录下新建一个目录,起名叫myapp; 3.myapp下新建一个目录WEB-INF,注意,目录名称是区分大小写的; 4.WEB-INF下新建一个文件web.xml,内容如下:
<?xml version=”1.0″ encoding=”ISO-8859-1″?> <!DOCTYPE web-app PUBLIC “-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN” “http://java.sun.com/dtd/web-app_2_3.dtd”> <web-app> <display-name>My Web Application</display-name> <description> A application for test. </description> </web-app> 5.在myapp下新建一个测试的jsp页面,文件名为index.jsp,文件内容如下: <html> 6.重启Tomcat 7.打开浏览器,输入http://localhost:8080/myapp/index.jsp 看到当前时间的话说明就成功了。 4.建立自己的servlet 写入你的第一个Servlet: 在你新建的Application myapp/WEB-INF/classes/test目录下新建HelloWorld.java 然后照样用javac HelloWorld.java来编译这个文件,如果出现无法import javax.servlet.* 那么就是应该把C:Tomcatcommonlib里面的servlet-api.jar文件拷贝到C:JDKjrelibext中,再次编译,就没有问题了! 笔者本想一篇来完结,看来有点不切实际,还是分篇来写。 第二步,安装openoffice.org openoffice.org是一套sun的开源office办公套件,能在widows,linux,solaris等操作系统上执行。 主要模块有writer(文本文档),impress(演示文稿),Calc(电子表格),Draw(绘图),Math(公式),base(数据库) 笔者下载的是openoffice.org 3.3.0。下载完直接安装即可。
package test; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException { response.setContentType(“text/html”); PrintWriter out = response.getWriter(); out.println(“<html><head><title>”); out.println(“This is my first Servlet”); out.println(“</title></head><body>”); out.println(“<h1>Hello,World!</h1>”); out.println(“</body></html>”); } } 但是,我们还需要启动openoffice server。有两种做法: 1.以命令行方式启动openoffice server,缺点是每次系统重启,都需要手动去把openoffice server启动。 2.将openoffice server作为操作系统的服务启动,既然成为了系统服务,就可以设定开机自动启动了。 我们先来看第一种方式, 以命令行方式启动openoffice server 在cmd命令下,cd opeonofiice的安装路径/program 如:cd c:program filesopenoffice.org 3program soffice -headless -accept=”socket,host=127.0.0.1,port=8100;urp;” -nofirststartwizard 以系统服务的方式启动 这里我们还需要Windows Resource Kit tools ,将openoffice server设为系统服务。 Windows Resource Kit tools 是微软专为管理人员、开发人员和高级用户开发的,包括管理活动目录、组策略、TCP/IP网络、注册表、系统安全、监测等涉及Windows Server 2003 操作系统的其它很多方面的非常规安装的工具组件。Resource Kit Tools for XP的发布使得XP用户也能使用Resource Kit Tools对这些问题进行处理。 下载windows resource kit tools,我们进行默认安装。 1.打开Windows Resource Kit Tools 在Command Shell执行以下命令: “C:Program FilesWindows Resource KitsToolsinstsrv” OpenOfficeUnoServer “C:Program FilesWindows Resource KitsToolssrvany.exe” 打开 管理工具->服务 可以找到以 OpenOfficeUnoServer 命名的服务 ??? 2.打开注册表寻找以下路径 ??? HKEY_LOCAL_MACHINE -> SYSTEM ->ControlSet001 ->Services ->OpenOfficeUnoServer ? 新建项 Parameters,在该项下添加两个字符串值: key:Application ???? value:C:Program FilesOpenOffice.org 3programsoffice.exe
???? key:AppParameters ?????value:-invisible -headless -accept=socket,port=8100;urp; -nofirststartwizard ???? 3.在服务控制台,启动 openoffice 服务 ???? 4.在CMD中用以下命令查看8100是否已被监听:netstat -anop tcp 这样OpenOffice3.0就以服务方式运行在Windows系统上了。(使用cmd命令:netstat -anp tcp查看8100端口是否工作) 然後可以通过socket方式连接openOffice,以使用openoffice提供的某些服务,如文件转换服务,ms office转pdf等等。 开源项目 JODConverter 就是结合openoffice来进行文档转换的java组件。 另外有一个命令行工具swftools,该工具可以将pdf转换为swf格式的文档,提供给ie客戶端流览。 另外,我们可以将该配置用bat文件来快速实现,运行前请先修改相应目录参数: ???? openoffice service.bat文件 ??? “C:Program FilesWindows Resource KitsToolsinstsrv” OpenOfficeUnoServer “C:Program FilesWindows Resource KitsToolssrvany.exe” 第三步,使用JODConverter将office文档转换为pdf JODConverter是一个java的OpenDucument文件转换器,可以进行许多文件格式的转换,它利用 OpenOffice来进行转换工作,它能进行以下的转换工作: 1.Microsoft Office格式转换为OpenDucument,以及OpenDucument转换为Microsoft Office 2.OpenDucument转换为PDF,Word、Excel、PowerPoint转换为PDF,RTF转换为PDF等。 它是一个开源项目。 笔者的项目是在MyEclipse下开发的。 下载最新版的jodconverter-2.2.2,把lib文件夹的包导入到你的DocConverter项目的lib文件夹内。 (假设你的项目是DocConverter) 新建DOC2PDFUtil.java
package com.iori.webapp.util; import java.io.File; import java.io.IOException; import java.net.ConnectException; import java.util.Date; 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; public class DOC2PDFUtil extends java.lang.Thread { private File inputFile;// 需要转换的文件 private File outputFile;// 输出的文件 public DOC2PDFUtil(File inputFile,File outputFile) { this.inputFile = inputFile; this.outputFile = outputFile; } public void docToPdf() { Date start = new Date(); OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100); try { connection.connect(); DocumentConverter converter = new OpenOfficeDocumentConverter(connection); converter.convert(inputFile,outputFile); } catch (ConnectException cex) { cex.printStackTrace(); } finally { // close the connection if (connection != null) { connection.disconnect(); connection = null; } } } /** * 由于服务是线程不安全的,所以……需要启动线程 */ public void run() { this.docToPdf(); } public File getInputFile() { return inputFile; } public void setInputFile(File inputFile) { this.inputFile = inputFile; } public File getOutputFile() { return outputFile; } public void setOutputFile(File outputFile) { this.outputFile = outputFile; } /** * 测试main方法 * @param args */ public static void main(String[] args) { File inputFile = new File("c://temp//333.xls"); File outputFile = new File("c://temp//333.pdf"); DOC2PDFUtil dp=new DOC2PDFUtil(inputFile,outputFile); dp.start(); } } 在DOC2PDFUtil.java,右键属性 – >Run as – >Java Application ,输出main的测试结果。 在jsp中执行 新建MyDOC2PDFTest.jsp <%@ page import="java.io.*"%>
<%@ page import="com.artofsolving.jodconverter.openoffice.connection.*"%>
<%@ page import="com.artofsolving.jodconverter.openoffice.connection.*"%>
<%@ page import="com.artofsolving.jodconverter.openoffice.converter.*"%>
<%@ page import="com.artofsolving.jodconverter.*"%>
<%@ page import="java.util.*"%>
<%@ page import="com.iori.webapp.util.*"%>
<%
File inputFile = new File("c://temp//333.xls");
File outputFile = new File("c://temp//333.pdf");
DOC2PDFUtil dp=new DOC2PDFUtil(inputFile,outputFile);
dp.start();
%>
<!-- 下面这些html可以去掉 -->
<html>
<head><title>Simple jsp page</title></head>
<body>Place your content here</body>
</html>
在项目DocConverter根目录,右键属性 – >Run as – >MyEclipse Server Application 发布到之前安装的Tomcat 6.0的根目录,然后用url路径访问:Http://localhost:8080/DocConverter/MyDOC2PDFTest.jsp?进行测试。 JODConverter将office文档转换pdf,用到的代码如下:
File inputFile = new File("c://temp//333.xls"); File outputFile = new File("c://temp//333.pdf"); // 链接 一个运行在8100端口的OpenOffice.org 实例 OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100); connection.connect(); // 创建一个converter对象并转换格式 DocumentConverter converter = new OpenOfficeDocumentConverter(connection); converter.convert(inputFile,outputFile); // 关闭连接 connection.disconnect(); 第四步,使用swftools将pdf转换为swf 建议下载swftools-0.9.1,笔者起先下载的是最新版的swftools-1.0版。貌似转换时出错,缺少什么组件。 继续笔者的DocConverter项目。笔者使用的开发环境是MyEclipse 9.0。 新建PDF2SWFUtil.java
package com.iori.webapp.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class PDF2SWFUtil { /** * 利用SWFTools工具将pdf转换成swf,转换完后的swf文件与pdf同名 * @author iori * @param fileDir PDF文件存放路径(包括文件名) * @param exePath 转换器安装路径 * @throws IOException */ public static synchronized void pdf2swf(String fileDir,String exePath) throws IOException { //文件路径 String filePath = fileDir.substring(0,fileDir.lastIndexOf("/")); //文件名,不带后缀 String fileName = fileDir.substring((filePath.length() + 1),fileDir.lastIndexOf(".")); Process pro = null; if (isWindowsSystem()) { //如果是windows系统 //命令行命令 String cmd = exePath + " "" + fileDir + "" -o "" + filePath + "/" + fileName + ".swf""; //Runtime执行后返回创建的进程对象 pro = Runtime.getRuntime().exec(cmd); } else { //如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程 String[] cmd = new String[3]; cmd[0] = exePath; cmd[1] = fileDir; cmd[2] = filePath + "/" + fileName + ".swf"; //Runtime执行后返回创建的进程对象 pro = Runtime.getRuntime().exec(cmd); } //非要读取一遍cmd的输出,要不不会flush生成文件(多线程) new DoOutput(pro.getInputStream()).start(); new DoOutput(pro.getErrorStream()).start(); try { //调用waitFor方法,是为了阻塞当前进程,直到cmd执行完 pro.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 判断是否是windows操作系统 * @author iori * @return */ private static boolean isWindowsSystem() { String p = System.getProperty("os.name"); return p.toLowerCase().indexOf("windows") >= 0 ? true : false; } /** * 多线程内部类 * 读取转换时cmd进程的标准输出流和错误输出流,这样做是因为如果不读取流,进程将死锁 * @author iori */ private static class DoOutput extends Thread { public InputStream is; //构造方法 public DoOutput(InputStream is) { this.is = is; } public void run() { BufferedReader br = new BufferedReader(new InputStreamReader(this.is)); String str = null; try { //这里并没有对流的内容进行处理,只是读了一遍 while ((str = br.readLine()) != null); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /** * 测试main方法 * @param args */ public static void main(String[] args) { //转换器安装路径 String exePath = "c:/Program Files/SWFTools/pdf2swf.exe"; try { PDF2SWFUtil.pdf2swf("c:/temp/333.pdf",exePath); } catch (IOException e) { System.err.println("转换出错!"); e.printStackTrace(); } } } 在PDF2SWFUtil.java,右键属性 – >Run as – >Java Application ,输出main的测试结果。 在jsp中执行 新建MyPDF2SWFTest.jsp
<%@ page import="java.io.*"%> <%@ page import="com.artofsolving.jodconverter.openoffice.connection.*"%> <%@ page import="com.artofsolving.jodconverter.openoffice.connection.*"%> <%@ page import="com.artofsolving.jodconverter.openoffice.converter.*"%> <%@ page import="com.artofsolving.jodconverter.*"%> <%@ page import="java.util.*"%> <%@ page import="com.iori.webapp.util.*"%> <% //转换器安装路径 String exePath = "c:/Program Files/SWFTools/pdf2swf.exe"; try { PDF2SWFUtil.pdf2swf("c:/temp/333.pdf",exePath); } catch (IOException e) { System.err.println("转换出错!"); e.printStackTrace(); } %> <!-- 下面这些html可以去掉 --> <html> <head> <title>Simple jsp page</title> </head> <body>Place your content here</body> </html> 在项目DocConverter根目录,右键属性 – >Run as – >MyEclipse Server Application 发布到之前安装的Tomcat 6.0的根目录,然后用url路径访问:Http://localhost:8080/DocConverter/MyPDF2SWFTest.jsp?进行测试。 ? 第五步,office文档转为pdf,同时进一步转为swf 网上资料有很多office文档转为pdf,pdf转为swf,但都是单步转换。关于一起转换的资料比较少。 一起转换有个问题就是转为pdf时,这个转换过程将花费一段时间才能成功,如何控制在pdf转换成功后,才进行swf的转换。 以及多个文档批量转换又该怎么办。 ? 有幸笔者还是找到了一篇同时转换的代码: 新建DocConverter.java
package com.iori.webapp.util; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; 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格式转换 * @author Administrator */ public class DocConverter { private static final int environment=1;//环境1:windows 2:linux(涉及pdf2swf路径问题) private String fileString; private String outputPath="";//输入路径,如果不设置就输出在默认位置 private String fileName; private File pdfFile; private File swfFile; private File docFile; public DocConverter(String fileString) { ini(fileString); } /* * 重新设置 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(); System.out.println("****pdf转换成功,PDF输出:"+pdfFile.getPath()+"****"); } catch(java.net.ConnectException e) { //ToDo Auto-generated catch block 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 */ 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/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()+"****"); if(pdfFile.exists()) { pdfFile.delete(); } } catch (Exception 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()+"****"); if(pdfFile.exists()) { pdfFile.delete(); } } catch (Exception e) { e.printStackTrace(); throw e; } } } else { System.out.println("****pdf不存在,无法转换****"); } } else { System.out.println("****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(); } /* * 转换主方法 */ 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 { doc2pdf(); pdf2swf(); } catch (Exception e) { // TODO: Auto-generated catch block 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 s[]) { DocConverter d=new DocConverter("c:/temp/111.ppt"); d.conver(); } } 在DocConverter.java,右键属性 – >Run as – >Java Application ,输出main的测试结果。笔者分别进行单个转换,及批量转换,都测试可行。 至于为什么能成功进行pdf及swf的完整转换,在代码中没有看到和上述问题相关的控制。笔者在得到预期的结果,偶尔也会装糊涂,不去继续深究。 ? 第六步,flexpaper在线浏览swf文档 FlexPaper是一个开源轻量级的在浏览器上显示各种文档的组件,被设计用来与PDF2SWF一起使用, 使在Flex中显示PDF成为可能,而这个过程并无需PDF软件环境的支持。它可以被当做Flex的库来使用。 另外你也可以通过将一些例如Word、PPT等文档转成PDF,然后实现在线浏览。 FlexPaper_1.2.4_flash:无打印功能 FlexPaper_1.4.7_flash:打印功能,右键打印 这里我们不需要让用户打印,所以笔者选择FlexPaper_1.2.4_flash。 FlexPaper项目中有演示demo,这里笔者不多述。 综上,一个完整的在线文档浏览方案。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |