做项目的时候碰到一个需求 :用户上传的文件需要在线进行预览(最少要支持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跟着代码走就能屡清楚了。篇幅所限,有些业务处理的方法和数据库交互的方法不贴了。有需要的留言交流
以上内容为本人自学及总结,如有错误,麻烦大家及时指出并提示我更正。谢谢!