在公司用到了文件的上传和下载,自己也是花费了巨多的时间才学会了,于是就在这里记录整理一下。
文件上传
首先前端Vue先摆上
<el-col :span="6" style="width: 350px;">
<el-form-item label="上传文件" >
<el-upload :auto-upload="false" class="upload-demo" drag :show-file-list="true" :file-list="fileList"
:limit="5" prop="feedfile"
:on-exceed="handleExceed"
:on-change="handleChange" action="customize">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">
<span style="font-weight: bold">{{fileListName}}</span>
</div>
</el-upload>
</el-form-item>
</el-col>
在这里介绍一下使用的el-upload
的组件,来自于element-ui的上传组件https://element.eleme.cn/2.11/#/zh-CN/component/upload
来自于官网的组件。
然后稍微介绍一下组件分别属性。
:show-file-list="true"
在这里属性就是说的显示你上传的文件的列表。
:file-list="fileList"
这里就是显示的集合fileList
:limit="5"
在这里的就是实现了一个显示文件的数量
prop="feedfile"
这个就是在你上传文件的时候进行一个文件的验证,判断你的上传文件的验证,看看你是不是空的,在表单提交的时候,没有提交的是会被写定好的rule
feedfile: [{
required: true,
message: '文件上传不能为空',
trigger: 'blur'
}],
:on-exceed="handleExceed"
这个就是进行一个判断,如果你上传的文件的数量在一定的范围之外的情况就会触动这个方法,这个方法就在下面。
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
:on-change="handleChange"
这个就是实现一个文件上传的时候,上传一个触动一次
handleChange(file, fileList) {
this.time=this.time+1;
for(var i=0;i<fileList.length;i++){
this.fileLists.push(fileList[i].raw);
}
在这里还是需要记住一个东西,fileList[i].raw
这个才是真的文件,raw就是文件里面的内容。
async dataFormSubmit(num) {
let valid = await this.$refs.dataForm.validate().catch(() => {
return util.$message.showInfo2('校验错误')
})
if (!valid) return
this.param.append('defectId', this.dataForm.id);
this.param.append('feedbackPersonId', this.dataForm.feedbackPersonId);
this.param.append('feedbackDate', this.dataForm.feedbackDate);
this.param.append('feedbackContent', this.dataForm.feedbackContent);
this.param.append('time', this.time);
for(var i=0;i<this.fileLists.length;i++){
this.param.append('file', this.fileLists[i]);
}
await api.upload(this.param).catch((err) => {
})
this.dialogFormVisible = false;
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$emit("refreshDataList", false);
})
},
这是一个表单提交的方法
let valid = await this.$refs.dataForm.validate().catch(() => {
return util.$message.showInfo2('校验错误')
})
if (!valid) return
首先这是一个进行表单验证的方法,这就是验证你的表单是否是存在数据,可以自己写定好的规则进行判断。
然后是就是把我们要使用的放进一个param 里面在这类param的定义是param: new FormData(),
后面await api.upload(this.param).catch((err) => {})
是用我们的组件完成表单提交的操作,首先引入组件 import * as api from './api'
然后再api.js这个文件里面我们存放表单提交的代码,
export function upload(data) {
return request({
url: '/pc/modeldefecrectificationfeedback/save',
method: 'post',
data
})
}
这就是和后端进行交互的代码,后端的接受我后面放上来
@PostMapping("save")
@ApiOperation("保存")
public Result save(ModelDefecRectificationFeedbackEntity dto, @RequestParam("file")MultipartFile[] files,@RequestParam("time")Integer times){
//效验数据
这是后端的代码实现的头,具体的问题也就是后端对于文件实现的功能,然后的问题不在我们这一次讨论的范围之内我们在稍后的文章里面会提到。
文件下载
首先我们在这里需要去描述一下需求,需求的话就是实现一个文件的下载,其次我们需要实现的效果就是能够显示文件列表,因为上传的时候是多个文件,于是我们下载的时候就是应该是将这个信息所有上传的文件全部显示出来,然后提供逐一的下载功能。
<el-row>
<el-form-item label="下载附件" >
<div v-for="p in fileName" >
<el-input :value="p.fileName" readonly="" />
<el-button size="mini" @click="submit(p.fileId)">下载</el-button>
</div>
</el-form-item>
<el-row>
我介绍一下这段代码的具体详情,v-for="p in fileName"
首先是从后端拿到信息的时候将文件存好传到前台,按照文件的数量将div进行v-for循环,有多少个文件就有多少个div,
@PostMapping("listByinfo")
@ApiOperation("列表")
public Result<IPage<Map>> listByinfo(@RequestBody Map<String, Object> params){
IPage<Map> listByParam = modelDefecRectificationFeedbackService.getListByParam(params);
List<Map> records = listByParam.getRecords();
Map map = records.get(0);
String codeDescription = codeService.getCodeDescription("RW", map.get("taskType").toString());
map.put("taskType",codeDescription);
String feedBackId = (String)map.get("id");
List list = modelDefecRectificationFeedbackFileService.list(new HashMap<>());
List<BasicFileOssEntity> fileName=new ArrayList<>();
/**
* 在文件表前端存储的都是缺陷整改的id而不是反馈的id
*/
for (int i = 0; i < list.size(); i++) {
ModelDefecRectificationFeedbackFileEntity modelDefecRectificationFeedbackFileEntity = (ModelDefecRectificationFeedbackFileEntity)list.get(i);
if(feedBackId.equals(modelDefecRectificationFeedbackFileEntity.getFeedbacktId())){
BasicFileOssEntity info = commonFileService.info(modelDefecRectificationFeedbackFileEntity.getFeedbackFileId());
fileName.add(info);
}
}
map.put("fileName",fileName);
listByParam.setRecords(records);
return new Result<IPage<Map>>().ok(listByParam);
}
这里的List就是一个自己书写的存储文件的类,里面有文件的名字,文件的一切信息,于是哦我们在前段进行调用就可以了,然后在显示的时候将文件名称放进input里面,设置为只读,然后进行下载的时候我们将需要下载的文件的文件id传到后端,进行删除的操作
submit(id){
api.download(id);
},
这里还是代用api里面写好的代码进行直接的调用,
export function download(id) {
let params = qs.stringify({
'token': util.cookies.get('token'),
'id': id,
})
let url = '/pc/modeldefecrectificationfeedbackfile/download'
window.location.href = `${window.SITE_CONFIG['apiURL']}${url}?${params}`
}
在这里就是需要注意下实现传后端的接口,因为我们这里是公司已经写好了的框架于是有一些形式可能和你们自己写不一样,window.location.href
然后就是使用window来实现一个新页面来完成下载
@RequestMapping({"/download"})
public void downFile2(@RequestParam("id") String id, HttpServletResponse response) {
commonFileService.downloadFile(response, id);
}
是用我们写好的接口,当然如果你要下载很多个文件的方法有很多,我之前的实现是通过点击一次下载下载多个文件,这样的实现就是通过多次循环,首先需要去拿到多少个文件,然后再传后台的时候前端传一个循环次数进去,就可以实现穿一次实现多个文件的下载,其实还有就是一个我只是有想法但是我没有实现,就是说在上传的时候直接打包达成一个压缩包的形式进行存储,或者是在下载的时候将所有的文件打包成一个压缩包的形式也是可以的。