透视表的操作直接使用原生POI接口较为复杂,于是我这里用注解的方式封装了一个可复用的方法。
1.注解实现
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author dhh
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface PivotTableFiled {
String header();
/* 标记该属性在透视表中的位置 */
PivotTableArea area() default PivotTableArea.NOT_REQUIRED;
/* 透视表的别名 */
String aliasName() default "";
/* 值汇总方式 */
SummaryType summaryType() default SummaryType.COUNT;
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author dhh
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PivotTableTitle {
String title() default "透视表";
}
/**
* @author dhh
*/
public enum PivotTableArea {
/** 过滤器 **/
FILTER,
/** 列 **/
COL,
/** 行 **/
ROW,
/** 值 **/
COLUMN,
/** 未参与计算**/
NOT_REQUIRED
}
/**
* @author dhh
*/
public enum SummaryType {
/* 求和 */
SUM,
/* 计数 */
COUNT
}
以上注解和枚举类型用于标注实体类对应的属性需要放置在透视表的行,列还是值上。
2.注解解析
/**
* @param clazz
* @return
*/
public static Map<String, List<String>> getAliasNameFieldNameAndTitle(Class<?> clazz) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> headerList = new ArrayList<String>();
List<String> fieldList = new ArrayList<String>();
List<String> titleList = new ArrayList<String>();
Field[] fields = clazz.getDeclaredFields();
List<Field> fieldsByAnnotation = Arrays.stream(fields).filter(field -> field.getAnnotation(PivotTableFiled.class) != null)
.collect(Collectors.toList());
if (fieldsByAnnotation.isEmpty()) {
return map;
}
for (Field field : fieldsByAnnotation) {
PivotTableFiled pivotTableFiled = field.getAnnotation(PivotTableFiled.class);
if (pivotTableFiled != null) {
headerList.add(pivotTableFiled.header());
fieldList.add(field.getName());
}
}
PivotTableTitle title = clazz.getAnnotation(PivotTableTitle.class);
if (title != null) {
titleList.add(title.title());
} else {
titleList.add("透视表");
}
map.put(HEADER, headerList);
map.put(FIELD, fieldList);
map.put(TITLE, titleList);
return map;
}
/**
* 获取字段对应的label位置,该字段应该在列,行还是值上
*
* @param clazz
* @return
*/
public static List<PivotTableLabel> getLabel(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
List<PivotTableLabel> labels = new ArrayList<PivotTableLabel>();
List<Field> fieldsByAnnotation = Arrays.stream(fields).filter(field -> field.getAnnotation(PivotTableFiled.class) != null)
.collect(Collectors.toList());
for (int i = 0; i < fieldsByAnnotation.size(); i++) {
PivotTableFiled annotation = fieldsByAnnotation.get(i).getAnnotation(PivotTableFiled.class);
if (annotation != null) {
PivotTableLabel label = new PivotTableLabel();
label.setIndex(i);
label.setArea(annotation.area());
label.setSummerType(annotation.summaryType());
label.setAliasName(annotation.aliasName());
labels.add(label);
}
}
return labels;
}
此为工具类中的方法,用于解析实体类上的注解内容。如此便可省去数据库新建配置表等繁杂操作。