java+vue实现多文件打包下载
前端传过下载文件编号,在数据库中根据编号查出对应文件存储的路径,根据路径将文件写入到HttpServletResponse中,设置文本传输类型为二进制流response.setContentType("APPLICATION/OCTET-STREAM")
,将其返回给前端。
1.java后台
1.1.controller
@GetMapping("/download/{contractId}")
public void download(@PathVariable("contractId")String contractId, HttpServletResponse response) throws IOException {
String zipName = System.currentTimeMillis()+"myfile.zip";
//根据contractId找到下载文件的路径
List<String> filePath = erpContractFileService.queryErpContractFilePathByContractId(contractId);
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition","attachment; filename="+zipName);
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
try {
for (String fPath : filePath) {
ZipUtils.doCompress(fPath, out);
response.flushBuffer();
}
}
catch (Exception e) {
throw new RuntimeException("下载文件失败",e);
}finally{
out.close();
}
}
1.2.zipUtils
package com.lyw.erp.contract.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipUtils {
private ZipUtils(){
}
public static void doCompress(String srcFile, String zipFile) throws IOException {
doCompress(new File(srcFile), new File(zipFile));
}
public static void doCompress(File srcFile, File zipFile) throws IOException {
ZipOutputStream out = null;
try {
out = new ZipOutputStream(new FileOutputStream(zipFile));
doCompress(srcFile, out);
} catch (Exception e) {
throw e;
} finally {
out.close();//记得关闭资源
}
}
public static void doCompress(String filelName, ZipOutputStream out) throws IOException{
doCompress(new File(filelName), out);
}
public static void doCompress(File file, ZipOutputStream out) throws IOException{
doCompress(file, out, "");
}
public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException {
if ( inFile.isDirectory() ) {
File[] files = inFile.listFiles();
if (files!=null && files.length>0) {
for (File file : files) {
String name = inFile.getName();
if (!"".equals(dir)) {
name = dir + "/" + name;
}
ZipUtils.doCompress(file, out, name);
}
}
} else {
ZipUtils.doZip(inFile, out, dir);
}
}
public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException {
String entryName = null;
if (!"".equals(dir)) {
entryName = dir + "/" + inFile.getName();
} else {
entryName = inFile.getName();
}
ZipEntry entry = new ZipEntry(entryName);
out.putNextEntry(entry);
int len = 0 ;
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(inFile);
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
out.closeEntry();
fis.close();
}
}
2.vue前端
2.1 api(axios) 需要指定返回的类型,不然会出现乱码, responseType:‘blob’
//文件下载
export function download(contractId) {
return request({
url: '/contract/download/'+contractId,
method: 'get',
responseType:'blob'
})
}
2.2 views
<template>
<div class="app-container">
<!-- ------省略----- -->
<el-table-column label="合同附件" align="center" prop="file" >
<el-button
slot-scope="scope"
size="mini"
type="text"
v-hasPermi="['contract:contract:download']"
@click="downloadFile(scope.row.contractId)"
>点击下载
</el-button>
</el-table-column>
</div>
</template>
2.3 js
import { listContract, getContract, delContract,download } from "@/api/basic/contract/contract";
import {blobValidate} from "@/utils/ruoyi";
import errorCode from "@/utils/errorCode";
import { saveAs } from 'file-saver';
export default {
//省略
methods: {
downloadFile(contractId){
// console.log(contractId);
download(contractId).then(async data => {
const isLogin = await blobValidate(data);
console.log(data)
let name = contractId + "附件.zip";
if (isLogin) {
const blob = new Blob([data])
saveAs(blob, name);
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
downloadLoadingInstance.close();
}).catch(error => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
});
},
}
}