package cn.hsa.zjhsb.bpgj.common.utils;
import cn.hsa.hsaf.core.framework.web.WrapperResponse;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.commons.collections.CollectionUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Stream;
/**
* @author
* @version 1.0
* @date 2022/06/28
*/
public class ExcelUtil {
private static final String CHARACTER = "UTF-8";
private static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
private static final String CONTENT_DISPOSITION = "Content-Disposition";
private static final String CACHE_CONTROL = "Cache-Control";
private static final String NO_STORE = "no-store";
private static final String MAX_AGE = "max-age=0";
public static <T, E> void export(HttpServletResponse response, String title, List<T> list, Class<E> tClass) throws IOException {
export(response, title, list, tClass, null);
}
public static <T, E> void export(HttpServletResponse response, String title, List<T> list, Class<E> tClass, Set<String> excludeColumnFiledNames) throws IOException {
response.setContentType(CONTENT_TYPE);
response.setCharacterEncoding(CHARACTER);
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode(title, CHARACTER).replaceAll("\\+", "%20");
response.setHeader(CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx");
Map<String, PropertyDescriptor> map = BeanUtil.getPropertyDescriptorMap(tClass, false);
// 根据用户传入字段
Set<String> includeColumnFiledNames = map.keySet();
ExcelWriterSheetBuilder builder = EasyExcel.write(response.getOutputStream(), tClass)
//自动列宽
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.includeColumnFiledNames(includeColumnFiledNames)
.autoCloseStream(Boolean.FALSE)
.sheet(title);
if (CollectionUtils.isNotEmpty(includeColumnFiledNames)) {
builder.excludeColumnFiledNames(excludeColumnFiledNames);
}
builder.doWrite(list);
}
public static void writeError(HttpServletResponse response, WrapperResponse<?> resp) throws IOException {
// 重置response
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println(resp.getClass());
}
/**
* 大数据导出
* 分页写入到excel
*
* @param biFunction 分页遍历时的回调函数
* @param response HttpServletResponse
* @param sheetName 标题
* @param pojoClass 导出类型
* @param pageSize 每页大小
* @param total 总数
* @param <R> 导出类型
* @param <U> 查询结果类型
* @throws IOException IOException
*/
public static <R, U> void exportPageExcel(BiFunction<Integer, Integer, List<U>> biFunction, HttpServletResponse response, String sheetName, Class<R> pojoClass, int pageSize, int total) throws IOException {
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode(sheetName, CHARACTER).replaceAll("\\+", "%20");
ServletOutputStream out = response.getOutputStream();
//设置字符集为utf-8
response.setCharacterEncoding(CHARACTER);
response.setContentType(CONTENT_TYPE);
//通知浏览器服务器发送的数据格式
response.setHeader(CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx");
//发送一个报头,告诉浏览器当前页面不进行缓存,每次访问的时间必须从服务器上读取最新的数据
response.setHeader(CACHE_CONTROL, NO_STORE);
response.addHeader(CACHE_CONTROL, MAX_AGE);
// 这里 需要指定写用哪个class去写
Map<String, PropertyDescriptor> map = BeanUtil.getPropertyDescriptorMap(pojoClass, false);
Set<String> includeColumnFiledNames = map.keySet();
ExcelWriter excelWriter = EasyExcel.write(out, pojoClass).includeColumnFiledNames(includeColumnFiledNames).build();
// 这里注意 如果同一个sheet只要创建一次
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
//总页数
int pageAll = total / pageSize + (total % pageSize != 0 ? 1 : 0);
//通过parallel 并行 遍历1到pageAll
Stream.iterate(1, item -> item + 1).limit(pageAll).parallel()
.map(pageNo -> biFunction.apply(pageNo, pageSize))
.forEachOrdered(excelList -> {
//forEachOrdered 按照原始数据的顺序遍历excelList,
//将每个excelList 依次写入excel
excelWriter.write(excelList, writeSheet);
});
// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
out.flush();
}
}
Easyexcel excel导出工具包 (正常导出、大数据导出)
于 2022-08-22 14:27:34 首次发布