文件上传
前端
页面上传组件
<el-upload class="upload-demo" :action="excelAction" :data="uploadPostData" :on-preview="handlePreview"
:on-remove="handleRemove" :before-remove="beforeRemove" :on-success="handleSuccess" :headers="uploadHeaders"
multiple :limit="1" :on-exceed="handleExceed" :file-list="fileList" style="margin-top: 10px;width: 100%;">
<div style="display: flex;">
<div class="fileNameClass"><el-tag>所导入文件</el-tag> {{ fileName }}</div>
<el-button size="small" type="primary" style="margin-left: 10px;height: 43px;">文件上传</el-button>
</div>
<div slot="tip" class="el-upload__tip" style="color: red;">
只能上传xlxs、xls文件,且不超过50MB
</div>
</el-upload>
数据声明
passengerFlowImportDialogVisible: false,
//文件上传地址(后端接受文件的地址)
excelAction: BASE_URL + "/shift-scheduling-calculate-service/schedulingTask/uploadExcelFile",
//所导入的文件名
fileName: "",
//文件列表
fileList: [],
//导入文件的同时向后台提交数据
uploadPostData: {},
//上传文件的请求头
uploadHeaders: {
token: "",
},
注意,如果项目后端做了权限校验,一定要给请求头的token赋值
文件上传相关方法
handleSuccess(res) {
this.fileName = res.fileName;
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(
`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length
} 个文件`
);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}?`);
},
//清除已经上传的文件
clearFileList() {
this.fileList = [];
},
//退出对话框
exitExcelImport() {
this.passengerFlowImportDialogVisible = false;
this.clearFileList()
}
样式
.fileNameClass {
margin-bottom: 30px;
border: 1px solid #235ada;
padding: 5px;
border-radius: 5px;
width: 400px;
text-align: left;
}
后端
/**
* 导入excel文件并完成解析
*
* @param multipartFile
* @param paramMap
* @return
* @throws Exception
*/
@PostMapping("/uploadExcelFile")
public R uploadExcelFile(@RequestParam(value = "file", required = true) MultipartFile multipartFile, @RequestParam(required = false) Map paramMap) throws Exception {
if (multipartFile.isEmpty() || multipartFile.getSize() > 52428800) {
R.error(ResultCodeEnum.FAIL.getCode(), "上传文件不能为空,且不能大于50MB");
}
String originalFilename = multipartFile.getOriginalFilename();
if (!(originalFilename.endsWith(".xlsx") || originalFilename.endsWith(".xls"))) {
return R.error(ResultCodeEnum.FAIL.getCode(), "只能导入xlsx、xls文件");
}
InputStream inputStream = multipartFile.getInputStream();
Workbook workbook;
if (originalFilename.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(inputStream);
} else {
workbook = new HSSFWorkbook(inputStream);
}
return R.ok().addData("fileName", originalFilename);
}
效果演示
文件下载
后端
@RequestMapping("/downloadUnCompressFile/{fileMessageId}")
public void downloadUnCompressFile(@PathVariable Long fileMessageId, HttpServletResponse response, @RequestHeader("User-Agent") String userAgent) {
try {
/// 将文件进行解压,获取解压之后的字节
FileMessage fileMessage = fileMessageService.getOne(new QueryWrapper<FileMessage>().eq("id", fileMessageId));
// 获取文件要解压到的路径
String targetFilePath = fileMessage.getTargetFilePath().substring(0, fileMessage.getTargetFilePath().lastIndexOf(".")) + fileMessage.getFileSuffix();
File file = new File(fileMessage.getTargetFilePath());
if (!file.exists()) {
throw new ClientException("压缩包丢失,解压失败");
}
// 将文件解压到相应的路径
GzipCompressUtil.unCompressFile(file, targetFilePath);
String fileName;
if (userAgent.indexOf("MSIE") > 0) {
// --if-- IE浏览器
fileName = new String(fileMessage.getFileName().getBytes("UTF-8"), "ISO-8859-1");
} else {
// --if-- 其他浏览器
fileName = URLEncoder.encode(fileMessage.getFileName(), "UTF-8");
}
// 设置字符编码
response.setCharacterEncoding("UTF-8");
response.setContentType("multipart/form-data");
// 设置响应头,控制浏览器下载该文件,设置文件名供下载之后解析
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
// 告知浏览器文件的大小
response.addHeader("Content-Length", "" + file.length());
// 设置文件ContentType的类型,这样设置,会自动判断下载文件类型
response.setContentType("application/octet-stream");
// 读取文件--输入流
InputStream input = new FileInputStream(file);
// 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff = new byte[1024];
int index;
// 执行写出操作
while ((index = input.read(buff)) != -1) {
out.write(buff, 0, index);
out.flush();
}
// 关闭流
out.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
前端方法
直接使用和其他请求一样的调用方法会出现问题,前端只会收到流数据,不会下载文件。因此需要使用如下方法来发起 下载请求
/**
* 下载解压后的文件
*/
downloadUnCompressFile(fileMessage) {
let a = document.createElement("a");
a.setAttribute("download", "");
a.setAttribute("target", "_blank");
a.setAttribute(
"href",
`${BASE_URL}/compress/downloadUnCompressFile/${fileMessage.id}`
);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},