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跟着代碼走就能屢清楚了。篇幅所限,有些業務處理的方法和數據庫交互的方法不貼了。有需要的留言交流

以上內容為本人自學及總結,如有錯誤,麻煩大家及時指出並提示我更正。謝謝!

          

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM