转载请注明出处:https://blog.csdn.net/feng2147685/article/details/80515371
简介:
最近项目中需要做一个批量打包ZIP下载,以前做过,但是没有记录下来。
于是又开始烧脑进行开发,本次也记录下来方便大家参考。直接上代码:
第一步:
列表选择需要下载的图片,将ID发送至后台。
//下载
function downloadat(id) {
document.location=encodeURI("../baseInfo/downloadAttachments.do?uuids="+id);
}
//批量下载
function downloadpl() {
var rows = $("#tt").datagrid("getSelections");
if (rows.length == 0) {
alertInfo(" 请先选择要下载的附件!");
} else {
var id2 = new Array();
for (var int = 0; int < rows.length; int++) {
id2[int] = rows[int].uuid;
}
document.location=encodeURI("../baseInfo/downloadAttachments.do?uuids="+id2);
}
}
第二步:
接收参数,ID为数组。
@RequestMapping("/downloadAttachments.do")
public void downloadAttachments(@RequestParam(value = "uuids")String[] uuids,HttpServletRequest request, HttpServletResponse response, PrintWriter pw) {
// map 接收返回信息
Map map = new HashMap<>();
// 如果uuids不为空,则下载
if (uuids.length > 0) {
try {
attachmentService.downloadAttachments(response,request,uuids);
map.put("msg", "下载成功!");
} catch (Exception e) {
e.printStackTrace();
}
}else{
map.put("msg", "下载异常!");
}
//返回结果转json
Gson gson = new Gson();
String json = gson.toJson(map);
try{
if(pw!=null){
pw.write(json);
}
}finally{
if(pw!=null){
pw.flush();
pw.close();
}
}
}
第三步:
/**
* 下载单个矿企附件
*/
@Override
public List queryAttachments(String epcode) {
List list = new ArrayList();
try {
// 根据矿企标识查询附件列表
list = baseattachmentMapper.selectByEpcode(epcode);
for (Baseattachment attachment : list) {
//改变文件名编码,防止乱码
String oldName = attachment.getFileoldname();
String fileName = new String (oldName.getBytes("UTF-8"),"ISO-8859-1");
attachment.setFileoldname(fileName);
//更改文件大小单位
attachment.setFilesize(FileUtil.getHumanReadableSize(Long.valueOf(attachment.getFilesize())));
// 遍历附件列表,如果有图片文件,复制到临时文件夹内,并将图片路径返回。
String fileFormat = attachment.getFileformat();
if (fileFormat.equals("jpg") || fileFormat.equals("png") || fileFormat.equals("bmp")) {
attachment.setFilepath(ConfigConstants.IMAGEPATH + new String (attachment.getFilepath().getBytes("UTF-8"),"ISO-8859-1"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 打包下载矿企附件
*/
@Override
public void downloadAttachments(HttpServletResponse response,HttpServletRequest request,String[] uuids) {
if (uuids.length<2) {//单独下载
String uuid = uuids[0];
//查询附件信息,将URL和名称放置对应数组
Baseattachment attachment = baseattachmentMapper.selectByPrimaryKey(uuid);//查询出附件信息
String filePath = ConfigConstants.IMAGEPATH + attachment.getFilepath();//拼接URL
try {
DownLoadUtil.urldownload(filePath, attachment.getFileoldname()+"."+attachment.getFileformat(), response);
} catch (IOException e) {
e.printStackTrace();
}
}else{//打包下载
//循环查询出所有的附件路径
List lstStr = new ArrayList<>();
List fileNamelst = new ArrayList<>();
for (String string : uuids) {
//循环查询附件信息,将URL和名称放置对应数组
Baseattachment selectByPrimaryKey = baseattachmentMapper.selectByPrimaryKey(string);
lstStr.add( ConfigConstants.IMAGEPATH+selectByPrimaryKey.getFilepath());
fileNamelst.add(selectByPrimaryKey.getFileoldname()+"."+selectByPrimaryKey.getFileformat());
}
try {
//调用工具类实现导出
DownLoadUtil.urldownloadZip(fileNamelst,lstStr,response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第四步:
转载请注明出处:https://blog.csdn.net/feng2147685/article/details/80515371
下面是一个导出工具类,本工具类可自行修改。
package com.yutu.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.yutu.config.ConfigConstants;
/**
* 工具类,下载
* Title: DownLoadUtil
* Description:
* @author ccf
* @date 2018-5-30
*/
public class DownLoadUtil{
/**
* 单个文件下载
* @param urlstring URL
* @param fileName 文件名称
* @param response
* @throws IOException
*/
public static void urldownload(String urlstring,String fileName,HttpServletResponse response) throws IOException{
fileName = new String (fileName.getBytes("UTF-8"),"ISO-8859-1");
response.reset();
response.setContentType("application/force-download");
response.addHeader("Content-Disposition","attachment;fileName=" + fileName);
response.setContentType("application/octet-stream;charset=utf-8");
URL url = new URL(urlstring);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
int length = conn.getContentLength();
response.setHeader("Content-Length", ""+length);
BufferedInputStream output = new BufferedInputStream(inputStream);
OutputStream outputStream = response.getOutputStream();
byte[] buff = new byte[1024*10];
int len = 0;
while ((len=output.read(buff))>-1) {
outputStream.write(buff,0,len);
}
//释放资源
output.close();
output.close();
}
/**
* 打包ZIP下载,图片不是本地,而是URL路径
* @param fileNamelst 文件名称list
* @param lstStr 文件URLlist
* @param response
* @throws Exception
*/
public static void urldownloadZip(List fileNamelst,List lstStr,
HttpServletResponse response) throws Exception {
//ConfigConstants.ZIPNAME为项目中配置的URL路径
String fileName =new String(ConfigConstants.ZIPNAME.getBytes("UTF-8"),"UTF-8");
//响应头的设置
response.reset();
response.setContentType("application/force-download");
response.addHeader("Content-Disposition","attachment;fileName=" + fileName);
response.setContentType("application/octet-stream;charset=utf-8");
//设置压缩流:直接写入response,实现边压缩边下载
ZipOutputStream zipos = null;
zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
//设置压缩方法
zipos.setMethod(ZipOutputStream.DEFLATED);
DataOutputStream os = null;
try {
//循环将文件写入压缩流
for (int i = 0; i < lstStr.size(); i++) {
URL url = new URL(lstStr.get(i));
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
//添加ZipEntry,并ZipEntry中写入文件流
zipos.putNextEntry(new ZipEntry(fileNamelst.get(i)));
os = new DataOutputStream(zipos);
byte[] buff = new byte[1024*10];
int len = 0;
//循环读写
while ((len=inputStream.read(buff))>-1) {
os.write(buff,0,len);
}
//关闭此文件流
inputStream.close();
//关闭当前ZIP项,并将流放置到写入的位置。下一个条目。
zipos.closeEntry();
}
//释放资源
os.flush();
os.close();
zipos.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
//释放资源
os.close();
zipos.close();
}
}
}
总结:
耗时4个小时,由于循环内没有调用zipos.closeEntry();,所以导出的ZIP会报错,未正确结尾。
转载请注明出处:https://blog.csdn.net/feng2147685/article/details/80515371