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) 编辑 收藏 举报