题主最近项目上的新需求是需要把多张图片打包为一个zip包,放到页面上供用户下载,前期的打包很顺利,但是最后的下载zip包却屡次碰壁,明明打包没问题,用ftp工具拉下来也可以正常打开,但是下载下来就是报错!!之后可以说是在看了全网相关帖子的基础上,终于是找到了解决办法,下面分享给大家。
以下载多个文件为例,需要导入zip4j的jar包,版本不要太高
public void downloadZip(List<fielEntiry> list, HttpServletRequest request, HttpServletResponse response) {
String zipFileName = "";
File[] tempList = null;
//因为我这边在classpath下无法获取到新建文件夹,所以使用路径拼接
String path = this.getClass().getClassLoader().getResource("template/").getPath();
path += "tempPack";
File outFile = new File(path);
for (fielEntiry file : list) {
String url = file.getUrl();//云服务器文件链接
String fileName = assc.getFileName();
if (!outFile.exists()) {
outFile.mkdirs();
}
try {
download(url, path, fileName);
} catch (Exception e) {
e.printStackTrace();
}
}
zipFileName = "/报告.zip";
tempList = outFile.listFiles();
createZipFile(path, zipFileName, tempList);
for (File file : outFile.listFiles()) {
download(file, request, response);
}
} else {
throw new BadRequestException("暂无报告附件");
}
}
}
下载文件到临时文件夹
public void download(String urlPath, String targetDirectory, String fileName) throws Exception {
URL url = new URL(urlPath);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
InputStream inputStream = http.getInputStream();
byte[] buff = new byte[1024 * 10];
OutputStream out = new FileOutputStream(new File(targetDirectory, fileName));
int lenth = -1;
while ((lenth = inputStream.read(buff)) != -1) {
out.write(buff, 0, len);
out.flush();
}
// 关闭资源
out.close();
inputStream.close();
http.disconnect();
}
将文件打包成zip文件
public static ZipFile createZipFile(String templatePathZip, String fileName, File... files) {
try { // 创建zip包,指定路径和名称
final ZipFile zipFile = new ZipFile(templatePathZip + fileName);
// 向zip包中添加文件集合
final ArrayList<File> fileAddZip = new ArrayList<File>();
File file1 = zipFile.getFile();
if (file1.exists()) {
file1.delete();
}
// 向zip包中添加文件
for (File file : files) {
fileAddZip.add(file);
}
// 设置zip包的一些参数集合
final ZipParameters parameters = new ZipParameters();
// 是否设置密码(若passwordZip为空,则为false)
/*if (null != passwordZip && !passwordZip.equals("")) {
parameters.setEncryptFiles(true);
// 压缩包密码
parameters.setPassword(passwordZip);
} else { }*/
parameters.setEncryptFiles(false);
// 压缩方式(默认值)
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 普通级别(参数很多)
// parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
// 加密级别
// parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
// 创建压缩包完成
zipFile.createZipFile(fileAddZip, parameters);
//压缩完成后删除文件
for (File file : files) {
file.delete();
}
return zipFile;
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
*最最最最重要的下载模块,作者就是在这踩坑无数,基本是把全网的帖子都看了一遍,这个方法已经验证过了,大家放心食用
private void download(File file, HttpServletRequest request, HttpServletResponse response) {
ServletOutputStream out = null;
FileInputStream inputStream = null;
try {
String filename = file.getName();
String userAgent = request.getHeader("User-Agent");
// 针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
filename = java.net.URLEncoder.encode(filename, "UTF-8");
} else {
// 非IE浏览器的处理:
// filename = URLEncoder.encode(filename, "UTF-8");
filename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
response.setHeader("Content-disposition",
String.format("attachment; filename=\"%s\"", filename));
response.setContentType("application/download");
response.setCharacterEncoding("UTF-8");
out = response.getOutputStream();
inputStream = new FileInputStream(file);
byte[] buffer = new byte[1024 * 10];
int lenth = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while ((lenth = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != out) out.close();
if (null != inputStream) inputStream.close();
file.delete();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}