场景一:将本地的多个文件(doc、jpg、txt、pdf)且文件名包含中文,打成压缩包后下载与某位置保存
原始多个文件位于D盘下
测试代码如下:
package cn.tedu.test;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class DownLoad {
public static void main(String[] args) {
//需要压缩的文件--包括文件地址和文件名
String [] path ={"D:\\测试水印1.doc","D:\\你好123.jpg","D:\\说明.txt","D:\\elasticsearch权威指南-中文.pdf"};
// 要生成的压缩文件地址和文件名称
String desPath = "D:\\new.zip";
File zipFile = new File(desPath);
ZipOutputStream zipStream = null;
FileInputStream zipSource = null;
BufferedInputStream bufferStream = null;
try {
//构造最终压缩包的输出流
zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
for(int i =0;i<path.length;i++){
String pathEach = tranZW(path[i]);
File file = new File(pathEach);
//将需要压缩的文件格式化为输入流
zipSource = new FileInputStream(file);
//压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样
String fileName = file.getName();
ZipEntry zipEntry = new ZipEntry(fileName);
//定位该压缩条目位置,开始写入文件到压缩包中
zipStream.putNextEntry(zipEntry);
//输入缓冲流
bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
int read = 0;
//创建读写缓冲区
byte[] buf = new byte[1024 * 10];
while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1){
zipStream.write(buf, 0, read);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if(null != bufferStream) bufferStream.close();
if(null != zipStream) zipStream.close();
if(null != zipSource) zipSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//文件路径中包含的中文编码返回 D:\\说明.txt
public static String tranZW(String filePath) throws UnsupportedEncodingException{
String fileName = filePath.substring(filePath.lastIndexOf(".") + 1);//说明.txt
String temp = new String(fileName.getBytes("GBK"), "ISO-8859-1");
return filePath.substring(0, filePath.lastIndexOf(".") + 1) + temp;
}
}
执行main方法后,D盘下多可一个压缩文件
该压缩文件包含如下
场景二:将本地的多个文件(doc、jpg、txt、pdf)且文件名包含中文,打成压缩包后弹框自定义下载路径
文件准备:D盘有6个文件如下
要求导出的压缩文件中有文件夹D,D下面还有文件夹,文件夹名称为文件的类型,将对应类型的文件放在文件夹下
E盘有2个文件如下
要求导出的压缩文件有文件夹E,E下面直接放这两个文件
前端代码:
<a style="color: red;" href="/download/file">打包压缩</a>
点击后直接进入controller如下
package com.tedu.controller;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tedu.entity.FileMap;
import com.tedu.util.DownloadUtil;
@Controller
@RequestMapping("/download")
public class FileConroller {
@RequestMapping("/file")
public void downloadFiles(HttpServletRequest request, HttpServletResponse response){
System.out.println("操作");
ZipOutputStream zipStream = null;
FileInputStream zipSource = null;
BufferedInputStream bufferStream = null;
String zipFileName = "压缩.zip";//压缩文件名
try {
zipFileName = new String(zipFileName.getBytes("GBK"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + zipFileName);//压缩文件名
zipStream = new ZipOutputStream(response.getOutputStream());
//准备数据
Map<String, List<FileMap>> map = DownloadUtil.getDdiskFiles();
//调用工具类
DownloadUtil.writeToFolder(map, zipStream, zipSource, bufferStream);
//导出结束
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
if(null != bufferStream) bufferStream.close();
if(null != zipStream) zipStream.close();
if(null != zipSource) zipSource.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
工具类如下
package com.tedu.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.collections4.map.HashedMap;
import com.tedu.entity.FileMap;
public class DownloadUtil {
//测试
public static void main(String[] args) {
Map<String, List<FileMap>> map = getDdiskFiles();
for(String key : map.keySet()){
System.out.println(key + "==" + map.get(key));
/*
for(FileMap e : map.get(key)){
System.out.println(e.getFile().getName());
}
*/
}
}
/**
* 创建目录并将文件写入
* map key 文件夹层级目录
* 创建文件夹D 再分别创建5个文件夹(文件夹名可以中文,此处以文件类型命名)
* 创建文件夹E 将2个文件直接放在e文件夹下(文件夹名可以中文)
* @throws IOException
*/
public static void writeToFolder(
Map<String, List<FileMap>> map,
ZipOutputStream zipStream,
FileInputStream zipSource,
BufferedInputStream bufferStream) throws IOException{
for(String key : map.keySet()){
zipStream.putNextEntry(new ZipEntry(key + "\\"));//第一层文件夹
for(FileMap e : map.get(key)){
String fileName = e.getFile().getName(); //测试水印1.doc 编码 避免中文乱码
//将需要压缩的文件格式化为输入流
zipSource = new FileInputStream(e.getFile());
//压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样
//定位该压缩条目位置,开始写入文件到压缩包中
ZipEntry zipEntry = new ZipEntry(key + "\\" + fileName);//内部文件名
zipStream.putNextEntry(zipEntry);
//输入缓冲流
bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
int read = 0;
//创建读写缓冲区
byte[] buf = new byte[1024 * 10];
while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1){
zipStream.write(buf, 0, read);
}
zipStream.flush();
}
}
}
/**
* 此处省略查询,直接给出D E盘 文件文件路径存于map
* 将要下载的文件找到并且将其属性封装到List
* @return
*/
public static Map<String, List<FileMap>> getDdiskFiles(){
Map<String, List<FileMap>> map = new HashedMap<String, List<FileMap>>();
List<String> list = new ArrayList<String>();
list.add("D:\\19-09-17-03.sql");
list.add("D:\\elasticsearch权威指南-中文.pdf");
list.add("D:\\测试水印1.doc");
list.add("D:\\你好123.jpg");
list.add("D:\\o_img_qq.jpg");
list.add("D:\\说明.txt");
List<String> list1 = new ArrayList<String>();
list1.add("E:\\cloud_note.sql");
list1.add("E:\\账单.xls");
for(String s : list){
String[] arr = s.split(":");
String key = arr[0] + "\\" + arr[1].split("\\.")[1];
if(map.containsKey(key)){
List<FileMap> temp = map.get(key);
temp.add(new FileMap(new File(s), s));
map.put(key, temp);
}else{
List<FileMap> temp = new ArrayList<FileMap>();
temp.add(new FileMap(new File(s), s));
map.put(key, temp);
}
}
for(String s : list1){
String key = s.split(":")[0];
if(map.containsKey(key)){
List<FileMap> temp = map.get(key);
temp.add(new FileMap(new File(s), s));
map.put(key, temp);
}else{
List<FileMap> temp = new ArrayList<FileMap>();
temp.add(new FileMap(new File(s), s));
map.put(key, temp);
}
}
return map;
}
//文件路径中包含的中文编码返回 D:\\说明.txt
public static String tranZW(String fileName) throws UnsupportedEncodingException {
return new String(fileName.getBytes("GBK"), "ISO-8859-1");
}
}
效果如下,点击
弹窗
桌面下载的文件如下
解压后的情况
到此结束