controller 代码
@ApiOperation(value = "系统文件批量下载接口", produces = "application/octet-stream")
@PostMapping(value = "/downloadzip")
public void downloadzip(@ApiParam("文件 url 路径") @RequestBody CommonProjectSearchVo searchVo, HttpServletResponse response) throws Exception {
String[] paths = searchVo.getPaths();
if (Objects.isNull(searchVo) || Objects.isNull(searchVo.getPaths()) || paths.length == 0) {
throw new CustomException("请选择附件");
}
if (paths.length != 0) {
// 创建临时路径,存放压缩文件
String myFileName = OperatorUtils.getOperator().getOperator()
+ String.valueOf(new Date().getTime()) + ".zip";
String zipFilePath = downloadPath + "/" + myFileName;
File file = new File(downloadPath);
//如果文件夹不存在则创建
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
// 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath));
// 循环调用压缩文件方法,将一个一个需要下载的文件打入压缩文件包
for (String path : paths) {
FileConvertUtil.fileToZip(path, zipOut);
}
// 压缩完成后,关闭压缩流
zipOut.close();
//拼接下载默认名称并转为ISO-8859-1格式
String fileName = new String((myFileName).getBytes(), "ISO-8859-1");
response.setHeader("Content-Disposition", "attchment;filename=" + fileName);
//该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
ServletOutputStream outputStream = response.getOutputStream();
FileInputStream inputStream = new FileInputStream(zipFilePath);
// 如果是SpringBoot框架,在这个路径
// org.apache.tomcat.util.http.fileupload.IOUtils产品
// 否则需要自主引入apache的 commons-io依赖
// copy方法为文件复制,在这里直接实现了下载效果
IOUtils.copy(inputStream, outputStream);
// 关闭输入流
inputStream.close();
//下载完成之后,删掉这个zip包
File fileTempZip = new File(zipFilePath);
fileTempZip.delete();
}
}
FileConvertUtil.fileToZip
/**
* 文件格式转换工具类
*/
public class FileConvertUtil {
/**
* 【文件压缩】网络文件
*
* @param filePath:
* @param zipOut:
* @return void
*/
public static void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {
filePath = getEncodeUrl(filePath).replaceAll("\\+", "%20");
// 需要压缩的文件
File file = new File(filePath);
// 获取文件名称,为解决压缩时重复名称问题,对文件名加时间戳处理
String fileName = FilenameUtils.getBaseName(URLDecoder.decode(file.getName(), "UTF-8")) + "-"
+ String.valueOf(new Date().getTime()) + "."
+ FilenameUtils.getExtension(file.getName());
InputStream fileInput = getInputStream(filePath);
// 缓冲
byte[] bufferArea = new byte[1024 * 10];
BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10);
// 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称
zipOut.putNextEntry(new ZipEntry(fileName));
int length = 0;
// 最常规IO操作,不必紧张
while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
zipOut.write(bufferArea, 0, length);
}
//关闭流
fileInput.close();
// 需要注意的是缓冲流必须要关闭流,否则输出无效
bufferStream.close();
// 压缩流不必关闭,使用完后再关
}
/**
* 【获取网络文件的输入流】
*
* @param filePath: 网络文件路径
* @return java.io.InputStream
*/
public static InputStream getInputStream(String filePath) throws IOException {
InputStream inputStream = null;
// 创建URL
URL url = new URL(filePath);
// 试图连接并取得返回状态码
URLConnection urlconn = url.openConnection();
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
int httpResult = httpconn.getResponseCode();
if (httpResult == HttpURLConnection.HTTP_OK) {
inputStream = urlconn.getInputStream();
}
return inputStream;
}
}