文件的上傳和下載都比較簡單,在線預覽比較複雜,針對不同類型的文件可能要進行不同的處理。
本文使用了 pdf.js 和 openoffice 兩種方法實現文件的預覽
pom.xml
上傳和下載都不需要添加什麼依賴,該文件中除了springboot本身的依賴就是在線預覽需要的依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--jodconverter 核心包 -->
<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-core -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.artofsolving.jodconverter/jodconverter-core -->
<!--
<dependency>
<groupId>org.artofsolving.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>3.0-beta-4</version>
</dependency>
-->
<!--springboot支持包,裏面包括了自動配置類 -->
<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-spring-boot-starter -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<!--jodconverter 本地支持包 -->
<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-local -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
fileTest.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</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.js實現
該方法非常簡便,不過只能預覽 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();
}
}
}
}
openoffice實現
該方式可以把各種文檔轉換成 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