阿里巴巴 Excel工具easyExcel 导出
最近有个需要要求既要动态列扩展、又要列和数据对应。最重要的是一定要通用,满足当前项目的需求
无实体兼容实体对象动态列扩展。
1、实体类
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
/**
* 活动用户奖品 导出视图对象
* @date 2022/10/19 下午3:20
*/
@HeadFontStyle(fontHeightInPoints = 14)
@ExcelIgnoreUnannotated
public class ActivityUserPrizeVO {
@ExcelProperty("用户ID")
private String userId;
@ExcelProperty("用户昵称")
private String userName;
@ExcelProperty("中奖时间")
private String winningTime;
2、模版对象
/**
* 文件编写导出模版对象
* @date 2022/10/10 下午5:02
*/
public class ExcelExportWriter {
/**
* 文件名称
*/
private String fileName;
/**
* sheet 名称数组
*/
private List<String> sheets;
/**
* 是否启用 头部Excel属性。
* 如果使用,则会读取 class对象注解 ExcelProperty 属性值。
* 不启用:则会根据heads 动态对列名称去便利
*/
private Boolean headPropertyFlag=Boolean.FALSE;
/**
* 头部属性class
*/
private Class headPropertyClass;
/**
* 动态列名称
* 描述:
* 第一个List 代表:sheet 列表集合
* 第二个List 代表:表体行数据(集合)
* 第三个list 代表:表体列数据(集合)
*/
private List<List<List<String>>> heads;
/**
* 数据对象
* 1、对象写:根据对象固定字段写(分为三层)
* 第二个List 代表:表体行数据(集合)
* 第三个对象(class) 对象
* List<ActivityUserPrizeVO>
*
* 2、无对象写(动态表体数据) 分为三层
* 第一个List 代表:表体行数据(集合)
* 第二个list 代表:表体列数据(集合)
* List<List<Object>>
*/
private Collection<?> datas;
3、导出工具
protected void excelExportFile(HttpServletResponse response, ExcelExportWriter excelExport) throws SaasException {
try {
if (Objects.isNull(excelExport)) {
throw new SaasException(ErrorCode.E9999997);
}
setExportResponseHeader(excelExport.getFileName(), response);
ExcelWriter writer = null;
//是否启用头部属性、头部属性类不能为空
if (Objects.nonNull(excelExport.getHeadPropertyFlag()) && excelExport.getHeadPropertyFlag() && Objects.nonNull(excelExport.getHeadPropertyClass())) {
writer=EasyExcel.write(response.getOutputStream(),excelExport.getHeadPropertyClass()).build();
}else {
writer= EasyExcel.write(response.getOutputStream()).build();
}
int sheetNum = 0;
if (CollectionUtils.isNotEmpty(excelExport.getSheets())){
sheetNum=excelExport.getSheets().size();
}else if (CollectionUtils.isNotEmpty(excelExport.getHeads())) {
sheetNum=excelExport.getHeads().size();
}else if (CollectionUtils.isNotEmpty(excelExport.getDatas())) {
sheetNum=excelExport.getDatas().size();
}
if (sheetNum == 0){
sheetNum=1;
}
for (int i = 0; i < sheetNum; i++) {
WriteSheet sheet = EasyExcel.writerSheet(i).build();
if (CollectionUtils.isNotEmpty(excelExport.getSheets())){
sheet.setSheetName(excelExport.getSheets().get(i));
}
if (CollectionUtils.isNotEmpty(excelExport.getHeads())){
sheet.setHead(excelExport.getHeads().get(i));
}
if (CollectionUtils.isNotEmpty(excelExport.getDatas())) {
writer.write((Collection<?>) ((List)excelExport.getDatas()).get(i), sheet);
}else {
writer.write((Collection<?>) null, sheet);
}
}
// 最后 finish
if (null != writer) {
writer.finish();
}
}catch (Exception e){
logger.error("export file error!", e);
throw new SaasException(ErrorCode.E9999999, e);
}
}
protected void setExportResponseHeader(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
// 设置响应头和保存文件名
response.setContentType("text/csv");
response.setContentType("application/csv;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + ".csv");
}