做項目的時候碰到一個需求 :用戶上傳的文件需要在線進行預覽(最少要支持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跟着代碼走就能屢清楚了。篇幅所限,有些業務處理的方法和數據庫交互的方法不貼了。有需要的留言交流
以上內容為本人自學及總結,如有錯誤,麻煩大家及時指出並提示我更正。謝謝!