网站毕业设计一般做几个页面,可以做任务的网站有哪些,扬中人才市场最新招聘,品牌传播策划方案今天接到一个优化需求#xff0c;表格导出后的表头顺序和页面不一致#xff0c;要优化成一致的。根据传入的字段#xff0c;动态导出数据#xff0c;并保证顺序。 我看到导出的实体类都有ExcelProperty注解#xff0c;同时也在官网查看了这注解的含义和使用。
ExcelPrope…今天接到一个优化需求表格导出后的表头顺序和页面不一致要优化成一致的。根据传入的字段动态导出数据并保证顺序。 我看到导出的实体类都有ExcelProperty注解同时也在官网查看了这注解的含义和使用。
ExcelProperty有两个属性可以帮我们排序index和order所以我就想每次在去写excel的时候对映射类字段的index去动态排序。 注意index的使用
index的值相同时会抛出异常index的值不连续时会插入空白列
然后想直接用反射动态修改index /**** param headList 前端上送的动态表头* param clazz 导出实体类的class对象*/private static void handleExcelHead(ListString headList, Class? clazz) {try {for (String excelHead : headList) {Field declaredField clazz.getDeclaredField(excelHead);ExcelProperty annotation declaredField.getAnnotation(ExcelProperty.class);InvocationHandler invocationHandler Proxy.getInvocationHandler(annotation);Field field invocationHandler.getClass().getDeclaredField(memberValues);field.setAccessible(true);MapString, Object memberValues (MapString, Object) field.get(invocationHandler);memberValues.put(index, headList.indexOf(excelHead));}}catch (Exception e){e.printStackTrace();}}完整代码如下
public class Test {public static void main(String[] args) throws Exception {ListString headList new ArrayList();headList.add(name);headList.add(sex);headList.add(age);// 动态处理表头handleExcelHead(headList,User.class);EasyExcel.write(test.xlsx).head(User.class).sheet(test).includeColumnFiledNames(headList).doWrite(init());}/**** param headList 前端上送的动态表头* param clazz 导出实体类的class对象*/private static void handleExcelHead(ListString headList, Class? clazz) {try {for (String excelHead : headList) {Field declaredField clazz.getDeclaredField(excelHead);ExcelProperty annotation declaredField.getAnnotation(ExcelProperty.class);InvocationHandler invocationHandler Proxy.getInvocationHandler(annotation);Field field invocationHandler.getClass().getDeclaredField(memberValues);field.setAccessible(true);MapString, Object memberValues (MapString, Object) field.get(invocationHandler);memberValues.put(index, headList.indexOf(excelHead));}}catch (Exception e){e.printStackTrace();}}private static ListUser init() {ListUser userList new ArrayList();for (int i 0; i 10; i) {User user new User();user.setName(testi);user.setSex(男);user.setAge(20 i);userList.add(user);}return userList;}
}代码运行后发现和预期结果一样。但是当我则调整表头顺序并增加表头后发现不生效了。后来debug发现由于使用的是class对象只要这个jvm不重启或者这个对象不被回收修改的index就一直存在所以我们每次应该把index恢复成默认值。但是发现还是不行。后来在想这框架应该是使用了缓存吧毕竟导出实体是固定的。果然
ClassUtils 这里使用了缓存 public static final MapClass?, FieldCache FIELD_CACHE new ConcurrentHashMap();private static FieldCache declaredFields(Class? clazz) {if (clazz null) {return null;}return FIELD_CACHE.computeIfAbsent(clazz, key - {ListField tempFieldList new ArrayList();Class? tempClass clazz;// When the parent class is null, it indicates that the parent class (Object class) has reached the top// level.while (tempClass ! null) {Collections.addAll(tempFieldList, tempClass.getDeclaredFields());// Get the parent class and give it to yourselftempClass tempClass.getSuperclass();}// Screening of fieldMapInteger, ListField orderFieldMap new TreeMapInteger, ListField();MapInteger, Field indexFieldMap new TreeMapInteger, Field();MapString, Field ignoreMap new HashMapString, Field(16);ExcelIgnoreUnannotated excelIgnoreUnannotated clazz.getAnnotation(ExcelIgnoreUnannotated.class);for (Field field : tempFieldList) {declaredOneField(field, orderFieldMap, indexFieldMap, ignoreMap, excelIgnoreUnannotated);}return new FieldCache(buildSortedAllFieldMap(orderFieldMap, indexFieldMap), indexFieldMap, ignoreMap);});}这下难住我了这个缓存也不刷新。后来想他把缓存放在map里key是Class我直接每次都给他remove不就可以了。加了一行代码放在处理表头前边果然可行
ClassUtils.FIELD_CACHE.remove(User.class);