文件的上传和下载都比较简单,在线预览比较复杂,针对不同类型的文件可能要进行不同的处理。
本文使用了 pdf.js 和 openoffice 两种方法实现文件的预览
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.jodconvertergroupId>
<artifactId>jodconverter-coreartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>org.jodconvertergroupId>
<artifactId>jodconverter-spring-boot-starterartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>org.jodconvertergroupId>
<artifactId>jodconverter-localartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
dependencies>
fileTest.html
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<h3>文件上传h3>
<form action="/uploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="file"/><br/><br/>
<input type="submit" value="提交">
form>
<hr/>
<form action="/uploadFiles" method="post" enctype="multipart/form-data">
<input type="file" name="file"/><br/><br/>
<input type="file" name="file"/><br/><br/>
<input type="file" name="file"/><br/><br/>
<input type="submit" value="提交">
form>
<hr/>
<h3>文件下载h3>
点击下载<a href="/downFile">《下载测试》a>
<hr/>
<h3>文件预览h3>
点击预览<a href="javascript:void();" onclick="viewFileOnline()">《预览测试》a>
body>
<script type="text/javascript">
function viewFileOnline(){
window.open("/js/pdfjs/web/viewer.html?file=/preview");
}
script>
html>
application.properties
主要是用来配置 openoffice ,在线预览用的
如果没有下载好 openoffice,最好把 openoffice 的配置注释掉,要不然启动项目时报错
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.html
# openoffice 的配置
jodconverter.local.enabled=true
jodconverter.local.office-home=C:/Program Files (x86)/OpenOffice 4
jodconverter.local.max-tasks-per-process=100
jodconverter.local.port-numbers=8100
感觉文件上传没什么好说的,获取相关属性存到数据库就行了。
/**
* 单文件上传
* @param file
* @return
* @throws IOException
*/
@PostMapping("/uploadFile")
@ResponseBody
public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
if (file.isEmpty()) {
return "上传失败,请选择文件";
}
String fileName = file.getOriginalFilename();
System.out.println("originalFilename==" + fileName); // 文件名.文档类型
System.out.println("name==" + file.getName());// 获取的是input中 name 的值
System.out.println("size==" + file.getSize());// 文件大小,单位:B
String filePath = "E:/temptest/";
File dest = new File(filePath + fileName);
try {
// 方式一
file.transferTo(dest);
// 方式二
//IOUtils.copy(file.getInputStream(), new FileOutputStream(dest));
LOGGER.info("上传成功");
return "上传成功";
} catch (IOException e) {
LOGGER.error(e.toString(), e);
}
return "上传失败!";
}
/**
* 多文件上传
* @param file
* @return
*/
@PostMapping("/uploadFiles")
@ResponseBody
public String uploadFiles(HttpServletRequest request) {
List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
String filePath = "E:/temptest/";
for (int i = 0; i < files.size(); i++) {
MultipartFile file = files.get(i);
if (file.isEmpty()) {
System.out.println("未找到附件。。。");
System.out.println("上传第" + (++i) + "个文件失败");
i--; // 需要判断下一个附件是否可以进行上传,把上一行+1的下标减回去
continue;
}
String fileName = file.getOriginalFilename();
File dest = new File(filePath + fileName);
try {
file.transferTo(dest);
LOGGER.info("第" + (i + 1) + "个文件上传成功");
} catch (IOException e) {
LOGGER.error(e.toString(), e);
return "上传第" + (++i) + "个文件失败";
}
}
return "上传成功";
}
/**
* 文件下载
* .doc .docx .pdf .xls .xlsx .jpg .png .gif .txt .js .css .html .java的文件均可下载成功
* @return
* @throws UnsupportedEncodingException
*/
@RequestMapping("/downFile")
public ResponseEntity<FileSystemResource> down()throws UnsupportedEncodingException{
String uploadPath = "E:/testFile";
String realimgurl=uploadPath+"/DemoOneApplication.java";
//String realimgurl=uploadPath+"/scDoc/Self-service analysis tool _ user manual.doc";
System.out.println(realimgurl);
File file = new File(realimgurl);
if (file == null){
return null;
}
String suffixType =realimgurl.substring(realimgurl.lastIndexOf("."));
String newfilename ="自定义文件名称"+suffixType;
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(newfilename, "UTF-8"));
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity
.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new FileSystemResource(file));
}
可以说我当时能想到的文件类型基本都试了个编,都能正常下载下来
该方法非常简便,不过只能预览 pdf 文件
pdf.js 下载地址:http://mozilla.github.io/pdf.js/
/**
* pdf.js实现,只能预览pdf
* @param request
* @param response
*/
@RequestMapping("/preview")
public void pdfPreview(HttpServletRequest request, HttpServletResponse response) {
//PDF文件地址
File file = new File("E:/testFile/temp.pdf");
if (file.exists()) {
byte[] data = null;
FileInputStream input=null;
try {
input= new FileInputStream(file);
data = new byte[input.available()];
input.read(data);
response.getOutputStream().write(data);
} catch (Exception e) {
System.out.println("pdf文件处理异常:" + e);
}finally{
try {
if(input!=null){
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
该方式可以把各种文档转换成 pdf 文件,然后进行预览,使用该方法必须先安装 openoffice 。下载地址:http://www.openoffice.org/download/index.html
测试该方法试了 .doc .docx .xlsx .xls .jpg .png .pdf 类型的文件,发现 .xls 和 .pdf类型的读不出来,其他的均可转换并查看。
后面对于 .pdf 的文件,我跳过转换步骤,把源文件直接当做送到前端的输入流,即可成功预览。所以,在应用过程中,应当是要获取源文件的文件类型的,要分类处理并保存到数据库
我是在 windows 测试的,安装好 openoffice,没有特意到 cmd 中启动它,在这个项目启动时,我发现会自动启动 openoffice
// 注入转换器
@Autowired
private DocumentConverter converter;
@Autowired
private HttpServletResponse response;
@RequestMapping("/viewByPDF")
public void viewByPDF() {
File file = new File("E:/testFile/yue.jpg");//需要转换的文件
try {
File newFile = new File("E:/prePDF");//转换之后文件生成的地址
if (!newFile.exists()) {
newFile.mkdirs();
}
//文件转化
converter.convert(file).to(new File("E:/prePDF/view.pdf")).execute();
//使用response,将pdf文件以流的方式发送的前端
ServletOutputStream outputStream = response.getOutputStream();
InputStream in = new FileInputStream(new File("E:/prePDF/view.pdf"));// 读取文件
// 如果源文件就是 pdf,不要转换
//InputStream in = new FileInputStream(new File("E:/testFile/temp.pdf"));// 读取文件
// copy文件
int i = IOUtils.copy(in, outputStream);
System.out.println(i);
in.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
由于在某些浏览器,如 IE ,点击预览时会提示下载,一些类型的文件起不到预览的作用,因此,可以利用 openoffice 先把文件转换为pdf,然后用 pdf.js 的方法进行预览
对于在线预览功能,我发现有篇博客考虑得很周全,写得很细致,可以参考一下 >>> https://blog.csdn.net/ccc1234_/article/details/79052809
本篇博客代码已上传 github >>> https://github.com/YOUflyme/demo_file