首先声明,不是通用的,是和我的业务进行结合的,但是拿去只要改一改,肯定能够用,我会详细的把参数说一遍;
方法是肯定能用的,因为我已经部署到公司的生产环境了,所以有什么问题随时在下面留言,我每天都会看csdn;
首先是主方法;
我这里list的数据,存的第一个字段是阀门的名称,所以下面在进行分类的时候是用这个分类的,即一个阀门就生成一个table或者sheet,你们拿去之后,想按那个分类,就把哪个放第一个参数就可以了
/**
* 压缩导出
* @param response res
* @param headerList 头集合
* @param list 数据集合
* @param fileName 文件名称
*/
public static String zipData(HttpServletResponse response, List<String> headerList, List<List<Object>> list, int type, String fileName) {
// 用于存放文件路径
List<String> filePaths = new ArrayList<>();
//生成的ZIP文件名为Demo.zip
String tmpFileName = fileName + ".zip";
// zip文件路径
filePaths.add(tmpFileName);
try {
//创建zip输出流
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tmpFileName));
//声明文件集合用于存放excel文件
List<File> fileList = new ArrayList<>();
//生成excel文件集合
// 生成随机文件名
fileName = fileName + ".xlsx";
File newFile = creatFile(fileName);
// 将文件路径保存
fileList.add(creatFile(fileName));
filePaths.add(fileName);
writeExcel(newFile, headerList, list, type);
byte[] buffer = new byte[1024];
//将excel文件放入zip压缩包
for (File file : fileList) {
FileInputStream fis = new FileInputStream(file);
out.putNextEntry(new ZipEntry(file.getName()));
int len;
// 读入需要下载的文件的内容,打包到zip文件
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
fis.close();
}
out.close();
//下载zip文件
downFile(response, tmpFileName, filePaths);
return "";
} catch (Exception e) {
// 下载失败删除生成的文件
deleteFile(filePaths);
log.error("文件下载出错", e);
e.printStackTrace();
return e.getMessage();
}
}
主方法调用的第一个方法
就如上面说的,datalist的里面的集合第一个字段是分类标准,type等于1是多sheet,等于2是多table
private static void writeExcel(File newFile, List<String> headerList, List<List<Object>> datalist, int type) {
//初始化excel
ExcelWriter excelWriter = EasyExcel.write(newFile).build();
//获取阀门名称
List<String> valveNameList = new ArrayList<>();
for (List<Object> objectList : datalist) {
valveNameList.add((String) objectList.get(0));
}
//去重
List<String> collectList = valveNameList.stream().distinct().collect(Collectors.toList());
//按阀门创建sheet
// 创建一个表格
if (type == 1) {
//多sheet
//创建表头
List<List<String>> headList = new ArrayList<>();
// 第 n 行 的表头
for (String s : headerList) {
List<String> headTitle = new ArrayList<>();
headTitle.add(s);
headList.add(headTitle);
}
WriteTable writeTable = EasyExcel.writerTable(0).head(headList).needHead(true).build();
String ifValveName;
for (int i = 0; i < collectList.size(); i++) {
//创建新数据集合
List<List<Object>> newList = new ArrayList<>();
for (List<Object> objects : datalist) {
//取出阀门名称
ifValveName = (String) objects.get(0);
//获取相符合的数据
if (collectList.get(i).equals(ifValveName)) {
newList.add(objects);
}
}
WriteSheet writeSheet = EasyExcel.writerSheet(i, collectList.get(i)).build();
excelWriter.write(newList, writeSheet, writeTable);
}
} else {
//多表头
String ifValveName;
for (int i = 0; i < collectList.size(); i++) {
List<List<Object>> newList = new ArrayList<>();
for (List<Object> objects : datalist) {
ifValveName = (String) objects.get(0);
if (collectList.get(i).equals(ifValveName)) {
newList.add(objects);
}
}
//创建表头
// 第 n 行 的表头
List<List<String>> headList = new ArrayList<>();
for (String s : headerList) {
List<String> headTitle = new ArrayList<>();
headTitle.add(s);
headList.add(headTitle);
}
WriteTable writeTable = EasyExcel.writerTable(i).head(headList).needHead(true).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet1").build();
excelWriter.write(newList, writeSheet, writeTable);
}
}
excelWriter.finish();
}
主方法调用的操作文件方法
这个没啥好说的
/**
* 文件下载
*
* @param response response
* @param str path
* @param filePaths 生成文件
*/
private static void downFile(HttpServletResponse response, String str, List<String> filePaths) {
try {
File file = new File(str);
if (file.exists()) {
InputStream ins = new FileInputStream(str);
BufferedInputStream bins = new BufferedInputStream(ins);// 放到缓冲流里面
OutputStream outs = response.getOutputStream();// 获取文件输出IO流
BufferedOutputStream bouts = new BufferedOutputStream(outs);
response.setContentType("application/x-download");// 设置response内容的类型
response.setHeader(
"Content-disposition",
"attachment;filename="
+ URLEncoder.encode(str, "UTF-8"));// 设置头部信息
int bytesRead;
byte[] buffer = new byte[8192];
// 开始向网络传输文件流
while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
bouts.write(buffer, 0, bytesRead);
}
bouts.flush();// 这里一定要调用flush()方法
ins.close();
bins.close();
outs.close();
bouts.close();
deleteFile(filePaths);
}
} catch (IOException e) {
deleteFile(filePaths);
log.error("文件下载出错", e);
}
}
//创建文件File对象
private static File creatFile(String filePath) {
return new File(filePath);
}
//删除文件
public static void deleteFile(List<String> filePath) {
for (String pathname : filePath) {
File file = new File(pathname);
if (file.exists()) {
file.delete();
}
}
}
2022-01-14更新:看有很多人,不知道数据怎么传,这里我把数据组装发一下
//创建表头 只是示例,不用在乎里面的内容和导出的内容不符,因为这个示例本来就不是之前的导出,只是把组装方法放到这里
List<String> headerList = new ArrayList<>();
headerList.add("科目");// 第一个必须是科目 已哪个为sheet名称,就是哪个是第一个
headerList.add("税务法人");
headerList.add("税务会计");
//这里得表头和你的字段一一对应 一共21个 我就不写了
//获取数据 从数据库获取 我因为是模拟的 所以直接创建了
List<TaxInfo> taxInfoList = new ArrayList<>();
//创建传入参数
List<List<Object>> list = new ArrayList<>();
//循环list
for (TaxInfo taxInfo : taxInfoList) {
//创建row行list
List<Object> rowList = new ArrayList<>();
rowList.add(taxInfo.getTaxSubject());//这里和上面的有list对应上
rowList.add(taxInfo.getTaxLegalPerson());
rowList.add(taxInfo.getTaxAccountPeriod());
//后面的也一样 和表头的顺序对应上就行了
list.add(rowList);
}
writeExcel(headerList,list,1,"xxxx.xlsx");
效果展示:
压缩多sheet:
多表头
感谢xuanbin.zhang提供的技术指导