您的位置:首页 > 编程语言 > Java开发

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper

2016-01-14 17:29 866 查看
在线预览实现简介:

    过程分为:1、使用OpenOffice(JODConverter)将不同类型的附件转换为.pdf后缀的文件(PDF);

                      2、使用SwfTools将pdf文件转换为swf文件;

                      3、使用FlexPaper 在jsp中预览swf文件;

注意:此过程不包含文件的上传下载部分代码说明;

本文的系统环境为 windows

Linux我会在下篇博客中进行说明(不同点也就是在安装openoffice和swftools上的不同,在Linux比较麻烦容易出现很多小问题)

由于本人经验有限,如有纰漏和不足 多多批评;

在此过程中遇到的问题以及解决方法,下面将进行详细解析:(该文可能会随时更新)

首先第一步(安装包下载以及安装):

1.openoffice是Apache下的一个开放免费的文字处理软件

   下载地址:Apache
oppenoffice 官网下载 版本-4.1.2

2.SWFTools是一组用来处理Flash的swf文件的工具包,我们使用它将pdf文件转成swf文件!

   下载地址:SWFTools官网下载
swftools-2013-04-09-1007.exe

3.FlexPaper是一个开源轻量级的在浏览器上显示各种文档的组件(下载下来后解压即可)

   下载地址:FlexPaper官网下载
版本FlexPaper_2.3.6

将所下载的文件进行安装(除了FlexPaper),盘符可设定!需要说明一下openOffice

安装openoffice(第三方工具) 使用的版本为4.1.2

openoffice.org是一套sun的开源office办公套件,能在widows,linux,solaris等操作系统上执行

可以将word、excel、ppt、txt等文件转换为pdf文件;(下载完成后直接安装即可)

安装完成后,我们还需要启动openoffice server。有两种做法:

   1.以命令行方式启动openoffice server,缺点是每次系统重启,都需要手动去把openoffice server启动。

    2.将openoffice server作为操作系统的服务启动,既然成为了系统服务,就可以设定开机自动启动了。

    我们先来看第一种方式,

1.以命令行方式启动openoffice server

  在cmd命令下,cd opeonofiice的安装路径/program 如:cd C:\Program Files (x86)\OpenOffice 4\program

在这层目录下执行下面的命令即可

soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard



 127.0.0.1 :是安装openOffice的主机可以写成 指定的ip

2.以系统服务的方式启动

    这里我们还需要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 Files\Windows Resource Kits\Tools\instsrv" OpenOfficeUnoServer "C:\Program Files\Windows Resource Kits\Tools\srvany.exe"

打开 管理工具->服务 可以找到以 OpenOfficeUnoServer 命名的服务

    2.打开注册表寻找以下路径

    HKEY_LOCAL_MACHINE -> SYSTEM ->ControlSet001 ->Services ->OpenOfficeUnoServer

  新建项 Parameters,在该项下添加两个字符串值:

  key:Application

     value:C:\Program Files\OpenOffice.org 3\program\soffice.exe

      key:AppParameters

    value:-invisible -headless -accept=socket,host=127.0.0.1,port=8100;urp;-nofirststartwizard

 

     3.在服务控制台启动 openoffice 服务

      4.在CMD中用以下命令查看8100是否已被监听:netstat -anop tcp

这样OpenOffice3.0就以服务方式运行在Windows系统上了。(使用cmd命令:netstat -aon|findstr 8100查看8100端口是否工作)

然後可以通过socket方式连接openOffice,以使用openoffice提供的某些服务,如文件转换服务,ms office转pdf等等。

开源项目JODConverter 就是结合openoffice来进行文档转换的java组件。

另外有一个命令行工具swftools,该工具可以将pdf转换为swf格式的文档,提供给ie客戶端流览。    

  另外,我们可以将该配置用bat文件来快速实现,运行前请先修改相应目录参数:

     openoffice service.bat文件

    "C:\Program Files\Windows Resource Kits\Tools\instsrv" OpenOfficeUnoServer "C:\Program Files\Windows Resource Kits\Tools\srvany.exe"

    reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\OpenOfficeUnoServer\Parameters /ve /d

    reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\OpenOfficeUnoServer\Parameters /v Application /t REG_SZ /d "C:\Program Files\OpenOffice.org 3\program\soffice.exe"

    reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\OpenOfficeUnoServer\Parameters /v AppParameters /t REG_SZ /d "-invisible -headless -accept=socket,host=127.0.0.1,port=8100;urp; -nofirststartwizard"

