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

在线预览实现简介:

    过程分为: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

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第1张图片

 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包

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第2张图片

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

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第3张图片

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第4张图片

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

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

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

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第5张图片

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


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、测试收工

java对文档等、附件在线预览的详细开发步骤解析:openOffice+SwfTools+FlexPaper_第6张图片




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)

 

 

工具栏上是否显示搜索。


我经历的这个懊恼的过程...希望对大家有帮助;

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

[email protected] 

微博:TactyBOY


你可能感兴趣的:(解决方案,在线预览,openoffice安装,swftools安装)