1.介紹
本文主要是介紹前后端分離的上傳下載,后端使用的是SpringBoot,持久層用的是mybatis-plus,前端用的Vue,UI用的elementUI,測試了一下,文本,圖片,excel,都是可以上傳下載的,前端就是一個頁面,后端就是一個controller頁面,就可以解決,代碼不清晰的話,我把這個前端的vue 跟 后端的controller代碼,以及本篇文章的MD版本放到了這個鏈接里? https://wwa.lanzous.com/b0cqr478f 密碼:19qb
1.1前端樣子
2.前端
2.1先分享一下前端的全部代碼
<template>
<div>
<center>
?
</center>
<divstyle="float: left;margin-left: 100px">
<!-- ? ?? <router-link to="/reportTools/customQuery" style="color: darkblue">-->
<!-- ? ? ?? 上一步-->
<!-- ? ?? </router-link>-->
<el-buttontype="primary"v-on:click="tocustomQuery">上一步</el-button>
</div>
<divstyle="float: right;margin-right: 100px">
<el-buttontype="primary"v-on:click="saveResource">保存</el-button>
</div>
<br>
<h1>基本信息設(shè)置</h1>
<br>
<br>
<center>
<divstyle="margin-right: 170px">
<el-formref="form":model="form"label-width="120px">
<el-form-itemlabel="報表名稱中文:"style="width: 470px;">
<el-inputv-model="form.reportName"></el-input>
</el-form-item>
<el-form-itemlabel="報表名稱英文:"style="width: 470px;">
<el-inputv-model="form.reportEnName"></el-input>
</el-form-item>
<el-form-itemlabel="報表名稱中英文:"style="width: 470px;">
<el-inputv-model="form.reportChEnName"></el-input>
</el-form-item>
<el-form-itemlabel="報表備注:"style="width: 470px;">
<el-inputv-model="form.remarks"></el-input>
</el-form-item>
<el-form-itemlabel="功能編號"style="width: 470px;">
<el-inputv-model="form.code"></el-input>
</el-form-item>
<el-form-itemlabel="編輯模板:"style="width: 570px;">
<el-inputplaceholder="模板地址"style="width: 200px"disabled></el-input>
<el-uploadclass="upload-demo"
:action="uploadUrl"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
:before-remove="beforeRemove"
multiple
:limit="5"
:on-exceed="handleExceed"
:file-list="fileList">
<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>
</el-upload>
<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>
</el-form-item>
<el-form-itemlabel="模板備注:"style="width: 480px;">
模板用于下載蝉绷,打印EXCEL時使用扣孟。其中{ {CURRENT_USER} }表示當(dāng)前用戶名勉耀,
{ {TITLE} }表示表頭瘫想,{ {DATA} }表示數(shù)據(jù)行醋粟,{ {FOOTER} }表示頁腳區(qū)域靡菇。
? ?? 導(dǎo)出的內(nèi)容不可改動重归,頁眉頁腳區(qū)域可以自由編輯。
</el-form-item>
<el-form-item>
<el-selectv-model="form.isPublic"style="width: 350px;">
<el-optionlabel="私有查詢"value="2"></el-option>
<el-optionlabel="公共查詢"value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-checkboxlabel="是否打印"v-model="form.isPrinting"true-label="1"false-label="2"></el-checkbox>
<el-checkboxlabel="是否導(dǎo)出"v-model="form.isExport"true-label="1"false-label="2"></el-checkbox>
<el-form-itemtype="hidden"style="width: 470px;">
</el-form-item>
</el-form-item>
</el-form>
</div>
</center>
</div>
</template>
?
<script>
importaxiosfrom'axios'
import{uuid}from'vue-uuid';
exportdefault{
data() {
return{
form: {
reportName:'',
reportEnName:'',
reportChEnName:'',
remarks:'',
code:'',
isPublic:'1',
isPrinting:"1",
isExport:"1",
?
datas:[{},{},{},{}],
A0010011:'',
A0010012:'',
A0010013:'',
A0010014:'',
?
?
?
? ?? },
// uuid1:'',
// cusList:{},
uploadUrl:'file/upload',
fileList: [],
?
?
?? }
? },
created() {
?
console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)
// this.handleUUIDv1()
this.form.code=this.$uuid.v1()
console.log("頁面刷新后新產(chǎn)生的uuid是",this.form.code)
?
? },
watch:{
reportName:function(newVal,oldVal) {//新值和原值
?
console.log("name改變了 a:"+newVal+" ?? b:"+oldVal)
?
?? }
? },
methods: {
//使用uuid
// handleUUIDv1() {
// ? this.uuid1 = this.$uuid.v1()
// },
//點(diǎn)擊多選按鈕true和false變成1或者2
reset(form){
this.$refs['form'].resetFields();
?? },
//獲取上個頁面?zhèn)鱽淼臄?shù)據(jù)
getcustomQuery() {
?
letreportName=this.form.reportName
sessionStorage.setItem("reportName",reportName)
letreportEnName=this.form.reportEnName
sessionStorage.setItem("reportEnName",reportEnName)
letreportChEnName=this.form.reportChEnName
sessionStorage.setItem("reportChEnName",reportChEnName)
letremarks=this.form.remarks
sessionStorage.setItem("remarks",remarks)
letcode=this.form.code
sessionStorage.setItem("code",code)
letisPublic=this.form.isPublic
sessionStorage.setItem("isPublic",isPublic)
letisPrinting=this.form.isPrinting
sessionStorage.setItem("isPrinting",isPrinting)
letisExport=this.form.isExport
sessionStorage.setItem("isExport",isExport)
?
?
?
console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)
?? },
// this.$router.push('/reportTools/cusMain'),點(diǎn)擊保存發(fā)送鏈接 并跳轉(zhuǎn)
tocustomQuery(){
this.$router.push('/reportTools/customQuery')
?? },
?
saveResource(){
console.log("當(dāng)前頁面表單的數(shù)據(jù)",this.form)
// sessionStorage.setItem("params",JSON.stringify(this.form))
console.log("sessionStorage中的數(shù)據(jù)",sessionStorage)
this.getcustomQuery()
this.$http.post("http://localhost:8080/reporttools/report-show/addReportShow",sessionStorage).then(
resp=>{
console.log(resp)
//this.$router.push('/reportTools/cusMain')
? ?? })
?? },
handleExceed(files,fileList) {
this.$message.warning(`當(dāng)前限制選擇 5 個文件厦凤,本次選擇了 ${files.length}個文件鼻吮,共選擇了 ${files.length+fileList.length}個文件`);
?? },
beforeRemove(file,fileList) {
returnthis.$confirm(`確定移除 ${file.name}?`);
?? },
handleUploadError(error,file) {
console.log("文件上傳出錯:"+error)
?? },
//測試上傳文件(注意web的上下文)
handleBeforeUpload(file){
console.log("開始上傳较鼓,上傳的文件為:"+file)
letformData=newFormData();
formData.append("multipartFiles",file);
axios({
method:'post',
url:'file/upload',
data:formData,
headers: {'Content-Type':'multipart/form-data'}
}).then((res)=>{
console.log("文件上傳返回:"+res)
}).catch(error=>{
console.log("文件上傳異常:"+error)
? ?? })
?? },
? }
}
</script>
?
<stylescoped>
a{
text-decoration:none;
}
</style>
?
2.2分享一下前端template層的代碼
2.2.1上傳下載template全部代碼
<el-uploadclass="upload-demo"
:action="uploadUrl"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
:before-remove="beforeRemove"
multiple
:limit="5"
:on-exceed="handleExceed"
:file-list="fileList">
<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>
</el-upload>
<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>
2.2.2 上傳代碼
<el-uploadclass="upload-demo"
:action="uploadUrl"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
:before-remove="beforeRemove"
multiple
:limit="5"
:on-exceed="handleExceed"
:file-list="fileList">
<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>
</el-upload>
2.2.3下載代碼
下載代碼就是一個a標(biāo)簽
<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>
2.3分享一下前端script代碼
<script>
importaxiosfrom'axios'
import{uuid}from'vue-uuid';
exportdefault{
data() {
return{
form: {
reportName:'',
reportEnName:'',
reportChEnName:'',
remarks:'',
code:'',
isPublic:'1',
isPrinting:"1",
isExport:"1",
?
datas:[{},{},{},{}],
A0010011:'',
A0010012:'',
A0010013:'',
A0010014:'',
?
?
?
? ?? },
// uuid1:'',
// cusList:{},
uploadUrl:'file/upload',
fileList: [],
?
?
?? }
? },
created() {
?
console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)
// this.handleUUIDv1()
this.form.code=this.$uuid.v1()
console.log("頁面刷新后新產(chǎn)生的uuid是",this.form.code)
?
? },
watch:{
reportName:function(newVal,oldVal) {//新值和原值
?
console.log("name改變了 a:"+newVal+" ?? b:"+oldVal)
?
?? }
? },
methods: {
//使用uuid
// handleUUIDv1() {
// ? this.uuid1 = this.$uuid.v1()
// },
//點(diǎn)擊多選按鈕true和false變成1或者2
reset(form){
this.$refs['form'].resetFields();
?? },
//獲取上個頁面?zhèn)鱽淼臄?shù)據(jù)
getcustomQuery() {
?
letreportName=this.form.reportName
sessionStorage.setItem("reportName",reportName)
letreportEnName=this.form.reportEnName
sessionStorage.setItem("reportEnName",reportEnName)
letreportChEnName=this.form.reportChEnName
sessionStorage.setItem("reportChEnName",reportChEnName)
letremarks=this.form.remarks
sessionStorage.setItem("remarks",remarks)
letcode=this.form.code
sessionStorage.setItem("code",code)
letisPublic=this.form.isPublic
sessionStorage.setItem("isPublic",isPublic)
letisPrinting=this.form.isPrinting
sessionStorage.setItem("isPrinting",isPrinting)
letisExport=this.form.isExport
sessionStorage.setItem("isExport",isExport)
?
?
?
?
?
?
console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)
?? },
// this.$router.push('/reportTools/cusMain'),點(diǎn)擊保存發(fā)送鏈接 并跳轉(zhuǎn)
tocustomQuery(){
this.$router.push('/reportTools/customQuery')
?? },
?
saveResource(){
console.log("當(dāng)前頁面表單的數(shù)據(jù)",this.form)
// sessionStorage.setItem("params",JSON.stringify(this.form))
console.log("sessionStorage中的數(shù)據(jù)",sessionStorage)
this.getcustomQuery()
this.$http.post("http://localhost:8080/reporttools/report-show/addReportShow",sessionStorage).then(
resp=>{
console.log(resp)
//this.$router.push('/reportTools/cusMain')
? ?? })
?? },
handleExceed(files,fileList) {
this.$message.warning(`當(dāng)前限制選擇 5 個文件椎木,本次選擇了 ${files.length}個文件,共選擇了 ${files.length+fileList.length}個文件`);
?? },
beforeRemove(file,fileList) {
returnthis.$confirm(`確定移除 ${file.name}博烂?`);
?? },
handleUploadError(error,file) {
console.log("文件上傳出錯:"+error)
?? },
//測試上傳文件(注意web的上下文)
handleBeforeUpload(file){
console.log("開始上傳香椎,上傳的文件為:"+file)
letformData=newFormData();
formData.append("multipartFiles",file);
axios({
method:'post',
url:'http://localhost:8080/file/upload',
data:formData,
headers: {'Content-Type':'multipart/form-data'}
}).then((res)=>{
console.log("文件上傳返回:"+res)
}).catch(error=>{
console.log("文件上傳異常:"+error)
? ?? })
?? },
? }
}
</script>
?
<stylescoped>
a{
text-decoration:none;
}
</style>
?
2.3.1上傳script全部代碼
主要是對前端做一些限制
handleExceed(files,fileList) {
this.$message.warning(`當(dāng)前限制選擇 5 個文件,本次選擇了 ${files.length}個文件禽篱,共選擇了 ${files.length+fileList.length}個文件`);
},
beforeRemove(file,fileList) {
returnthis.$confirm(`確定移除 ${file.name}畜伐?`);
},
handleUploadError(error,file) {
console.log("文件上傳出錯:"+error)
},
//測試上傳文件(注意web的上下文)
handleBeforeUpload(file){
console.log("開始上傳,上傳的文件為:"+file)
letformData=newFormData();
formData.append("multipartFiles",file);
axios({
method:'post',
url:'http://localhost:8080/file/upload',
data:formData,
headers: {'Content-Type':'multipart/form-data'}
}).then((res)=>{
console.log("文件上傳返回:"+res)
}).catch(error=>{
console.log("文件上傳異常:"+error)
? })
},
2.3.2在data的return里添加
uploadUrl:'file/upload',
fileList: [],
也就是在data層的 return里寫
data(){
return{
? ? uploadUrl:'http://localhost:8080/file/upload',
? ? ? ? fileList: [],
? ? }
}
就這樣前端就完成了
后端主要就是一個controller層
2.3.3Axios的引入
很重要的一個,因為我的寫法不一樣可能有不兼容的地方,有的vue不能這么寫,所以需要引入一下
直接引入就可以,在script里面,
不會就看我上面分享的
importaxiosfrom'axios'
3.后端
3.1后端全部代碼
packagecom.ciic.reporter.updownload.controller;
?
?
importorg.apache.tomcat.util.http.fileupload.IOUtils;
importorg.springframework.web.bind.annotation.*;
importorg.springframework.web.multipart.MultipartFile;
?
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.*;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.nio.file.Paths;
?
?
@RestController
@RequestMapping("file")
publicclassCiicUpDownloadController{
privatefinalstaticStringrootPath="E:/attachment/";
?
@RequestMapping("/upload")
publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){
FilefileDir=newFile(rootPath);
if(!fileDir.exists()&&!fileDir.isDirectory()) {
fileDir.mkdirs();
? ? ?? }
try{
if(multipartFiles!=null&&multipartFiles.length>0) {
for(inti=0;i<multipartFiles.length;i++){
try{
//以原來的名稱命名,覆蓋掉舊的躺率,這里也可以使用UUID之類的方式命名烤礁,這里就沒有處理了
StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();
System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()
+",保存的路徑為:"+storagePath);
// 3種方法: 第1種
// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);
// 第2種
Pathpath=Paths.get(storagePath);
Files.write(path,multipartFiles[i].getBytes());
// 第3種
// multipartFiles[i].transferTo(new File(storagePath));
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ? ? ? ? ?? }
? ? ? ? ? ? ?? }
? ? ? ? ?? }
?
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
//前端可以通過狀態(tài)碼肥照,判斷文件是否上傳成功
return"文件上傳成功";
?? }
?
?
/**
*
* @param fileName 文件名
* @param response
* @return
*/
@RequestMapping("/download")
publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){
OutputStreamos=null;
InputStreamis=null;
try{
// 取得輸出流
os=response.getOutputStream();
// 清空輸出流
response.reset();
response.setContentType("application/x-download;charset=utf-8");
//Content-Disposition中指定的類型是文件的擴(kuò)展名,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的勤众,點(diǎn)保存后舆绎,文件以filename的值命名,
// 保存類型以Content中設(shè)置的為準(zhǔn)们颜。注意:在設(shè)置Content-Disposition頭字段之前吕朵,一定要設(shè)置Content-Type頭字段。
//把文件名按UTF-8取出窥突,并按ISO8859-1編碼努溃,保證彈出窗口中的文件名中文不亂碼,中文不要太多阻问,最多支持17個中文梧税,因為header有150個字節(jié)限制。
response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));
//讀取流
Filef=newFile(rootPath+fileName);
is=newFileInputStream(f);
if(is==null) {
System.out.println("下載附件失敗称近,請檢查文件“"+fileName+"”是否存在");
return"下載附件失敗第队,請檢查文件“"+fileName+"”是否存在";
? ? ? ? ?? }
//復(fù)制
IOUtils.copy(is,response.getOutputStream());
response.getOutputStream().flush();
}catch(IOExceptione) {
return"下載附件失敗,error:"+e.getMessage();
? ? ?? }
//文件的關(guān)閉放在finally中
finally
? ? ?? {
try{
if(is!=null) {
is.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
try{
if(os!=null) {
os.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
? ? ?? }
//其實,這個返回什么都不重要
return"下載成功";
?? }
?
}
?
3.2后端定義一個class類
@RestController
@RequestMapping("file")
publicclassCiicUpDownloadController{
?
}
3.3后端定義一個上傳的路徑
privatefinalstaticStringrootPath="E:/attachment/";
3.3.1加上上面定義的類也就是
@RestController
@RequestMapping("file")
publicclassCiicUpDownloadController{
? ? privatefinalstaticStringrootPath="E:/attachment/";
}
3.4后端定義上傳方法
@RequestMapping("/upload")
publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){
FilefileDir=newFile(rootPath);
if(!fileDir.exists()&&!fileDir.isDirectory()) {
fileDir.mkdirs();
? ? ?? }
try{
if(multipartFiles!=null&&multipartFiles.length>0) {
for(inti=0;i<multipartFiles.length;i++){
try{
//以原來的名稱命名,覆蓋掉舊的刨秆,這里也可以使用UUID之類的方式命名凳谦,這里就沒有處理了
StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();
System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()
+",保存的路徑為:"+storagePath);
// 3種方法: 第1種
// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);
// 第2種
Pathpath=Paths.get(storagePath);
Files.write(path,multipartFiles[i].getBytes());
// 第3種
// multipartFiles[i].transferTo(new File(storagePath));
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ? ? ? ? ?? }
? ? ? ? ? ? ?? }
? ? ? ? ?? }
?
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
//前端可以通過狀態(tài)碼衡未,判斷文件是否上傳成功
return"文件上傳成功";
?? }
?
3.4.3加上之前的路徑和類就是
@RestController
@RequestMapping("file")
publicclassCiicUpDownloadController{
privatefinalstaticStringrootPath="E:/attachment/";
?
@RequestMapping("/upload")
publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){
FilefileDir=newFile(rootPath);
if(!fileDir.exists()&&!fileDir.isDirectory()) {
fileDir.mkdirs();
? ? ?? }
try{
if(multipartFiles!=null&&multipartFiles.length>0) {
for(inti=0;i<multipartFiles.length;i++){
try{
//以原來的名稱命名,覆蓋掉舊的尸执,這里也可以使用UUID之類的方式命名家凯,這里就沒有處理了
StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();
System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()
+",保存的路徑為:"+storagePath);
// 3種方法: 第1種
// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);
// 第2種
Pathpath=Paths.get(storagePath);
Files.write(path,multipartFiles[i].getBytes());
// 第3種
// multipartFiles[i].transferTo(new File(storagePath));
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ? ? ? ? ?? }
? ? ? ? ? ? ?? }
? ? ? ? ?? }
?
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
//前端可以通過狀態(tài)碼如失,判斷文件是否上傳成功
return"文件上傳成功";
?? }
}
3.5后端定義下載方法
/**
*
* @param fileName 文件名
* @param response
* @return
*/
@RequestMapping("/download")
publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){
OutputStreamos=null;
InputStreamis=null;
try{
// 取得輸出流
os=response.getOutputStream();
// 清空輸出流
response.reset();
response.setContentType("application/x-download;charset=utf-8");
//Content-Disposition中指定的類型是文件的擴(kuò)展名绊诲,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的,點(diǎn)保存后岖常,文件以filename的值命名驯镊,
// 保存類型以Content中設(shè)置的為準(zhǔn)。注意:在設(shè)置Content-Disposition頭字段之前竭鞍,一定要設(shè)置Content-Type頭字段板惑。
//把文件名按UTF-8取出,并按ISO8859-1編碼偎快,保證彈出窗口中的文件名中文不亂碼冯乘,中文不要太多,最多支持17個中文晒夹,因為header有150個字節(jié)限制裆馒。
response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));
//讀取流
Filef=newFile(rootPath+fileName);
is=newFileInputStream(f);
if(is==null) {
System.out.println("下載附件失敗,請檢查文件“"+fileName+"”是否存在");
return"下載附件失敗丐怯,請檢查文件“"+fileName+"”是否存在";
? ? ? ? ?? }
//復(fù)制
IOUtils.copy(is,response.getOutputStream());
response.getOutputStream().flush();
}catch(IOExceptione) {
return"下載附件失敗,error:"+e.getMessage();
? ? ?? }
//文件的關(guān)閉放在finally中
finally
? ? ?? {
try{
if(is!=null) {
is.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
try{
if(os!=null) {
os.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
? ? ?? }
//其實喷好,這個返回什么都不重要
return"下載成功";
?? }
3.5.1加上之前定義的路徑類和上傳方法就是
packagecom.ciic.reporter.updownload.controller;
?
?
importorg.apache.tomcat.util.http.fileupload.IOUtils;
importorg.springframework.web.bind.annotation.*;
importorg.springframework.web.multipart.MultipartFile;
?
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.*;
importjava.nio.file.Files;
importjava.nio.file.Path;
importjava.nio.file.Paths;
?
?
@RestController
@RequestMapping("file")
publicclassCiicUpDownloadController{
privatefinalstaticStringrootPath="E:/attachment/";
?
@RequestMapping("/upload")
publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){
FilefileDir=newFile(rootPath);
if(!fileDir.exists()&&!fileDir.isDirectory()) {
fileDir.mkdirs();
? ? ?? }
try{
if(multipartFiles!=null&&multipartFiles.length>0) {
for(inti=0;i<multipartFiles.length;i++){
try{
//以原來的名稱命名,覆蓋掉舊的,這里也可以使用UUID之類的方式命名读跷,這里就沒有處理了
StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();
System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()
+"梗搅,保存的路徑為:"+storagePath);
// 3種方法: 第1種
// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);
// 第2種
Pathpath=Paths.get(storagePath);
Files.write(path,multipartFiles[i].getBytes());
// 第3種
// multipartFiles[i].transferTo(new File(storagePath));
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ? ? ? ? ?? }
? ? ? ? ? ? ?? }
? ? ? ? ?? }
?
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
//前端可以通過狀態(tài)碼,判斷文件是否上傳成功
return"文件上傳成功";
?? }
?
?
/**
*
* @param fileName 文件名
* @param response
* @return
*/
@RequestMapping("/download")
publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){
OutputStreamos=null;
InputStreamis=null;
try{
// 取得輸出流
os=response.getOutputStream();
// 清空輸出流
response.reset();
response.setContentType("application/x-download;charset=utf-8");
//Content-Disposition中指定的類型是文件的擴(kuò)展名效览,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的无切,點(diǎn)保存后,文件以filename的值命名丐枉,
// 保存類型以Content中設(shè)置的為準(zhǔn)哆键。注意:在設(shè)置Content-Disposition頭字段之前,一定要設(shè)置Content-Type頭字段瘦锹。
//把文件名按UTF-8取出籍嘹,并按ISO8859-1編碼,保證彈出窗口中的文件名中文不亂碼弯院,中文不要太多噩峦,最多支持17個中文,因為header有150個字節(jié)限制抽兆。
response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));
//讀取流
Filef=newFile(rootPath+fileName);
is=newFileInputStream(f);
if(is==null) {
System.out.println("下載附件失敗识补,請檢查文件“"+fileName+"”是否存在");
return"下載附件失敗,請檢查文件“"+fileName+"”是否存在";
? ? ? ? ?? }
//復(fù)制
IOUtils.copy(is,response.getOutputStream());
response.getOutputStream().flush();
}catch(IOExceptione) {
return"下載附件失敗,error:"+e.getMessage();
? ? ?? }
//文件的關(guān)閉放在finally中
finally
? ? ?? {
try{
if(is!=null) {
is.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
try{
if(os!=null) {
os.close();
? ? ? ? ? ? ?? }
}catch(IOExceptione) {
e.printStackTrace();
? ? ? ? ?? }
? ? ?? }
//其實辫红,這個返回什么都不重要
return"下載成功";
?? }
?
}
?