第二步:开发过程解析(此过程对主要的代码进行说明)

     1、 在已有项目中或者新建web项目;

在项目中需要添加引入依赖的jar包以及js文件,缺少的jar包可自行下载:我习惯在这里下载http://cn.jarfire.org/

需要的jar包



需要的js文件swf文件,此文件在flexPaper的包中的js文件夹下





将js以及swf文件,放在项目根目录的自定义的包下,以便在jsp中引用;

特别说明的是 flexpaper.js需要修改一下,很简单

修改的目的是因为你所引用的swf文件,是可以随意存放在你自定义的文件夹下,保证我们来引用就可以,这里就是修改的文件路径(举例说明)



到这步基本具备了实现预览功能的辅助的工具以及第三方包的引入;

2、创建转换类

import java.io.BufferedInputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;

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;

import com.integrity.dataSmart.impAnalyImport.util.ContentType;

import com.integrity.dataSmart.impAnalyImport.util.FileTools;

import com.integrity.lawCase.util.ChineTo16Utils;

/**

 * doc docx格式转换

 * @author Liubf

 * 文本在线预览实现

 */

public class DocConverter {
private static Logger logger = Logger.getLogger(DocConverter.class);

    private static int environment;//环境1:windows 2:linux(涉及pdf2swf路径问题)

    private String fileString;

    private String outputPath;//输入路径,如果不设置就输出在默认位置(上传文件保存的路径)

    private String fileName;

    private File pdfFile;

    private File swfFile;

    private File docFile;

    static{

    if(isWindowsSys()){

    environment = 1;

    }else{

    environment = 2;

    }

    }

    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");

        String s = fileName.substring(0,fileName.lastIndexOf(File.separator));

        String e = fileName.substring(fileName.lastIndexOf(File.separator)+1);
  String utf8name = ChineTo16Utils.getUtf8(e);
  utf8name = s+File.separator+utf8name;

        swfFile=new File(utf8name+".swf");//转换后输出的swf文件

    }

    /**

     * 判断是否是windows操作系统

     * @author Liubf

     * @return true false

     */

    private static boolean isWindowsSys() {

       String p = System.getProperty("os.name");

       return p.toLowerCase().indexOf("windows") >= 0 ? true : false;

    }

    

    /**

     * 转pdf文件

     */

    private void doc2pdf(String serviceIp){

        if(docFile.exists()){

         if(!pdfFile.exists()){

       OpenOfficeConnection connection=new SocketOpenOfficeConnection(serviceIp,8100);

//serverIP是openoffice的服务ip,这样是因为避免openoffice的服务不在同一台服务器上

//如果是本地服务这样 SocketOpenOfficeConnection("127.0.0.1",8100);就可以,

//或者SocketOpenOfficeConnection("127.0.0.1",8100)

         try{

             connection.connect();

             DocumentConverter converter=new OpenOfficeDocumentConverter(connection);

             try {

                    converter.convert(docFile,pdfFile);

                    //close the connection
} catch (Exception e) {
logger.error("文本格式不符合要求:建议安装最新版本的openoffice",e);
}

          }catch(java.net.ConnectException e){

                logger.error("****swf转换异常,openoffice服务未启动!****",e);

          }catch(com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e){

                    logger.error("****swf转换器异常,读取转换文件失败****",e);

                    throw e;

             }catch(Exception e){

                  e.printStackTrace();

                  throw e;

                }finally {  

                    if (connection != null) {  

                        connection.disconnect();

                        connection = null;  

                    }  

                } 

            }else{

                //System.out.println("****已经转换为pdf,不需要再进行转化****");

            }

        }else{

        logger.error("****swf转换器异常,需要转换的文档不存在,无法转换****");

        }

    }

    /**

     * 转swf文件

     */

 private void pdf2swf(String exePath){//exePath参数是swftools执行文件的路径

        Runtime r=Runtime.getRuntime();

        if(!swfFile.exists()){

            if(pdfFile.exists()){

                if(environment==1){//windows环境处理

try { Process p=r.exec(

exePath+" "+pdfFile.getPath()+" -o "+swfFile.getPath()+" -T 9 -t -s storeallcharacters");

                 loadStream(p.getInputStream());

                 //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();

                    }

                }else if(environment==2){//linux环境处理

                    try {

Process p=r.exec(

exePath+" "+pdfFile.getPath()+" -o "+swfFile.getPath()+" -T 9 -t -s storeallcharacters");

                 loadStream(p.getInputStream());

                 //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();

                    }

                }

            }else{

            logger.error("****pdf不存在,无法转换****");

            }

        }else{

        logger.info("****swf已存在不需要转换****");

        }

    }

    static String loadStream(InputStream in){

        int ptr=0;

        in=new BufferedInputStream(in);

        StringBuffer buffer=new StringBuffer();

        try {
while((ptr=in.read())!=-1)
{
   buffer.append((char)ptr);
}
} catch (IOException e) {
logger.error("加载数据流异常",e);
}

        return buffer.toString();

    }

    /**

     * @param fileName 文件名(含后缀)

     * @return true false

     * 转换主方法

     */

    public boolean conver(String fileName,String openIp,String exePath){

    String fileTypes =  FileTools.getTypeByFileName(fileName);
String contentTypes= ContentType.getNameByType(fileTypes);
if (StringUtils.isBlank(contentTypes)) {
logger.error("当前文件类型不支持预览: "+ fileName );
return false;
}else{

        if(swfFile.exists())

        {

            //System.out.println("****swf转换器开始工作,该文件已经转换为swf****");

            return true;

        }

        try {

            doc2pdf(openIp);

            pdf2swf(exePath);

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

        if(swfFile.exists())

        {

            return true;

        }

        else {

            return false;

        }

    }

    }

   

}


