码迷,mamicode.com
首页 > 编程语言 > 详细

Java实现文档在线预览(openoffice+swfTools+FlexPaper)

时间:2015-10-26 22:17:00      阅读:341      评论:0      收藏:0      [点我收藏+]

标签:

      文档在线预览在项目中早就完成了,后来又经过了一次优化。但是一直都没时间去记录遇到的问题,文档在线预览的详细步骤可以参考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();        
    }

}

问题一  flexPaper无法加载SWF文件名为中文问题

       这个问题我开始是将要转换成的SWF文件以UUID命名,后来发现每次预览文件都得转换,很影响效率,同时也会使项目中转换的swf文件越来越多,浪费空间。最后想到每个文件夹中不会出现相同的文件名(包括后缀名),那就可以用文件名的hash值作为转换后SWF文件的文件名,这样就解决了中文名问题和文件只需要转换一次就能多次预览。具体代码实现是红色标记部分。

问题二  要预览的文档为PDF格式

        原文中并没有考虑这种情况,但是项目中大多数文件都是PDF格式的。PDF文档不需要经过OpenOffice转换,可以直接转换成SWF格式,而且原文中将PDF格式转换成SWF格式后就把PDF文件删除,所以我们先要判断文件的格式再删文件,这个问题的具体解决代码可以看灰色部分的标记和注解

问题三  txt文件转换后乱码问题

        这个问题原文中有解答,EncodingDetect类也可以在原文中下载。具体代码可以看黄色部分标记。

问题四  转换后的文件不放在项目中

        在线预览是通过flexPaper实现的,flexPaper是由js写的,js只能读取项目中的路径,无法读取绝对路径。一开始我是把所有转换的的文件存放在项目下,但是老板说这样不好,如果以后项目更新转换的文件就没了,而且把文件都存到项目中去会使项目占得空间越来越大,最好是保存到项目外的路径中去,老板的要求大于一切,我疯狂百度最后找到了思路。把文件以流的形式传到界面上去。

第一步 创建Servlet类

       创建一个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>

第二步  修改documentView.jsp中预览文件路径

<%@ 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!