2024-07-10 10:20:51 +08:00
|
|
|
|
package com.gunshi.project.xyt.util;
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
|
import cn.hutool.core.io.resource.ClassPathResource;
|
|
|
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
|
|
|
import com.alibaba.excel.ExcelWriter;
|
|
|
|
|
|
import com.alibaba.excel.support.ExcelTypeEnum;
|
|
|
|
|
|
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
|
|
|
|
|
|
import com.alibaba.excel.write.metadata.WriteSheet;
|
2024-07-12 11:21:22 +08:00
|
|
|
|
import com.gunshi.project.xyt.util.excel.ExcelFillCellMergeStrategy;
|
2024-07-10 14:04:43 +08:00
|
|
|
|
import com.gunshi.project.xyt.util.excel.ExcelListener;
|
|
|
|
|
|
import com.gunshi.project.xyt.util.excel.ExcelResult;
|
2024-07-12 11:21:22 +08:00
|
|
|
|
import com.gunshi.project.xyt.util.excel.VoteTitleHandler;
|
2024-07-10 10:20:51 +08:00
|
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2024-07-10 14:04:43 +08:00
|
|
|
|
import java.io.InputStream;
|
2024-07-10 10:20:51 +08:00
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
|
import java.net.URLEncoder;
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
public class ExcelUtil {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 导出excel
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param list 导出数据集合,加动态表头
|
|
|
|
|
|
* @param filename 工作表的名称
|
|
|
|
|
|
* @param clazz 实体类
|
|
|
|
|
|
* @param response 响应体
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> void exportExcel(List<T> list, String filename, Class<T> clazz, HttpServletResponse response,String sheetName) {
|
|
|
|
|
|
OutputStream out = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
out = getOutputStream(filename,response);
|
|
|
|
|
|
ExcelWriterSheetBuilder builder = EasyExcel.write(out, clazz)
|
|
|
|
|
|
//是否自动关闭流
|
|
|
|
|
|
.autoCloseStream(Boolean.FALSE)
|
|
|
|
|
|
//自动列宽(不太精确)
|
|
|
|
|
|
.registerWriteHandler(new VoteTitleHandler(filename))
|
|
|
|
|
|
.sheet(sheetName);
|
|
|
|
|
|
builder.doWrite(list);
|
2024-07-11 13:36:44 +08:00
|
|
|
|
} finally {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (out != null){
|
|
|
|
|
|
out.flush();
|
|
|
|
|
|
out.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
throw new RuntimeException("导出Excel异常");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-12 11:21:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 导出动态列
|
|
|
|
|
|
* @param head 表头
|
|
|
|
|
|
* @param data 数据
|
|
|
|
|
|
* @param filename
|
|
|
|
|
|
* @param response
|
|
|
|
|
|
* @param sheetName
|
|
|
|
|
|
* @param <T>
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> void exportExcel(List<List<String>> head,List<T> data, String filename, HttpServletResponse response,String sheetName) {
|
2024-07-11 13:36:44 +08:00
|
|
|
|
OutputStream out = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
out = getOutputStream(filename,response);
|
2024-07-12 11:21:22 +08:00
|
|
|
|
ExcelWriterSheetBuilder builder = EasyExcel.write(out)
|
2024-07-11 13:36:44 +08:00
|
|
|
|
//是否自动关闭流
|
|
|
|
|
|
.autoCloseStream(Boolean.FALSE)
|
|
|
|
|
|
//自动列宽(不太精确)
|
|
|
|
|
|
.registerWriteHandler(new VoteTitleHandler(filename))
|
|
|
|
|
|
.head(head)
|
|
|
|
|
|
.sheet(sheetName);
|
|
|
|
|
|
builder.doWrite(data);
|
2024-07-10 10:20:51 +08:00
|
|
|
|
} finally {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (out != null){
|
|
|
|
|
|
out.flush();
|
|
|
|
|
|
out.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
throw new RuntimeException("导出Excel异常");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-12 11:21:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
*导出动态列,带合并单元格
|
|
|
|
|
|
* @param head 表头
|
|
|
|
|
|
* @param data 表格数据
|
|
|
|
|
|
* @param mergeRowIndex 从第几行开始合并
|
|
|
|
|
|
* @param mergeColumnIndex 合并字段的下标,如第一到五列new int[]{0,1,2,3,4}
|
|
|
|
|
|
* @param filename
|
|
|
|
|
|
* @param response
|
|
|
|
|
|
* @param sheetName
|
|
|
|
|
|
* @param <T>
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> void exportExcel(List<List<String>> head,List<T> data,int mergeRowIndex,int[] mergeColumnIndex, String filename, HttpServletResponse response,String sheetName) {
|
|
|
|
|
|
OutputStream out = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
out = getOutputStream(filename,response);
|
|
|
|
|
|
ExcelWriterSheetBuilder builder = EasyExcel.write(out)
|
|
|
|
|
|
//是否自动关闭流
|
|
|
|
|
|
.autoCloseStream(Boolean.FALSE)
|
|
|
|
|
|
.registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex))
|
|
|
|
|
|
.head(head)
|
|
|
|
|
|
.sheet(sheetName);
|
|
|
|
|
|
builder.doWrite(data);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (out != null){
|
|
|
|
|
|
out.flush();
|
|
|
|
|
|
out.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
throw new RuntimeException("导出Excel异常");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-07-10 10:20:51 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 单表多数据模板导出 模板格式为 {.属性}
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param filename 文件名
|
|
|
|
|
|
* @param templatePath 模板路径 resource 目录下的路径包括模板文件名
|
|
|
|
|
|
* 例如: excel/temp.xlsx
|
|
|
|
|
|
* 重点: 模板文件必须放置到启动类对应的 resource 目录下
|
|
|
|
|
|
* @param data 模板需要的数据
|
|
|
|
|
|
* @param list 模板需要的集合数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> void exportTemplate(Map<String, Object> data, List<T> list, String filename, String templatePath, HttpServletResponse response) {
|
|
|
|
|
|
OutputStream out = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
out = getOutputStream(filename,response);
|
|
|
|
|
|
ClassPathResource templateResource = new ClassPathResource(templatePath);
|
|
|
|
|
|
ExcelWriter excelWriter = EasyExcel.write(out)
|
|
|
|
|
|
.withTemplate(templateResource.getStream())
|
|
|
|
|
|
.excelType(ExcelTypeEnum.XLSX)
|
|
|
|
|
|
.build();
|
|
|
|
|
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
|
|
|
|
|
if (CollUtil.isEmpty(data)) {
|
|
|
|
|
|
throw new IllegalArgumentException("数据为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
excelWriter.fill(list,writeSheet);
|
|
|
|
|
|
excelWriter.fill(data, writeSheet);
|
|
|
|
|
|
excelWriter.finish();
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (out != null){
|
|
|
|
|
|
out.flush();
|
|
|
|
|
|
out.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
throw new RuntimeException("导出Excel异常");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
|
|
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
|
|
|
|
|
|
response.setCharacterEncoding("utf8");
|
|
|
|
|
|
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
|
|
|
|
|
|
response.setHeader("Pragma", "public");
|
|
|
|
|
|
response.setHeader("Cache-Control", "no-store");
|
|
|
|
|
|
response.addHeader("Cache-Control", "max-age=0");
|
|
|
|
|
|
return response.getOutputStream();
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
System.out.println(e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-10 14:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 使用自定义监听器 异步导入 自定义返回
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param is 输入流
|
|
|
|
|
|
* @param clazz 对象类型
|
|
|
|
|
|
* @param listener 自定义监听器
|
|
|
|
|
|
* @return 转换后集合
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, ExcelListener<T> listener) {
|
|
|
|
|
|
EasyExcel.read(is, clazz, listener).sheet().doRead();
|
|
|
|
|
|
return listener.getExcelResult();
|
|
|
|
|
|
}
|
2024-07-10 10:20:51 +08:00
|
|
|
|
|
|
|
|
|
|
}
|