文件上传与下载
# 文件上传与下载实现
在企业级应用中,文件上传与下载是常见的需求。若依框架通过前后端分离的方式实现了文件上传与下载功能,后端基于 Spring Boot,前端基于 Vue 2 和 Element UI。本文将详细介绍如何在若依框架中实现文件的上传与下载,并涵盖常见的扩展需求和注意事项。
# 一、创建上传文件表
首先,需要在数据库中创建一张用于存储文件信息的表,以便在文件上传后记录文件的路径和其他相关信息。
DROP TABLE IF EXISTS sys_file_info;
CREATE TABLE sys_file_info (
file_id INT(11) NOT NULL AUTO_INCREMENT COMMENT '文件ID',
file_name VARCHAR(50) DEFAULT '' COMMENT '文件名称',
file_path VARCHAR(255) DEFAULT '' COMMENT '文件路径',
PRIMARY KEY (file_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT = '文件信息表';
2
3
4
5
6
7
# 二、上传文件实现流程
# 1. 前端上传文件控件与表单提交
在前端页面中,通过 Element UI 提供的 <el-upload>
组件实现文件选择,并通过绑定事件将文件与其他参数一同提交到后端。
<template>
<div>
<!-- 文件上传组件 -->
<el-upload
ref="upload"
action="/api/system/file/upload" // 后端文件上传接口
:headers="uploadHeaders" // 请求头,包含认证信息
:on-success="handleSuccess" // 上传成功处理
:on-error="handleError" // 上传失败处理
:file-list="fileList" // 上传的文件列表
:limit="3" // 文件上传数量限制
multiple // 是否支持多选文件
:auto-upload="false"> // 是否自动上传
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传</el-button>
</el-upload>
</div>
</template>
<script>
export default {
data() {
return {
fileList: [], // 存储上传的文件列表
uploadHeaders: {
Authorization: "Bearer " + this.getToken() // 设置请求头,包含认证信息
}
};
},
methods: {
// 获取认证Token
getToken() {
return localStorage.getItem("token"); // 示例,实际根据项目情况获取token
},
// 手动提交文件上传
submitUpload() {
this.$refs.upload.submit();
},
// 文件上传成功处理
handleSuccess(response, file, fileList) {
this.$message.success("文件上传成功");
this.fileList = fileList;
},
// 文件上传失败处理
handleError(err, file, fileList) {
this.$message.error("文件上传失败");
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
说明:
action
: 设置为后端处理文件上传的接口地址。uploadHeaders
: 设置请求头,通常包含认证信息,如Authorization
。:auto-upload="false"
: 设置为false
时需要手动调用submitUpload
方法来上传文件。
# 2. 后端控制器添加上传方法
在后端控制器中,编写文件上传的处理逻辑。使用 MultipartFile
接收前端上传的文件,并将文件保存到指定路径,同时记录文件信息到数据库。
@PostMapping("/upload")
@ResponseBody
public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) throws IOException
{
// 获取文件上传路径
String filePath = RuoYiConfig.getUploadPath();
// 上传文件并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
// 保存文件信息到数据库
SysFileInfo fileInfo = new SysFileInfo();
fileInfo.setFileName(file.getOriginalFilename());
fileInfo.setFilePath(fileName);
sysFileInfoService.insertSysFileInfo(fileInfo);
// 返回上传成功结果
return AjaxResult.success(fileName);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
关键点:
RuoYiConfig.getUploadPath()
:获取文件上传的目录路径。FileUploadUtils.upload(filePath, file)
:处理文件上传,并返回上传后的文件名称。sysFileInfoService.insertSysFileInfo(fileInfo)
:将文件信息保存到数据库中。
# 3. 文件预览功能
上传文件成功后,如果需要在前端预览文件,可以对该属性进行格式化处理。例如,展示图片或文件的缩略图。
<el-table-column
prop="filePath"
label="文件预览"
width="120">
<template slot-scope="scope">
<img :src="scope.row.filePath" class="preview-image" />
</template>
</el-table-column>
2
3
4
5
6
7
8
# 4. 文件上传限制
为了防止用户上传过大的文件,可以在后端的 application.yml
中配置文件上传的大小限制。
# 文件上传限制配置
spring:
servlet:
multipart:
max-file-size: 10MB # 单个文件最大为10MB
max-request-size: 20MB # 总上传文件最大为20MB
2
3
4
5
6
# 三、文件下载实现流程
# 1. 前端文件下载代码
在前端页面中,通过 Vue 和 JavaScript 实现文件下载功能。使用 window.location.href
来触发浏览器的下载操作。
<template>
<el-button @click="downloadFile(scope.row.filePath)">下载</el-button>
</template>
<script>
export default {
methods: {
downloadFile(filePath) {
// 触发文件下载
window.location.href = `/api/system/file/download?filePath=${filePath}`;
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2. 后端下载方法
在后端控制器中,编写文件下载的处理逻辑。通过读取文件路径,将文件流输出到客户端,实现文件下载。
@GetMapping("/download")
public void downloadFile(@RequestParam String filePath, HttpServletResponse response) throws IOException
{
// 获取本地资源路径
String localPath = RuoYiConfig.getProfile() + filePath;
// 获取文件名
String downloadName = StringUtils.substringAfterLast(filePath, "/");
// 设置响应头信息,指示浏览器下载文件
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadName, "UTF-8"));
// 输出文件字节流
FileUtils.writeBytes(localPath, response.getOutputStream());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
关键点:
RuoYiConfig.getProfile()
:获取配置的文件存储根目录。FileUtils.writeBytes(localPath, response.getOutputStream())
:将文件字节流写入响应输出流,返回给客户端。
# 四、注意事项与扩展功能
# 1. 文件格式控制
如果需要对上传的文件格式进行控制,可以在前端限制文件选择框的 accept
属性,例如限制为 image/*
,后端可以在上传方法中对文件后缀名进行验证。
# 2. 文件命名策略
在文件上传时,可以采用随机命名或根据业务需求进行命名,以避免文件名冲突。同时,可以保留原始文件名并将其存储在数据库中,以便用户查看或下载时显示正确的文件名。
# 3. 文件预览与缩略图
在前端显示文件时,可以通过预览功能展示图片的缩略图,对于其他类型的文件,可以显示图标或下载按钮。同时,可以在后端生成文件的缩略图,并提供缩略图的下载功能。
# 4. 文件删除与回收站
在实现文件上传与下载的同时,可以扩展实现文件删除功能。为了防止误删除,可以设计一个“回收站”功能,将文件标记为已删除但不立即从磁盘中删除。用户可以在一定时间内恢复文件,超出时间后再进行彻底删除。
# 5. 文件的权限控制
为了保护敏感文件,可以在文件下载方法中添加权限验证,确保只有具有相应权限的用户才能下载文件。例如,可以根据用户角色或业务逻辑判断是否允许下载文件。
# 6. 文件上传进度显示
为了提升用户体验,可以在文件上传过程中显示上传进度。前端可以通过 el-upload
的 on-progress
事件获取当前上传进度,后端也可以返回当前上传进度,前端根据进度信息进行展示。