3 转码工具类ChineToUtfUtils目的是因为flexPaper对swf文件进行预览加载的时候,文件名会默认转码为utf-8(处理后),这样会导致如果上传的中文名的文件预览失败,包错404找不到,就是因为文件名被转码;

/**

 * @author liuBf

 * 获取中文的utf-8编码值

 *

 */

public class ChineToUtfUtils {
public static String getUtf8(String strInput){

        StringBuffer output = new StringBuffer();

        for (int i = 0; i < strInput.length(); i++)

        {

            output.append(Integer.toString(strInput.charAt(i), 16));

        }

        return output.toString().toUpperCase();
}

4.上传文件的代码 中调用代码(主要)

//将文本转换为swf文件,用于在线预览;
DocConverter d=new DocConverter(realpath+fileName);//参数为上传文件的路径以及文件名称

String exe = swfdatas.get("swf.exe").toString();

String openIp = swfdatas.get("openoffice.ip").toString();

//exe 是我在项目启动时,自动加载的配置信息,也就是swfTools的执行文件路径

//openIp是openoffice的服务ip

d.conver(fileName,openIp,exe);

如果初步测试可这样写(open为本地服务):

DocConverter d=new DocConverter(realpath+fileName);

d.conver(fileName,"127.0.0.1",“E:/SWFtools/pdf2swf.exe”);//这是swfTools安装目录下的exe文件

//E:/SWFtools/pdf2swf.exe被调用后,实现pdf转swf

也就是说action中值加入这三行代码;

上传文件成功(同时也生成了swf可预览的文件);

5、点击预览时调用的action代码

public String toShowIngOnline(){

//在这里因为特别原因,我会在数据库中重新查到上传文件的数据(所要预览的文件)

//其实在前台可以直接将要预览的文件路径传过来 接受就可以了

//这里可更具具体情况编码
String fid = request.getParameter("fid");
FilesObject fo = fileManageService.getFileinfoByid(Long.valueOf(fid));
String filename = fo.getFileName().substring(0,fo.getFileName().indexOf(".")).trim();
filename = ChineToUtfUtils.getUtf8(filename);
String directory = "images/uploadFile/"+fo.getAnnexName()+"/"+filename+".swf";
request.getSession().setAttribute("swfpath", directory);  
return SUCCESS;
}

6 创建showingOnline.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  

<%  

