表单数据通用导出Excel
1、自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAttribute {
String name() default "";
int sort();
Class<? extends ExportTypeHandler> typeHandler() default ExportTypeHandler.class;
}
2、自定义类型格式化Handler
import java.util.Date;
import java.util.Objects;
public class DateTypeHandler implements ExportTypeHandler{
private static final String DATE_FORMAT = "yyyy-MM-dd";
@Override
public String getValue(Object value) throws Exception {
if (Objects.isNull(value) || !(value instanceof Date)) {
return "";
} else {
return DateUtils.format((Date) value, DATE_FORMAT);
}
}
}
3、导出方法实现
private static final Map<Class<? extends ExportTypeHandler>, ExportTypeHandler> TYPE_HANDLER_MAP = new HashMap<>();
private static final String ROW_NUMBER = "rowNum";
private static final String ROW_NUMBER_ALIAS = "序号";
/**
* 导出Excel
* @param request
* @param response
* @param title
* @param records
*/
public void exportExcel(HttpServletRequest request, HttpServletResponse response, String title, List<T> records) {
ExcelSource<Map<String, Object>> excelSource = new ExcelSource<>();
// excel 文件名称
excelSource.setExcelName(title);
// excel sheet名称
excelSource.setSheetName(title);
// excel表头组装
Map<String, String> headerMap = new LinkedHashMap<>();
Map<Integer, ExcelFieldDTO> fieldAliasMap = new HashMap<>();
List<Map<String, Object>> data = new ArrayList<>();
// 初始化行号
int row = 1;
if (CollectionUtils.isNotEmpty(records)) {
for (T record : records) {
Map<String, Object> rowDataMap = new LinkedHashMap<>();
rowDataMap.put(ROW_NUMBER, String.valueOf(row));
if (row == 1) {
ExcelFieldDTO alias = new ExcelFieldDTO();
alias.setField(ROW_NUMBER);
alias.setAlias(ROW_NUMBER_ALIAS);
fieldAliasMap.put(0, alias);
}
Field[] fields = record.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (field.isAnnotationPresent(ExcelAttribute.class)) {
ExcelAttribute attribute = field.getAnnotation(ExcelAttribute.class);
if (row == 1) {
ExcelFieldDTO fieldAlias = new ExcelFieldDTO();
fieldAlias.setField(field.getName());
fieldAlias.setAlias(attribute.name());
fieldAliasMap.put(attribute.sort(), fieldAlias);
}
// 获取原值
field.setAccessible(true);
Object value = null;
try {
value = field.get(record);
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
}
if (Objects.nonNull(attribute.typeHandler().getSuperclass()) && attribute.typeHandler().getSuperclass().isAssignableFrom(ExportTypeHandler.class)) {
// 重新赋值
rowDataMap.put(field.getName(), getValue(value, attribute.typeHandler()));
} else {
rowDataMap.put(field.getName(), value);
}
}
}
// 行号加1
row++;
// 添加行数据
data.add(rowDataMap);
}
fieldAliasMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(x -> headerMap.put(x.getValue().getField(), x.getValue().getAlias()));
excelSource.setMergeHead(title);
excelSource.setHeaderMap(headerMap);
excelSource.setDataList(data);
ExcelEnhanceHelper.exportExcel(request, response, excelSource);
}
}
/**
* 获取格式化后的值
*
* @param value
* @param aClass
* @return
*/
private static Object getValue(Object value, Class<? extends ExportTypeHandler> aClass) {
if (Objects.isNull(value)) {
value = "";
} else {
ExportTypeHandler typeHandler;
try {
if (TYPE_HANDLER_MAP.containsKey(aClass)) {
typeHandler = TYPE_HANDLER_MAP.get(aClass);
} else {
//如果TYPE_HANDLER_MAP内没有该class的实力 则通过反射创建一个并存入
typeHandler = aClass.newInstance();
TYPE_HANDLER_MAP.put(aClass, typeHandler);
}
//调用方法获得类型对应的value
value = typeHandler.getValue(value);
} catch (Exception e) {
log.error("ExportTypeHandler转换失败,value:{},失败异常:", value, e);
}
}
return value;
}
4、导出实体添加ExcelAttribute注解
@Data
public class PersonDTO {
/**
* 名称
*/
@ExcelAttribute(name = "名称", sort = 1)
private String name;
/**
* 年龄
*/
@ExcelAttribute(name = "年龄", sort = 2)
private Integer age;
/**
* 生日
*/
@ExcelAttribute(name = "生日", sort = 3, typeHandler = DateTypeHandler.class)
private Date birthday;
}
ExcelAttribute
注解的name
属性指定字段别名,通过sort
属性指定字段先后顺序,若字段需要格式化通过typeHandler
属性指定要格式化的类,已经提供DateTypeHandler
,扩展需实现ExportTypeHandler
接口
5、导出调用
public void exportExcel(HttpServletRequest request, HttpServletResponse response, PageParam param) {
List<PersonDTO> list = baseMapper.queryList(param);
exportExcel(request, response, "XXXX", list);
}
标签: 自定义注解