public class FileUtils {
/**
* 本地文件路径
*/
private static final String FILE_PATH = "F:\\test";
/**
* 批量下载文件
*
* @param list 批量文件集合(前端只传id集合,后端去查数据库拿到文件信息)
* @param request request
* @param response response
* @param <T> 实体类 extends BaseEntityPoJo
*/
public static <T extends BaseEntityPoJo> void batchDownloadFile(List<T> list, HttpServletRequest request, HttpServletResponse response) {
//设置响应头信息
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
//设置压缩包的名字,date为时间戳
String date = DateUtil.formatDateTimeSecond(new Date());
String downloadName = "压缩包" + date + ".zip";
//返回客户端浏览器的版本号、类型
String agent = request.getHeader("USER-AGENT");
try {
//针对IE或者以IE为内核的浏览器:
if (agent.contains("MSIE") || agent.contains("Trident")) {
downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
} else {
//非IE浏览器的处理:
downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}
} catch (Exception e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");
//设置压缩流:直接写入response,实现边压缩边下载
ZipOutputStream zipOs = null;
//循环将文件写入压缩流
DataOutputStream os = null;
//文件
File file;
try {
zipOs = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
//设置压缩方法
zipOs.setMethod(ZipOutputStream.DEFLATED);
//遍历文件信息(主要获取文件名/文件路径等)
for (T t : list) {
try {
//文件名(包含后缀名,如:测试.pdf)
Field field = t.getClass().getDeclaredField("name");
field.setAccessible(true);
String name = field.get(t).toString();
//本地文件路径(绝对路径,包含后缀名,如:F:\\test\\测试.pdf),这里是在windows上测试的,路径是反斜杠
String path = FILE_PATH + File.separator + name;
log.info("batchDownloadFile:[filePath:{}]", path);
file = new File(path);
if (!file.exists()) {
throw new RuntimeException("文件不存在");
}
//添加ZipEntry,并将ZipEntry写入文件流
zipOs.putNextEntry(new ZipEntry(name));
os = new DataOutputStream(zipOs);
FileInputStream fs = new FileInputStream(file);
byte[] b = new byte[1024];
int length;
//读入需要下载的文件的内容,打包到zip文件
while ((length = fs.read(b)) != -1) {
os.write(b, 0, length);
}
//关闭流
fs.close();
zipOs.closeEntry();
} catch (IllegalAccessException | NoSuchFieldException e) {
log.error("下载文件出错![{}]", e.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if (os != null) {
os.flush();
os.close();
}
if (zipOs != null) {
zipOs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
控制层:
/**
* 批量下载(测试时可改为GET请求,浏览器直接调用接口)
*
* @param ids 用于查询相关表获取文件信息
* @param request request
* @param response response
*/
@GetMapping("/batchDownloadFile")
@ApiOperation("批量下载")
public void batchDownloadFile(@RequestParam("ids") final String ids,
HttpServletRequest request,
HttpServletResponse response) {
log.info("downloadPlanFile:批量下载[ids:{},request:{},response:{}]", ids, request, response);
List<Integer> idList = ControllerHelper.splitToLong(ids);
List<RegulatoryReport> list = service.list(idList);
FileUtil.batchDownloadFile(list, request, response);
}