SpringMvc+OpenOffice4实现文档文件预览

做项目的时候碰到一个需求 :用户上传的文件需要在线进行预览(最少要支持word pdf txt excel )的预览。

openoffice的下载和使用自行百度吧~

先将文档转为swf文件。

需要jar包为:

转换需要这个东西 (在代码用有注释哪里需要这个地址)

 

 

ps:

  用maven的朋友可能找不到 2.2.2的jar 只有2.2.1 但是2.2.1又不能兼容高版本的office文件。

    我尝试过2种解决方案都可以实现:1.pom.xml中指向本地的jar,自制maven的连接。2.下载jar包放入lib  然后buildPath。(有其他好方法告诉我啊)。

以下是转换类,细节看注释

  1 package com.common;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.InputStreamReader;
  8 
  9 import org.apache.log4j.Logger;
 10 
 11 import com.artofsolving.jodconverter.DocumentConverter;
 12 import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
 13 import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
 14 import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
 15 
 16 /**
 17  * 文档转为swf工具类
 18  * 不支持中文路径  swf文件名不能为中文名
 19  * 
 20  * @author lwh 2018年9月25日 上午11:27:29
 21  */
 22 public class DocConverter {
 23     private static Logger logger = Logger.getLogger(DocConverter.class);
 24 
 25     private static final int environment = 1;// 环境1:windows,2:linux(涉及pdf2swf路径问题)
 26     private String fileString;
 27     private String outputPath = "";// 输入路径,如果不设置就输出在默认位置(可不修改)
 28     private String fileName;
 29     private File pdfFile;
 30     private File swfFile;
 31     private File docFile;
 32     private String pdf2swfexePath = "";//pdf2swf.exe文件的位置
 33 
 34     public DocConverter(String fileString, String outputPath, String pdf2swfexePath) {
 35         this.outputPath = outputPath;
 36         this.pdf2swfexePath = pdf2swfexePath;
 37         ini(fileString, outputPath);
 38     }
 39 
 40     public DocConverter(String fileString) {
 41 
 42         ini(fileString);
 43     }
 44 
 45     /*
 46      * 重新设置 file @param fileString
 47      */
 48     public void setFile(String fileString) {
 49         ini(fileString);
 50     }
 51 
 52     /**
 53      * 初始化 文件输出到默认位置 lwh 2018年9月27日 上午10:27:36
 54      * 
 55      * @param fileString
 56      */
 57     private void ini(String fileString) {
 58         this.fileString = fileString;
 59         fileName = fileString.substring(0, fileString.lastIndexOf(".")).trim();
 60         docFile = new File(fileString);
 61         String fn = String.valueOf(System.currentTimeMillis());
 62         pdfFile = new File(fn.trim() + ".pdf");
 63         swfFile = new File(fn.trim() + ".swf");
 64     }
 65 
 66     /**
 67      * 文件输出到指定位置 lwh 2018年9月27日 上午10:27:14
 68      * 
 69      * @param fileString  待转换文件全路径
 70      * @param optPath  文件输出位置
 71      */
 72     private void ini(String fileString, String optPath) {
 73 
 74         this.fileString = fileString;
 75         String fn = String.valueOf(System.currentTimeMillis());
 76         docFile = new File(fileString);
 77         pdfFile = new File(optPath, fn + ".pdf");
 78         swfFile = new File(optPath, fn + ".swf");
 79     }
 80 
 81     /**
 82      * 文档转为pdf lwh 2018年9月27日 上午10:28:21
 83      * 
 84      * @throws Exception
 85      */
 86     private void doc2pdf() throws Exception {
 87         if (docFile.exists()) {
 88             if (!pdfFile.exists()) {
 89                 OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
 90                 try {
 91                     connection.connect();
 92                     DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
 93                     converter.convert(docFile, pdfFile);
 94                     connection.disconnect();
 95                     logger.info("****pdf转换成功,PDF输出:" + pdfFile.getPath() + "****");
 96 
 97                 } catch (java.net.ConnectException e) {
 98                     e.printStackTrace();
 99                     throw new Exception("****swf转换异常,openoffice服务未启动!****");
100                 } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
101                     e.printStackTrace();
102                     throw new Exception("****swf转换器异常,读取转换文件失败****");
103                 } catch (Exception e) {
104                     e.printStackTrace();
105                     throw e;
106                 }
107             } else {
108                 throw new Exception("****已经转换为pdf,不需要再进行转化****");
109             }
110         } else {
111             throw new Exception("****swf转换器异常,需要转换的文档不存在,无法转换****");
112         }
113     }
114 
115     /**
116      * pdf转为swf文件
117      * lwh
118      * 2018年9月27日 上午10:28:31
119      * @throws Exception
120      */
121     @SuppressWarnings("unused")
122     private void pdf2swf() throws Exception {
123         Runtime r = Runtime.getRuntime();
124         if (!swfFile.exists()) {
125             if (pdfFile.exists()) {
126                 if (1 == environment)// windows环境处理
127                 {
128                     try {
129                         // 这里根据SWFTools安装路径需要进行相应更改 修改2
130                         Process p = r.exec(pdf2swfexePath + "/pdf2swf.exe " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
131                         logger.info(loadStream(p.getInputStream()));
132                         logger.info(loadStream(p.getErrorStream()));
133                         logger.info(loadStream(p.getInputStream()));
134                         logger.info("****swf转换成功,文件输出:" + swfFile.getPath() + "****");
135                         if (pdfFile.exists()) {
136                             pdfFile.delete();
137                         }
138                     } catch (Exception e) {
139                         e.printStackTrace();
140                         throw e;
141                     }
142                 } else if (environment == 2)// linux环境处理
143                 {
144                     try {
145                         Process p = r.exec("pdf2swf " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
146                         logger.info(loadStream(p.getInputStream()));
147                         logger.info(loadStream(p.getErrorStream()));
148                         logger.info("****swf转换成功,文件输出:" + swfFile.getPath() + "****");
149                         if (pdfFile.exists()) {
150                             pdfFile.delete();
151                         }
152                     } catch (Exception e) {
153                         e.printStackTrace();
154                         throw e;
155                     }
156                 }
157             } else {
158                 throw new Exception("****pdf不存在,无法转换****");
159             }
160         } else {
161             throw new Exception("****swf已存在不需要转换****");
162         }
163     }
164 
165     static String loadStream(InputStream in) throws IOException {
166         int ptr = 0;
167         // 把InputStream字节流 替换为BufferedReader字符流
168         BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GB2312"));
169         StringBuilder buffer = new StringBuilder();
170         while ((ptr = reader.read()) != -1) {
171             buffer.append((char) ptr);
172         }
173         return buffer.toString();
174     }
175 
176     /**
177      * 转换主方法
178      * lwh
179      * 2018年9月27日 上午10:28:47
180      * @return
181      * @throws Exception 
182      */
183 
184     @SuppressWarnings("unused")
185     public boolean conver() throws Exception {
186         boolean  flag = false;
187         if (swfFile.exists()) {
188             logger.info("****swf转换器开始工作,该文件已经转换为swf****");
189             flag =  true;
190         }
191         if (environment == 1) {
192             logger.info("****swf转换器开始工作,当前设置运行环境windows****");
193         } else {
194             logger.info("****swf转换器开始工作,当前设置运行环境linux****");
195         }
196         try {
197             doc2pdf();
198             pdf2swf();
199         } catch (Exception e) { // TODO: Auto-generated catch block
200             e.printStackTrace();
201             
202             flag =  false;
203             throw new Exception(e.getMessage());
204         }
205         if (swfFile.exists()) {
206             flag =  true;
207         } else {
208             flag =  false;
209         }
210         return  flag;
211     }
212 
213     /**
214      * 返回转换 后的swf文件的路径
215      * lwh
216      * 2018年9月27日 上午10:29:05
217      * @return
218      */
219     public String getswfPath() {
220         if (swfFile.exists()) {
221             String tempString = swfFile.getPath();
222             tempString = tempString.replaceAll("\\\\", "/");
223             return tempString;
224         } else {
225             return "";
226         }
227 
228     }
229 
230     /*
231      * 设置输出路径
232      */public void setOutputPath(String outputPath) {
233         this.outputPath = outputPath;
234         if (!outputPath.equals("")) {
235             String realName = fileName.substring(fileName.lastIndexOf("/"), fileName.lastIndexOf("."));
236             if (outputPath.charAt(outputPath.length()) == '/') {
237                 swfFile = new File(outputPath + realName + ".swf");
238             } else {
239                 swfFile = new File(outputPath + realName + ".swf");
240             }
241         }
242     }
243 
244     public static void main(String[] args) {
245         // 修改1-不支持中文路径和中文文档
246         // DocConverter d = new DocConverter("D://testfile/test2.pptx");
247         // d.conver();
248     }
249 }

Bean定义(属性是业务需求 ,自行修改)

package com.main.pojo;

import java.io.Serializable;

import com.auto.annotation.Column;
import com.auto.annotation.Table;

/**
 * 系统附件表
 * 
 * @author lwh
 * 
 */
@Table(name="TZW_ATTACHMENT",jsname="附件",includeSupperClass=false)
public class Attachment  implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Column(flag = "primary")
    private String id; // 附件id
    @Column
    private String asocciateId;// 附件所属id
    @Column(type = "varchar(200)")
    private String fileName;// 文件名
    @Column(type = "varchar(200)")
    private String fileUrl;// 文件路径
    @Column(type = "int")
    private Integer attachmentType;// 附件类型
    @Column(type = "varchar(200)")
    private String memo;// 备注
    /**
     * 附件类型定义。例如:凭证附件 值为1
     * @author lwh
     *
     */
    public static final class AttachmentType {
        /**
         * 凭证附件
         */
        public final static Integer VOUCHER = 1;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    

    public String getAsocciateId() {
        return asocciateId;
    }

    public void setAsocciateId(String asocciateId) {
        this.asocciateId = asocciateId;
    }

    public String getFileUrl() {
        return fileUrl;
    }

    public void setFileUrl(String fileUrl) {
        this.fileUrl = fileUrl;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public Integer getAttachmentType() {
        return attachmentType;
    }

    public void setAttachmentType(Integer attachmentType) {
        this.attachmentType = attachmentType;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }
}

 

 

以下是controller的代码(代码中有一段if是用来控制图片预览的 isPic==false 这段就是文档预览的实现 )

package com.main.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.common.CommonUtil;
import com.common.DocConverter;
import com.main.pojo.Attachment;
import com.main.service.AttachmentService;

/**
 * 附件预览controller 基于OppenOfiice实现
 * 
 * @author lwh 2018年9月21日 下午3:28:38
 */
@Controller
@RequestMapping("/attachmentPreview")
public class AttachmentPreviewController {
    @Resource
    private AttachmentService attachmentService;

    /**
     * 附件预览(支持excel word pdf txt ppt pdf png gif bpm jpg) lwh 2018年10月11日
     * 下午4:25:55
     * 
     * @param id
     *            附件
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/filePreview/{id}")
    public String toFilePreviewPage(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
        boolean res = false;
        String contexPath = request.getSession().getServletContext().getRealPath("/");
        boolean isPic = false;// 判断是否为图片预览 ·
        try {

            Attachment att = attachmentService.getById(id);
            if (isPicture(att.getFileName())) {
                List<Attachment> attList = new ArrayList<>();
                attList.add(att);
                // TODO
                /*
                 * 
                 * 为了避免预览时大量下载造成压力故图片预览的时候 不做图片下载IO操作, 通过配置虚拟目录读取,将以下配置加入
                 * tomcat的server.xml的<host>中 <Context path="/attachment"
                 * docBase="E:\apache-tomcat-7.0.90\financeAttatch\"
                 * docBase为tomcat下的附件存放目录的绝对路径 reloadable="true"></Context>
                 * 如果配置nginx或者其他负载均衡等。。。 需要将虚拟目录加入其配置文件,否则可能会被拦截,导致图片无法显示
                 */

                isPic = true;
                List<Attachment> attListTemp = attachmentService.getPictureAttachment(att.getAsocciateId(), att.getId());

                /*
                 * 设置当前点击图片为第一张显示
                 */
                if (attListTemp != null && attListTemp.size() > 0) {
                    for (Attachment attachment : attListTemp) {
                        attList.add(attachment);
                    }
                }
                request.setAttribute("list", attList);
            } else {
                // TODO
                // 服务器上需要安装openoffice 并启动服务.
                DocConverter d = new DocConverter(att.getFileUrl() + File.separator + att.getFileName(), contexPath + "/resources/file/ftp", contexPath
                        + "/WEB-INF/classes");
                delete(contexPath + "/resources/file/ftp");
                // 调用conver方法开始转换,先执行doc2pdf()将office文件转换为pdf;再执行//pdf2swf()将pdf转换为swf;
                res = d.conver();
                String fn = d.getswfPath();
                if (CommonUtil.isNotNullStr(fn)) {
                    request.setAttribute("swfPath", fn.substring(fn.lastIndexOf("/"), fn.length()));
                }
            }
        } catch (Exception e) {
            request.setAttribute("errorMsg", e.getMessage());
            e.printStackTrace();

        }
        if (res == false && isPic == false) {
            // 类型不支持预览。
            return "attach/Cantpreview";
        }
        if (isPic) {
            return "attach/PicPreview";// 图片预览
        }
        return "attach/FilePreview";// 文档预览
    }

    /**
     * 清除临时文件夹中的文件。
     */
    protected boolean delete(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delete(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delete(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 要预览其他格式的图片,将图片的后缀加入条件即可,支持预览html img标签src="支持的图片格式"  lwh 2018年10月15日
     * 上午11:38:25
     * 
     * @param fileName
     * @return
     */
    public boolean isPicture(String fileName) {

        boolean flag = false;
        if (fileName.endsWith(".jpg") || fileName.endsWith(".bpm") || fileName.endsWith(".png") || fileName.endsWith(".gif")) {
            flag = true;
        }

        return flag;
    }

}

以上服务器端代码基本就是这样了。下面是页面代码

flexpaper插件自行下载一下  导入对应的js即可。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";    
	String swfName = String.valueOf(request.getAttribute("swfPath"));
%> 



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

<title>凭证录入</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<base href="<%=basePath%>">
<link rel="stylesheet"
	href="<%=path%>/resources/style/record-background.css" type="text/css" />
<!-- 通用的文件导入 -->
<jsp:include page="/base.jsp"></jsp:include>
<script type="text/javascript"
	src="<%=path%>/resources/script/extjs4.2/ux/ComBoTree.js"></script>
<script type="text/javascript"
	src="<%=path%>/resources/ueditor/third-party/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="<%=path%>/resources/script/flexpaper/flexpaper.js"></script>
<script type="text/javascript" src="<%=path%>/resources/script/flexpaper/FlexPaperViewer.js"></script>
<script type="text/javascript" src="<%=path%>/resources/script/flexpaper/flexpaper_handlers.js"></script>

</head>
<body>
<div style="padding-left: 5px;padding-top: 5px;padding-bottom: -10px;">
<a href="javascript:void(0)"  class="easyui-linkbutton"  iconCls="icon-back"  onclick="javascript:parent.closePreviewWin()">返回</a>
<font  color='red' >双击文本 可放大查看!</font>
</div>
 <div id="documentViewer" class="flexpaper_viewer" style="width:100%;"></div>
	        <script type="text/javascript"> 
	        $("#documentViewer").css("height", document.documentElement.clientHeight-40);
	        $('#documentViewer').FlexPaperViewer(
	                { config : {

	                    SWFFile :'<%=path%>/resources/file/ftp<%=swfName%>',
	                    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: 'zh_CN'
	                }}
	        );
	        </script>  
	        </div>  

       
</body>
</html>

 

基本上的思路从controller跟着代码走就能屡清楚了。篇幅所限,有些业务处理的方法和数据库交互的方法不贴了。有需要的留言交流

以上内容为本人自学及总结,如有错误,麻烦大家及时指出并提示我更正。谢谢!

          

 

posted on 2018-10-26 15:57  techno-geek  阅读(2148)  评论(0编辑  收藏  举报