需求:
附件表存的报表的附件信息,包括地址,名称后缀,用户展示端选择一个文件或者多个文件进行下载。
思路:
1、展示端获取附件id一个或者多个传到后台
2、后台获取附件信息,判断附件信息个数,确定是否达成zip包
3、将压缩文件存在临时文件中
4、用流的方式输出到浏览器
代码:
/**
* 下载文件
* @param ids
*/
function downLoadFile(ids) {
var form = $("<form id='excel_temp_download_form' method='get'></form>");
form.attr("action",common.domainName+'/api-i/inspection/report/load');
form.append($("<input type='text' name='ids' value='" + ids + "' />"));
$(document.body).append(form);
form.submit();
$('#excel_temp_download_form').remove()
}
/**
* 单个或者多个下载
* @param response
* @param ids
* @throws IOException
*/
@RequestMapping("/load")
public void downLoad(HttpServletResponse response, @RequestParam("ids") List<String> ids)
throws IOException {
reportService.download(response,ids);
}
/**
* 单个或者批量下载文件
*
* @param response
* @param ids
*/
public void download(HttpServletResponse response,
List<String> ids) throws IOException {
ZipEntry zipEntry = null;
// 获取指定ID的附件列表
List<Attachment> list = attachmentRepository.findAllByIdIn(ids);
String path = "";
String name = "";
if(list.size() == 1){
Attachment attachment = list.get(0);
path = attachment.getPath();
name = attachment.getName() + attachment.getSuffix();
} else {
long nowTime = new Date().getTime();
name = "attachment_" + nowTime + ".zip";
path = fileToZip(list,name);
}
OutputStream out = null;
BufferedInputStream br = null;
try {
String fileName = URLEncoder.encode(name, "UTF-8");
br = new BufferedInputStream(new FileInputStream(path));
byte[] buf = new byte[1024];
int len = 0;
response.reset(); // 非常重要
// 纯下载方式
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
out = response.getOutputStream();
while ((len = br.read(buf)) > 0)
out.write(buf, 0, len);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
br.close();
out.close();
}
}
/**
* 将文件放入zip文件中
* @param list
* @param fileName
* @return
*/
public static String fileToZip(List<Attachment> list,String fileName) {
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
// 临时目录 C:\Users\ADMINI~1\AppData\Local\Temp\
String path = System.getProperty("java.io.tmpdir")+ fileName;
try {
File zipFile = new File(path );
// 如果存在该zip文件,则删除
zipFile.deleteOnExit();
// 创建一个新文件
zipFile.createNewFile();
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024 * 10];
for (Attachment attachment: list) {
File subFile = new File(attachment.getPath());
//如果文件不存在,则不添加到zip包中
if (!subFile.exists()){
continue;
}
// 文件名增加时间戳避免重复
String subFileName = attachment.getName() + "-" + new Date().getTime() +
attachment.getSuffix();
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(subFileName);
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(subFile);
bis = new BufferedInputStream(fis, 1024 * 10);
int read = 0;
while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
zos.write(bufs, 0, read);
}
}
System.out.println("压缩成功");
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭流
try {
if (null != bis) bis.close();
if (null != zos) zos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return path;
}