实现文件预览,首先,pdf的实现是比较简单的,因为pdf和图片中的文字是不能改动的,但是word,excel文字是可变动的,所以文件预览首先需要将文件转化为pdf格式,方可预览。
首先需要一个插件和几个jar包。
插件:
openOffice
jar包:
jodconverter-3.0-beta-4.jar
jodconverter-core-4.1.0.jar
lombok-1.16.6.jar
juh-3.2.1.jar
jurt-3.2.1.jar
unoil-3.2.1.jar
ridl-3.2.1.jar
具体架构图如下:
代码如下:
action层(controller层)
/**
* 文件预览
* @param id 文件保存时名称
* @param name 文件原名
* @param ext 文件后缀
* @param request
* @param response
* @return
* @throws Exception
*/
@RequestMapping(value = "/inline")
public String inline(String newName,String name,String ext,HttpServletRequest request,HttpServletResponse response){
//BaseConfig.uploadPath + "flow_task" 是参数savepath, 为自己设置的文件保存路径
return FileUtils.inline(BaseConfig.uploadPath + "flow_task", name, newName, ext,request,response);
}
FilePreviewUtil工具类(借鉴于github)
package com.oa.commons.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.regex.Pattern;
/**
* 这是一个工具类,主要是为了使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx)
* 参考代码 :https://github.com/ourlang/preview
* @author 福小林
*/
public class FilePreviewUtil {
private static final Log LOG = LogFactory.getLog(FilePreviewUtil.class);
private FilePreviewUtil(){
}
/**
* 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件<br>
* @param inputFilePath 源文件路径源文件路径
* 源文件路径,如:"e:/test.doc"
* @return 转换后的pdf文件
*/
public static File openOfficeToPdf(String inputFilePath) {
return office2pdf(inputFilePath);
}
/**
* 根据操作系统的名称,获取OpenOffice.org 4的安装目录<br>
* 如我的OpenOffice.org 4安装在:C:\Program Files (x86)\OpenOffice 4
* 请根据自己的路径做相应的修改
* @return OpenOffice.org 4的安装目录
*/
private static String getOfficeHome() {
//这个路径为你自己安装openOffice的路径
return "C:/Program Files (x86)/OpenOffice 4";
}
/**
* 连接OpenOffice.org 并且启动OpenOffice.org
* @return OfficeManager对象
*/
private static OfficeManager getOfficeManager() {
DefaultOfficeManagerConfiguration config = new DefaultOfficeManagerConfiguration();
// 设置OpenOffice.org 的安装目录
String officeHome = getOfficeHome();
config.setOfficeHome(officeHome);
// 启动OpenOffice的服务
OfficeManager officeManager = config.buildOfficeManager();
officeManager.start();
return officeManager;
}
/**
* 把源文件转换成pdf文件
* @param inputFile 文件对象
* @param outputFilePath pdf文件路径
* @param inputFilePath 源文件路径
* @param converter 连接OpenOffice
*/
private static File converterFile(File inputFile, String outputFilePath, String inputFilePath, OfficeDocumentConverter converter) {
File outputFile = new File(outputFilePath);
// 假如目标路径不存在,则新建该路径
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
converter.convert(inputFile, outputFile);
System.out.println("文件:" + inputFilePath + "\n转换为\n目标文件:" + outputFile + "\n成功!");
return outputFile;
}
/**
* 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件<br>
* @param inputFilePath 源文件路径
* 源文件路径,如:"e:/test.doc"
* 目标文件路径,如:"e:/test_doc.pdf"
* @return 对应的pdf文件
*/
private static File office2pdf(String inputFilePath) {
OfficeManager officeManager = null;
try {
if (StringUtils.isEmpty(inputFilePath)) {
LOG.info("输入文件地址为空,转换终止!");
return null;
}
File inputFile = new File(inputFilePath);
// 转换后的文件路径 这里可以自定义转换后的路径,这里设置的和源文件同文件夹
String outputFilePath = getOutputFilePath(inputFilePath);
if (!inputFile.exists()) {
LOG.info("输入文件不存在,转换终止!");
return null;
}
// 获取OpenOffice的安装路劲
officeManager = getOfficeManager();
// 连接OpenOffice
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
return converterFile(inputFile, outputFilePath, inputFilePath, converter);
} catch (Exception e) {
LOG.error("转化出错!", e);
} finally {
// 停止openOffice
if (officeManager != null) {
officeManager.stop();
}
}
return null;
}
/**
* 获取输出文件路径 可自定义
* @param inputFilePath 源文件的路径
* @return 取输出pdf文件路径
*/
private static String getOutputFilePath(String inputFilePath) {
return inputFilePath.replaceAll("." + getPostfix(inputFilePath), ".pdf");
}
/**
* 获取inputFilePath的后缀名,如:"e:/test.doc"的后缀名为:"doc"<br>
* @param inputFilePath 源文件的路径
* @return 源文件的后缀名
*/
private static String getPostfix(String inputFilePath) {
int index = inputFilePath.lastIndexOf('.');
return inputFilePath.substring(index+1);
}
}
FileUtil类
/**
* 预览文件
* @param savePath 保存目录
* @param name 文件原名
* @param nowName 保存时的UUID 不包含后缀
* @param ext 文件后缀
* @param request
* @param response
* @return
*/
public static String inline(String savePath,String name,String uuid,String ext,HttpServletRequest request,HttpServletResponse response){
response.addHeader("Access-Control-Allow-Origin", "*");
OutputStream toClient=null;
try{
String path=savePath+"/"+uuid+"."+ext;
// String path=savePath+"/"+name;
//判断此文件是否为pdf
File file=null;
if(ext.equals("pdf")){
//如果是pdf
file = new File(path);
}else{
//如果不是,转化为pdf
file =FilePreviewUtil.openOfficeToPdf(path);
}
if(!file.exists()){
//不存在
request.setAttribute("name", name);
return "download_error";//返回下载文件不存在
}
// if(!inOnLineExt(ext)){
// response.setContentType("application/octet-stream");
// }
// 根据不同浏览器 设置response的Header
// String userAgent = request.getHeader("User-Agent").toLowerCase();
//
// if(userAgent.indexOf("msie")!=-1||userAgent.indexOf("trident")!=-1){
// //ie浏览器
// //System.out.println("ie浏览器");
// response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(name,"utf-8"));
//
// }else{
// response.addHeader("Content-Disposition", "inline;filename=" + new String(name.getBytes("utf-8"),"ISO8859-1"));
// }
// response.addHeader("Content-Length", ""+file.length());
// //以流的形式下载文件
// InputStream fis = new BufferedInputStream(new FileInputStream(path));
// byte[] buffer = new byte[fis.available()];
// fis.read(buffer);
// fis.close();
// toClient = new BufferedOutputStream(response.getOutputStream());
// toClient.write(buffer);
// toClient.flush();
//把转换后的pdf文件响应到浏览器上面
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream br = new BufferedInputStream(fileInputStream);
byte[] buf = new byte[1024];
int length;
// 清除首部的空白行。非常重要
response.reset();
//设置调用浏览器嵌入pdf模块来处理相应的数据。
response.setContentType("application/pdf");
response.setHeader("Content-Disposition","inline; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
OutputStream out = response.getOutputStream();
//写文件
while ((length = br.read(buf)) != -1){
out.write(buf, 0, length);
}
br.close();
out.close();
return null;
}catch (Exception e) {
e.printStackTrace();
response.reset();
return "exception";//返回异常页面
}finally{
if(toClient!=null){
try {
toClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件预览效果(word示例)
如有不对的地方,请在评论区纠正。