本文记录下前后端分离项目中实现文件的打包下载功能
后端文件下载接口
@PostMapping("/downloadResource")
public void downloadResource(@RequestBody ResourceTree resourceTree, HttpServletResponse response) throws IOException{
// sourceFolderPath为要打包下载的文件夹地址
String sourceFolderPath = "E:/importDir/test";
response.setContentType("application/zip");
String fileName ="打包测试.zip";
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName,"UTF-8"));
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(response.getOutputStream());
fileUtils.addFolderToZip("", sourceFolderPath, zos);
zos.close();
// response.setContentType("application/zip");
response.flushBuffer();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
文件打包方法
public static void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws IOException {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(path, srcFile, zip);
} else {
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
}
}
public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws IOException {
File folder = new File(srcFolder);
for (String fileName : folder.list()) {
if (path.equals("")) {
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
} else {
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
}
}
}
前端下载按钮
<el-table-column align = "center" label="操作">
<template slot-scope="scope">
<el-button size="medium"
type = "text"
@click="downloadBtn(scope.row)">资源下载
<i class="el-icon-download el-icon--right"></i>
</el-button>
</template>
</el-table-column>
前端下载方法
downloadBtn(param){
this.dialogForm.revision = param.revision
downloadResourceAPI(this.dialogForm).then(function(res){
console.log(res)
let blob = new Blob([res.data],{
type: "application/zip"})
let contentDisposition = res.headers['content-disposition'];
// 运用window.decodeURI来解码,解决中文乱码问题
let fileName = window.decodeURI(contentDisposition.substring(contentDisposition.indexOf('=')+1)) //获取文件名称
//创建一个a标签用 link 来接收
let link = document.createElement('a')
// link.style.display = 'none'
//通过 window.URL.createObjectURL 将 blob二进制资源 转为 url地址并赋给link.href
link.href = window.URL.createObjectURL(blob)
//给 a 标签添加 download 属性
link.setAttribute('download', fileName)
// document.body.appendChild(link)
link.click()
//释放内存
window.URL.revokeObjectURL(link.href)
}.bind(this))
}
其中downloadResourceAPI
是封装好的axios请求,请求后端下载接口方式如下
export const downloadResourceAPI= (params) =>request({
url:'resource/downloadResource',method:'post',responseType:'blob',data:params,headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
}});