文件上传效果展示:
文件上传效果预览
文件上传删除
Vue 前端核心代码
<el-form-item label="文件上传" >
<el-upload drag multiple
name="multipartfiles"
ref="upload"
:limit=1
:action="imageAction"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:beforeUpload="beforeAVatarUpload"
:on-exceed = "onExceed"
:onError="uploadError"
:onSuccess="uploadSuccess"
:auto-upload="true">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将图片拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传'jpg/png/jpeg/gif'</div>
</el-upload>
</el-form-item>
export default{
name: 'new_house',
data () {
return {
imageAction:'http://192.168.1.74:8014/minio/api/upload/file/up',
fileList: [],
}
},
methods: {
handleRemove (file, fileList) {
if (file.status === 'success') {
var params = {'filePath': file.response.datas.filePath}
this.$axios({
url: "/api/upload/file/del",
method: 'post',
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
},
data: params
}).then(res => {
this.$message.success('删除图片成功!')
this.fileList = []
this.uploadFile.fileName = ''
this.uploadFile.filePath = ''
this.uploadFile.fileType =''
this.uploadFile.fileSize = ''
}).catch(function (error) {
console.log(error)
})
}
},
handlePreview (file) {
if (file.status === 'success') {
window.open(file.response.datas.fileUrl)
}
},
onExceed (files, fileList) {
this.$message.error('提示:只能上传一张图片!')
},
// 图片上传
beforeAVatarUpload (file) {
if (file.type !== 'image/jpg' && file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
this.$message.error('只支持jpg、png、gif格式的图片!')
return false
}
},
uploadSuccess (response, file, fileList) {
if(response.code === '200'){
this.uploadFile.fileName = response.datas.fileName
this.uploadFile.filePath = response.datas.filePath
this.uploadFile.fileType = response.datas.fileType
this.uploadFile.fileSize = response.datas.fileSize
console.log('上传图片成功')
} else {
console.log('上传图片失败')
}
},
uploadError (response, file, fileList) {
this.$message.error('上传图片失败!')
}
}
SpringBoot 核心代码:
package com.zzg.controller;
import java.io.FileNotFoundException;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzg.common.AbstractController;
import com.zzg.common.PageParame;
import com.zzg.common.Result;
import com.zzg.entity.UploadFile;
import com.zzg.minio.entity.MinioUploadEntity;
import com.zzg.minio.util.MinioUploadUtil;
import com.zzg.service.UploadFileService;
import io.minio.GetObjectResponse;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.ServerException;
import io.minio.errors.XmlParserException;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import kotlin.Pair;
import okhttp3.Headers;
/**
* 文件上传controller
*
* @author zzg
*
*/
@RestController
@RequestMapping("/api/upload/file")
public class UploadFileController extends AbstractController {
@Autowired
private UploadFileService uploadFileService;
/**
* 上传文件删除
*
* @param file
*/
@ApiOperation(httpMethod = "POST", value = "上传文件删除")
@RequestMapping(value = "/del", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public Result fileDelete(@RequestBody Map<String, Object> parame) {
String filePath = String.valueOf(parame.get("filePath"));
MinioUploadEntity entity = new MinioUploadEntity("http://192.168.1.74:9000", "minioadmin", "minioadmin");
MinioUploadUtil util = new MinioUploadUtil(entity);
util.removeFile(filePath, "gxpt-img");
return Result.ok();
}
/**
* 单文件上传
*
* @param file
*/
@RequestMapping(value = "/up", method = RequestMethod.POST)
public Result fileUpload(@RequestParam("multipartfiles") MultipartFile file) {
Map<String, Object> rs = new HashMap<String, Object>();
// 获取文件名称
String fileName = file.getOriginalFilename();
// 文件大小
long fileSize = file.getSize();
// 文件类型
String fileType = file.getContentType();
// 文件标识
String filePath = "";
// 文件预览地址
String fileUrl = "";
MinioUploadEntity entity = new MinioUploadEntity("http://192.168.1.74:9000", "minioadmin", "minioadmin");
MinioUploadUtil util = new MinioUploadUtil(entity);
// 获取文件后缀类型
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
InputStream stream;
try {
stream = file.getInputStream();
if (stream != null) {
filePath = util.uploadFile(stream, "gxpt-img", "image/jpg", suffix);
if (StringUtils.isNotBlank(filePath)) {
System.out.println("文件上传成功:" + filePath);
if (stream != null) {
stream.close();
}
// 生成文件预览地址
try {
fileUrl = util.getPreviewAddress(filePath, "gxpt-img");
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (ErrorResponseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (InsufficientDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (InternalException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (InvalidResponseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (XmlParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (ServerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
}
} else {
System.out.println("文件上传失败:" + filePath);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Result.error("文件上传失败");
}
rs.put("fileName", fileName);
rs.put("fileType", fileType);
rs.put("filePath", filePath);
rs.put("fileSize", fileSize);
rs.put("fileUrl", fileUrl);
return Result.ok().setData(rs);
}
}
Vue 电子文件页面全部前端代码:
<style>
</style>
<template>
<div id="new_house">
<el-col :span="24">
<el-form :inline="true" :model="queryParams" ref="queryParams">
<el-form-item label="文件名称">
<el-input v-model="queryParams.fileName" placeholder="类名"></el-input>
</el-form-item>
<el-form-item label="文件类型">
<el-input v-model="queryParams.fileType" placeholder="方法名称"></el-input>
</el-form-item>
<el-form-item label="上传时间">
<el-date-picker
v-model="queryParams.rangTime"
type="daterange"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-form>
</el-col>
<el-col>
<!--自定义searchHandler函数-->
<el-button type="primary" @click="searchHandler">查询</el-button>
<!---->
<el-button type="primary" @click="reset">重置</el-button>
<!---->
<el-button type="primary" @click="dialogFormAdd = true">新增</el-button>
</el-col>
<!--
<p style="text-align: left; margin-bottom: 10px;">
<el-button type="primary" @click="dialogFormAdd = true">添加</el-button>
</p>-->
<el-col>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
v-for="(data,index) in tableHeader"
:key="index"
:prop="data.prop"
:label="data.label"
:min-width="data['min-width']"
:align="data.align">
</el-table-column>
<el-table-column
label="操作"
min-width="240">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="toEdit(scope)">修改</el-button>
<el-button type="danger" size="mini" @click="deleteMember(scope)">删除</el-button>
<el-button type="success" size="mini" @click="downloadRest(scope)">下载</el-button>
</template>
</el-table-column>
</el-table>
<br>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.pageIndex"
:page-sizes="[5, 10, 20, 30, 40]"
:page-size=pagination.pageSize
layout="total, sizes, prev, pager, next, jumper"
:total=pagination.total>
</el-pagination>
</el-col>
<el-dialog title="添加电子文件" :visible.sync="dialogFormAdd">
<el-form :model="uploadFile">
<el-form-item label="文件名称" >
<el-input v-model="uploadFile.fileName" auto-complete="off" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="文件类型" >
<el-input v-model="uploadFile.fileType" auto-complete="off" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="文件大小" >
<el-input v-model="uploadFile.fileSize" auto-complete="off" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="文件描述" >
<el-input v-model="uploadFile.fileDesc" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="文件上传" >
<el-upload drag multiple
name="multipartfiles"
ref="upload"
:limit=1
:action="imageAction"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:beforeUpload="beforeAVatarUpload"
:on-exceed = "onExceed"
:onError="uploadError"
:onSuccess="uploadSuccess"
:auto-upload="true">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将图片拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传'jpg/png/jpeg/gif'</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormAdd = false">取 消</el-button>
<el-button type="primary" @click="add(uploadFile)">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="修改电子文件" :visible.sync="dialogFormEdit">
<el-form :model="uploadFile">
<el-form-item label="文件名称" >
<el-input v-model="uploadFile.fileName" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="文件描述" >
<el-input v-model="uploadFile.fileDesc" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="图片预览" >
<el-image :src="this.uploadFile.fileUrl"></el-image>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormEdit = false">取 消</el-button>
<el-button type="primary" @click="edit(uploadFile)">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default{
name: 'new_house',
data () {
return {
imageAction:'http://192.168.1.74:8014/minio/api/upload/file/up',
fileList: [],
tableData: [],
dialogFormEdit: false,
dialogFormAdd:false,
uploadFile: {
sid: '',
fileName: '',
filePath: '',
fileType: '',
fileSize: '',
fileDesc: '',
fileUrl:'',
createdBy:'',
createdDt:''
},
queryParams:{
fileName:'',
filePath:'',
fileType:'',
rangTime: [],
startDt: '',
endDt: ''
},
pagination: {
pageIndex: 1,
pageSize: 10,
total: 0,
},
tableHeader: [
{
prop: 'id',
label: '文件编号',
align: 'left'
},
{
prop: 'fileName',
label: '文件名称',
align: 'left'
},
{
prop: 'filePath',
label: '文件路径',
align: 'left'
},
{
prop: 'fileType',
label: '文件类型',
align: 'left'
},
{
prop: 'fileSize',
label: '文件大小',
align: 'left'
},
{
prop: 'fileDesc',
label: '文件描述',
align: 'left'
},
{
prop: 'createdBy',
label: '上传人',
align: 'left'
},
{
prop: 'createdDt',
label: '上传时间',
align: 'left'
}
]
}
},
methods: {
handleRemove (file, fileList) {
if (file.status === 'success') {
var params = {'filePath': file.response.datas.filePath}
this.$axios({
url: "/api/upload/file/del",
method: 'post',
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
},
data: params
}).then(res => {
this.$message.success('删除图片成功!')
this.fileList = []
this.uploadFile.fileName = ''
this.uploadFile.filePath = ''
this.uploadFile.fileType =''
this.uploadFile.fileSize = ''
}).catch(function (error) {
console.log(error)
})
}
},
handlePreview (file) {
if (file.status === 'success') {
window.open(file.response.datas.fileUrl)
}
},
onExceed (files, fileList) {
this.$message.error('提示:只能上传一张图片!')
},
// 图片上传
beforeAVatarUpload (file) {
if (file.type !== 'image/jpg' && file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
this.$message.error('只支持jpg、png、gif格式的图片!')
return false
}
},
uploadSuccess (response, file, fileList) {
if(response.code === '200'){
this.uploadFile.fileName = response.datas.fileName
this.uploadFile.filePath = response.datas.filePath
this.uploadFile.fileType = response.datas.fileType
this.uploadFile.fileSize = response.datas.fileSize
console.log('上传图片成功')
} else {
console.log('上传图片失败')
}
},
uploadError (response, file, fileList) {
this.$message.error('上传图片失败!')
},
init () {
var self = this
this.$axios({
method:'post',
url:'/api/upload/file/getPage',
data:{"page":this.pagination.pageIndex,"limit":this.pagination.pageSize},
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
console.log(res);
self.pagination.total = res.data.datas.data.total;
self.tableData = res.data.datas.data.records;
})
.catch(function (error) {
console.log(error)
})
},
handleSizeChange(val) {
this.pagination.pageSize = val;
this.pagination.pageIndex = 1;
this.init();
},
handleCurrentChange(val) {
this.pagination.pageIndex = val;
this.init();
},
add (uploadFile) {
console.log("添加事件被触发")
this.$axios({
method:'post',
url:'/api/upload/file/insert',
data:JSON.stringify(uploadFile),
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
this.$message.success('添加成功')
this.dialogFormAdd = false
this.init()
})
.catch(function (error) {
console.log(error)
})
},
toEdit (scope) {
this.uploadFile.sid = scope.row.id
this.uploadFile.fileName = scope.row.fileName
this.uploadFile.fileDesc = scope.row.fileDesc
// 请求文件预览地址
this.$axios({
method:'post',
url:'/api/upload/file/preview',
data:{"filePath":scope.row.filePath},
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
this.uploadFile.fileUrl = res.data.datas.fileUrl
})
.catch(function (error) {
console.log(error)
})
this.dialogFormEdit = true
},
edit () {
var params ={
'id' : this.uploadFile.sid,
'fileName' : this.uploadFile.fileName,
'fileDesc' : this.uploadFile.fileDesc
}
this.$axios({
method:'post',
url:'/api/upload/file/update',
data:params,
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
this.$message.success('修改成功')
this.dialogFormEdit = false
this.init()
}).catch(function (error) {
console.log(error)
})
},
deleteMember (scope) {
if (!scope.row.id) {
this.tableData.splice(scope.$index, 1)
} else {
this.$confirm('确认是否删除', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
})
.then(() => {
console.log(scope.row.id)
var params ={
'id' : scope.row.id
}
this.$axios({
method:'post',
url:'/api/upload/file/delete',
data:params,
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
this.$message.success('修改成功')
this.init()
}).catch(function (error) {
console.log(error)
})
})
}
},
searchHandler() {
var self = this
if(this.queryParams.rangTime.length > 0){
this.queryParams.startDt = this.queryParams.rangTime[0]
this.queryParams.endDt = this.queryParams.rangTime[1]
}
this.$axios({
method:'post',
url:'/api/upload/file/getPage',
data:JSON.stringify(this.queryParams),
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
console.log(res);
self.pagination.total = res.data.datas.data.total;
self.tableData = res.data.datas.data.records;
})
.catch(function (error) {
console.log(error)
})
},
reset(){
// 重新设置请求参数实体属性
this.queryParams = {
fileName:'',
filePath:'',
fileType:'',
rangTime:[],
startDt: '',
endDt: ''
};
//表单验证还原
if (this.$refs['queryParams'] !== undefined) {
this.$refs['queryParams'].resetFields();
}else{
this.$nextTick(()=>{
this.$refs['queryParams'].resetFields();
});
}
},
downloadRest(scope){
this.$axios({
method:'post',
url:'/api/upload/file/preview',
data:{"filePath":scope.row.filePath},
headers:{
'Content-Type':'application/json;charset=utf-8' //改这里就好了
}
}).then(res => {
// 文件下载方式二
//window.open(res.data.datas.fileUrl)
// 文件下载方式一
window.location.href =res.data.datas.fileUrl
})
.catch(function (error) {
console.log(error)
})
},
download(scope){
// 通过blob 下载文件方法暂时未调试成功
this.$axios.get('/api/upload/file/fileDownload?filePath=' +scope.row.filePath).then(function(response){
if (!response.data) {
this.$Message.error('下载内容为空')
return
}
const disposition = response.headers['content-disposition'];
let fileName = disposition.substring(disposition.indexOf('filename=') + 9, disposition.length);
let url = window.URL.createObjectURL(new Blob([response.data]), {
type: "image/jpeg"
})
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
//释放URL对象所占资源
window.URL.revokeObjectURL(url)
//用完即删
document.body.removeChild(link)
}).catch(function (response){
console.log(response);//发生错误时执行的代码
});
}
},
mounted: function () {
this.init()
}
}
</script>