192 lines
7.1 KiB
Java
192 lines
7.1 KiB
Java
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;
|
||
import com.gunshi.project.xyt.util.excel.ExcelFillCellMergeStrategy;
|
||
import com.gunshi.project.xyt.util.excel.ExcelListener;
|
||
import com.gunshi.project.xyt.util.excel.ExcelResult;
|
||
import com.gunshi.project.xyt.util.excel.VoteTitleHandler;
|
||
import jakarta.servlet.http.HttpServletResponse;
|
||
|
||
import java.io.IOException;
|
||
import java.io.InputStream;
|
||
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);
|
||
} finally {
|
||
try {
|
||
if (out != null){
|
||
out.flush();
|
||
out.close();
|
||
}
|
||
} catch (IOException e) {
|
||
throw new RuntimeException("导出Excel异常");
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 导出动态列
|
||
* @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) {
|
||
OutputStream out = null;
|
||
try {
|
||
out = getOutputStream(filename,response);
|
||
ExcelWriterSheetBuilder builder = EasyExcel.write(out)
|
||
//是否自动关闭流
|
||
.autoCloseStream(Boolean.FALSE)
|
||
//自动列宽(不太精确)
|
||
.registerWriteHandler(new VoteTitleHandler(filename))
|
||
.head(head)
|
||
.sheet(sheetName);
|
||
builder.doWrite(data);
|
||
} finally {
|
||
try {
|
||
if (out != null){
|
||
out.flush();
|
||
out.close();
|
||
}
|
||
} catch (IOException e) {
|
||
throw new RuntimeException("导出Excel异常");
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
*导出动态列,带合并单元格
|
||
* @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异常");
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 单表多数据模板导出 模板格式为 {.属性}
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
/**
|
||
* 使用自定义监听器 异步导入 自定义返回
|
||
*
|
||
* @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();
|
||
}
|
||
|
||
}
|