一、文件上传
- 后端核心代码(其实文件上传网上有很多资源,而且一般不会存到项目本地,而是存到一些专门的文件存储,如腾讯云对象存储COS,或者hdfs等,所以这里只简单记录后端的一些代码)
public static void upload(MultipartFile file) {
HttpServletRequest request = getRequest();
if (ObjectUtils.isEmpty(request)) {
return null;
}
// 上传文件所存放的位置(根据需求修改)
String rootPath = request.getSession().getServletContext().getRealPath("WEB-INF/upload");
try {
String originalFileName = file.getOriginalFilename();
String newFileName = UUID.randomUUID().toString() + originalFileName.substring(originalFileName.lastIndexOf("."));
// 创建年月文件夹
Calendar date = Calendar.getInstance();
File dateDirs = new File(date.get(Calendar.YEAR) + File.separator + (date.get(Calendar.MONTH) + 1));
// 新文件
File newFile = new File(rootPath + File.separator + dateDirs + File.separator + newFileName);
// 判断目标文件所在目录是否存在
if (!newFile.getParentFile().exists()) {
// 如果目标文件所在的目录不存在,则创建父目录
newFile.getParentFile().mkdirs();
}
// 将内存中的数据写入磁盘
file.transferTo(newFile);
String path = date.get(Calendar.YEAR) + "/" + (date.get(Calendar.MONTH) + 1) + "/" + newFileName;
} catch (Exception e) {
e.printStackTrace();
}
}
二、文件下载
- 后端核心代码(无需确定文件的具体后缀格式,以流的形式写入response里)
public static Object download(Document document, HttpServletResponse response) {
HttpServletRequest request = getRequest();
// 获得文件路径
String downLoadPath = request.getSession().getServletContext().getRealPath("WEB-INF/upload") + "/" + document.getPath();
String fileName = document.getFileName();
OutputStream os = null;
InputStream is = null;
try {
// 取得输出流
os = response.getOutputStream();
// 清空输出流
response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 获取文件,并读取流
File f = new File(downLoadPath);
is = new FileInputStream(f);
if (ObjectUtils.isEmpty(is)) {
return null;
}
//复制
IOUtils.copy(is, response.getOutputStream());
response.getOutputStream().flush();
} catch (Exception e) {
e.printStackTrace();
}
//文件的关闭放在finally中
finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
- 前端核心代码
// 封装的axios里发送请求时请求头必须添加responseType为'blob'(只在下载时才需要)
{
url: url,
method: 'post',
data: postData,
responseType: 'blob'
}
// 下载文件核心代码(事件操作)
async downloadFile(val) {
// 封装的axios请求
await commonAPI("downloadDocument", {id: val.row.id}, 'file')
.then(res => {
if (res.data && !res.data.size) {
return this.$message.error(res.data.info.message);
}
// 从response的headers中获取filename
const contentDisposition = res.headers['content-disposition'];
let filename = window.decodeURI(contentDisposition.substring(contentDisposition.indexOf('=') + 1));
// 获得blob对象
let blob = new Blob([res.data], {type: 'application/octet-stream;charset=utf-8'});
let objectUrl = URL.createObjectURL(blob);
// 创建a标签,模拟点击a标签下载
let a = document.createElement('a')
a.href = objectUrl;
const reg = /^["](.*)["]$/g;
a.download = decodeURI(filename.replace(reg, "$1"));
a.click();
// 释放掉blob对象
window.URL.revokeObjectURL(objectUrl);
})
.catch(error => {
this.$message.error("文件下载失败");
})
},
版权声明:本文为hmq1350167649原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。