之前写过了压缩文件上传,现有一个新的需求,上传了多个文件,要把这些文件打包下载,本例子是通过zip的方式压缩下载多个文件。
首先jar包还是那两个:
<!--zip4j依赖,解压zip压缩-->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
<!--解压rar压缩-->
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>0.7</version>
</dependency>
然后controller类:
package com.kindo.monitor.plan.api;
import com.kindo.aria.base.Pageable;
import com.kindo.monitor.common.RowsWithTotal;
import com.kindo.monitor.fileUpload.CompressDownloadUtil;
import com.kindo.monitor.plan.model.MonitorFile;
import com.kindo.monitor.plan.service.PlanService;
import com.kindo.uas.common.model.ApiResultExten;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author liangliang
* @date 2021/2/2 16:22
*/
@Slf4j
@RestController
@RequestMapping("/file")
public class MonitorFileApi {
@Autowired
private PlanService planService;
@Value("${updown.dir}")
private String dir;
@RequestMapping(value = "/download/common", method = RequestMethod.GET)
@ApiOperation(value = "文件下载",notes = "文件下载")
public void downloadFile(@RequestParam("filePath") String filePath, @RequestParam("fileName") String fileName, HttpServletResponse response) {
log.info("文件下载路径:{},", filePath);
try (InputStream inputStream = new FileInputStream(new File(filePath));
OutputStream outputStream = response.getOutputStream()) {
// response.setContentType("application/x-download");
response.setContentType("multipart/form-data;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
// response.addHeader("Content-Disposition", "attachment;fileName=ttt");
// 把输入流copy到输出流
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
} catch (FileNotFoundException e) {
log.info("文件不能找到:", e);
} catch (IOException e) {
log.info("文件下载异常:", e);
}
}
@RequestMapping(value = "/downloadAllFiles", method = RequestMethod.GET)
public void downloadAllFiles(String year, HttpServletResponse response) {
if(!StringUtils.isBlank(year) && year.length() >= 4) {
year = year.substring(0, 4);
}
// 所有文件对象
List<MonitorFile> fileCenters = planService.queryFileList(year);
//-- 2、转换成文件列表
List<File> files = toFileList(fileCenters);
//-- 检查需要下载多文件列表中文件路径是否都存在
for (File file : files) {
if (!file.exists()) {
//-- 需要下载的文件中存在不存在地址
return;
}
}
//-- 3、响应头的设置
String downloadName = year + ".zip";
try {
HttpServletResponse response2 = CompressDownloadUtil.setDownloadResponse(response, downloadName);
//-- 将多个文件压缩写进响应的输出流
CompressDownloadUtil.compressZip(files, response2.getOutputStream());
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
* 将fileCenters列表转换为File列表
*
* @param fileCenters
* @return
* @author hongwei.lian
* @date 2018年9月6日 下午6:54:16
*/
private List<File> toFileList(List<MonitorFile> fileCenters) {
return fileCenters.stream()
.map(feFileCenter -> {
//-- 获取每个文件的路径
String filePath = feFileCenter.getFilePath();
return new File(filePath);})
.collect(Collectors.toList());
}
/**
* 设置下载响应头
*
* @param response
* @return
*/
public static HttpServletResponse setDownloadResponse(HttpServletResponse response, String downloadName) throws UnsupportedEncodingException {
// 如果加上会出现您的主机中的软件中止了一个已建立的连接
// response.reset();
response.setContentType("multipart/form-data;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadName, "UTF-8"));
return response;
}
}
多个文件下载其实也还是要获取每个文件的路径,所以查询出来的对象中把路径拿到转化为File对象然后进行压缩下载。