    String swfFilePath=session.getAttribute("swfpath").toString();

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >  

<html>  

<head> 

<base href="<%=basePath%>">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  

<script type="text/javascript" src="scripts/showOnline/jquery.min.js"></script>  

<script type="text/javascript" src="scripts/showOnline/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 id="viewerPlaceHolder" class="flexpaper_viewer" style="width:1084px;height:560px;"></div> 

          <script type="text/javascript"> 

            $('#viewerPlaceHolder').FlexPaperViewer(     

                    { config : {  

                    SWFFile : escape('<%=swfFilePath%>'),  

                    Scale : 1,   

                    ZoomTransition : 'easeOut',  

                    ZoomTime : 0.5,  

                    ZoomInterval : 0.2,  

                    FitPageOnLoad : false,  

                    FitWidthOnLoad : true,  

                    FullScreenAsMaxWindow : false,  

                    ProgressiveLoading : false,  

                    MinZoomSize : 0.5,  

                    MaxZoomSize : 2,  

                    SearchMatchAll : true,  

                    InitViewMode : 'Portrait',

                    ReaderingOrder :'false',

                    StartAtPage :'',

                    ViewModeToolsVisible : true,  

                    ZoomToolsVisible : true,  

                    NavToolsVisible : true,  

                    CursorToolsVisible : true,  

                    SearchToolsVisible : true,

                    

                    localeChain: 'zh_CN'  

                    }});    

            </script>              

         

</body>  

</html>

7、测试收工



8、FlexPaper api

Flexpaper可能用到如下参数
 SwfFile (String)需要使用Flexpaper打开的文档
 Scale (Number)初始化缩放比例,参数值应该是大于零的整数
 ZoomTransition (String)Flexpaper中缩放样式,它使用和Tweener一样的样式,默认参数值为easeOut.其他可选值包括: easenone, easeout, linear, easeoutquad
 ZoomTime (Number)从一个缩放比例变为另外一个缩放比例需要花费的时间,该参数值应该为0或更大。
 ZoomInterval (Number)缩放比例之间间隔,默认值为0.1,该值为正数。
 FitPageOnLoad (Boolean)初始化得时候自适应页面,与使用工具栏上的适应页面按钮同样的效果。
 FitWidthOnLoad (Boolean)初始化的时候自适应页面宽度,与工具栏上的适应宽度按钮同样的效果。
 localeChain (String)设置地区(语言),目前支持以下语言。

en_US (English) 

fr_FR (French) 

zh_CN (Chinese, Simple) 

es_ES (Spanish) 

pt_BR (Brazilian Portugese) 

ru_RU (Russian) 

fi_FN (Finnish) 

de_DE (German) 

nl_NL (Netherlands) 

tr_TR (Turkish) 

se_SE (Swedish) 

pt_PT (Portugese) 

el_EL (Greek) 

da_DN (Danish) 

cz_CS (Czech) 

it_IT (Italian) 

pl_PL (Polish) 

pv_FN (Finnish) 

hu_HU (Hungarian)
 FullScreenAsMaxWindow (Boolean)当设置为true的时候,单击全屏按钮会打开一个flexpaper最大化的新窗口而不是全屏,当由于flash播放器因为安全而禁止全屏,而使用flexpaper作为独立的flash播放器的时候设置为true是个优先选择。
 ProgressiveLoading (Boolean)当设置为true的时候,展示文档时不会加载完整个文档,而是逐步加载,但是需要将文档转化为9以上的flash版本(使用pdf2swf的时候使用-T 9 标签)。
 MaxZoomSize (Number)设置最大的缩放比例。
 MinZoomSize (Number)最小的缩放比例。
 SearchMatchAll (Boolean)设置为true的时候,单击搜索所有符合条件的地方高亮显示。
 InitViewMode (String)设置启动模式如"Portrait" or "TwoPage".
 ViewModeToolsVisible (Boolean)工具栏上是否显示样式选择框。
 ZoomToolsVisible (Boolean)工具栏上是否显示缩放工具。
 NavToolsVisible (Boolean)工具栏上是否显示导航工具。
 CursorToolsVisible (Boolean)工具栏上是否显示光标工具。
 SearchToolsVisible (Boolean)

 

 
工具栏上是否显示搜索。
我经历的这个懊恼的过程...希望对大家有帮助;

有问题可咨询我(小民工一个);

liubf995250@163.com 

微博:TactyBOY
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息