自定义注解导出excel数据

自定义注解导出excel数据

利用自定义注解方式,对数据列表进行简单的导出操作。即在实体对象的属性域上添加导出标识的注解,在对实体进行导出时,利用自定义注解进行反射的方法,获取实体需要导出的属性及值。该导出功能由于进行了封装,所以只适用于简单的excel导出功能,如需对导出的excel进行格式上的美化或合并单元格之类的操作,则本功能未进行实现。

优点:

1、由于使用了自定义注解,在导出时,只需要给接口传实体对象类和数据的list以及一些条件参数即可,使用起来简单易懂。
2、由于对导出excel方法进行了封装,所以导出时不用在进行繁琐的excel表格代码的编写了。
3、使用自定义注解的方式进行方法的封装,可根据业务需要进行自定义注解的扩展,满足业务需求,即具有可扩展性。
4、自定义注解中封装了一个数组属性,用来进行导出对象属性的分组,如系统中不同页面显示的对象属性不同,这时可以根据需要进行属性的分组,在导出时传入分组的参数,对应导出分组的属性值。

缺点:

1、导出的excel表格样式比较单一简单,暂时不支持合并单元格、添加表格特殊样式功能。

部分代码介绍:

1、ExcelField.java自定义注解类介绍:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {

    /**
     * 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”)
     */
    String value() default "";

    /**
     * 导出字段标题(需要添加批注请用“**”分隔,标题**批注,仅对导出模板有效)
     */
    String title();

    /**
     * 字段类型(0:导出导入;1:仅导出;2:仅导入)
     */
    int type() default 0;

    /**
     * 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右)
     */
    int align() default 0;

    /**
     * 导出字段字段排序(升序)
     */
    int sort() default 0;

    /**
     * 如果是字典类型,请设置字典的type值
     */
    String dictType() default "";

    /**
     * 反射类型
     */
    Class<?> fieldType() default Class.class;

    /**
     * 字段归属组(根据分组导出导入)
     */
    int[] groups() default {};
}

2、导出excel类代码简单介绍:

/**
     * 构造函数
     * @param title 表格标题,传“空值”,表示无标题
     * @param cls 实体对象,通过annotation.ExportField获取标题
     * @param type 导出类型(1:导出数据;2:导出模板)
     * @param groups 导入分组
     */
    public ExportExcel(String title, Class<?> cls, int type, int... groups){
        // Get annotation field 
        Field[] fs = cls.getDeclaredFields();
        for (Field f : fs){
            ExcelField ef = f.getAnnotation(ExcelField.class);
            if (ef != null && (ef.type()==0 || ef.type()==type)){
                if (groups!=null && groups.length>0){
                    boolean inGroup = false;
                    for (int g : groups){
                        if (inGroup){
                            break;
                        }
                        for (int efg : ef.groups()){
                            if (g == efg){
                                inGroup = true;
                                annotationList.add(new Object[]{ef, f});
                                break;
                            }
                        }
                    }
                }else{
                    annotationList.add(new Object[]{ef, f});
                }
            }
        }
        // Get annotation method
        Method[] ms = cls.getDeclaredMethods();
        for (Method m : ms){
            ExcelField ef = m.getAnnotation(ExcelField.class);
            if (ef != null && (ef.type()==0 || ef.type()==type)){
                if (groups!=null && groups.length>0){
                    boolean inGroup = false;
                    for (int g : groups){
                        if (inGroup){
                            break;
                        }
                        for (int efg : ef.groups()){
                            if (g == efg){
                                inGroup = true;
                                annotationList.add(new Object[]{ef, m});
                                break;
                            }
                        }
                    }
                }else{
                    annotationList.add(new Object[]{ef, m});
                }
            }
        }
        // 根据自定义注解中的sort进行排序
        Collections.sort(annotationList, new Comparator<Object[]>() {
            public int compare(Object[] o1, Object[] o2) {
                return new Integer(((ExcelField)o1[0]).sort()).compareTo(
                        new Integer(((ExcelField)o2[0]).sort()));
            };
        });
        // Initialize
        List<String> headerList = Lists.newArrayList();
        for (Object[] os : annotationList){
            String t = ((ExcelField)os[0]).title();
            // 如果是导出,则去掉注释
            if (type==1){
                String[] ss = StringUtils.split(t, "**", 2);
                if (ss.length==2){
                    t = ss[0];
                }
            }
            headerList.add(t);
        }
        initialize(title, headerList);
    }

3、调用该接口代码介绍:

 String fileName = "银行列表"+DateUtils.getDate("yyyyMMddHHmmss")+"."+fileType;
 //分页查询导出数据
 Page<InvestorBankCard> page = bankCardService.findPage(new Page<InvestorBankCard>(request, response, -1), investorBankCard);
//调用导出方法进行excel表格导出
new ExportExcel("银行卡数据", InvestorBankCard.class).setDataList(page.getList()).write(response, fileName);
            return null;

总结

自定义注解可以灵活的对代码进行封装使用,通过本次excel表格数据的功能开发,对自定义注解有了一些新的认识,在一些特定的场景,使用自定义注解可以节省很大的代码量,并且具有重用性。避免大量的重复代码。由于导出涉及的excel表格比较简单,所以该功能还需要在进行完善,至少需要支持单元格的合并及一些表格样式或字体样式的设置,待后续业务需要或有空余时间在进行完善。
完整工程代码已打包上传到svn上了,如有需要可以点击以下链接进行下载:https://download.csdn.net/download/songyou05/10634062,对代码如有疑问,可加QQ:734108708进行沟通交流。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java注解是一种元数据,它可以为类、方法、字段等元素添加额外的信息。在Java中,可以使用自定义注解和反射来实现导入导出Excel文档。 首先,定义一个自定义注解,用于标记需要导出的实体类的字段: ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ExcelField { /** * 列名 */ public String name(); /** * 顺序 */ public int order(); } ``` 然后,在实体类的字段上添加该注解: ```java public class User { @ExcelField(name = "姓名", order = 1) private String name; @ExcelField(name = "年龄", order = 2) private int age; // 省略其他字段和方法 } ``` 接着,定义一个工具类,用于读取和写入Excel文档: ```java public class ExcelUtil { /** * 从Excel中读取数据 */ public static <T> List<T> readFromExcel(InputStream is, Class<T> clazz) { List<T> list = new ArrayList<>(); try { Workbook workbook = WorkbookFactory.create(is); Sheet sheet = workbook.getSheetAt(0); Map<Integer, String> headers = getHeaders(sheet.getRow(0)); for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); T obj = clazz.newInstance(); for (int j = 0; j < row.getLastCellNum(); j++) { Cell cell = row.getCell(j); String value = getValue(cell); String fieldName = headers.get(j); Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); setValue(obj, field, value); } list.add(obj); } } catch (Exception e) { e.printStackTrace(); } return list; } /** * 写入数据Excel中 */ public static <T> void writeToExcel(List<T> list, OutputStream os) { try { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); Row header = sheet.createRow(0); Map<String, Integer> fields = getFields(list.get(0).getClass()); List<String> fieldNames = new ArrayList<>(fields.keySet()); Collections.sort(fieldNames); for (int i = 0; i < fieldNames.size(); i++) { String fieldName = fieldNames.get(i); Cell cell = header.createCell(i); cell.setCellValue(fields.get(fieldName)); } for (int i = 0; i < list.size(); i++) { Row row = sheet.createRow(i + 1); T obj = list.get(i); for (int j = 0; j < fieldNames.size(); j++) { String fieldName = fieldNames.get(j); Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); Object value = field.get(obj); Cell cell = row.createCell(j); cell.setCellValue(value.toString()); } } workbook.write(os); } catch (Exception e) { e.printStackTrace(); } } /** * 获取Excel中的列名 */ private static Map<Integer, String> getHeaders(Row row) { Map<Integer, String> headers = new HashMap<>(); for (int i = 0; i < row.getLastCellNum(); i++) { Cell cell = row.getCell(i); String value = getValue(cell); headers.put(i, value); } return headers; } /** * 获取实体类中的字段名和顺序 */ private static <T> Map<String, Integer> getFields(Class<T> clazz) { Map<String, Integer> fields = new HashMap<>(); Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { if (field.isAnnotationPresent(ExcelField.class)) { ExcelField excelField = field.getAnnotation(ExcelField.class); fields.put(field.getName(), excelField.order()); } } return fields; } /** * 设置实体类中的字段值 */ private static <T> void setValue(T obj, Field field, String value) throws Exception { String typeName = field.getType().getName(); if ("int".equals(typeName)) { field.set(obj, Integer.parseInt(value)); } else if ("java.lang.String".equals(typeName)) { field.set(obj, value); } // 省略其他类型的判断 } /** * 获取单元格中的值 */ private static String getValue(Cell cell) { String value = ""; if (cell != null) { switch (cell.getCellType()) { case STRING: value = cell.getStringCellValue(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); value = new SimpleDateFormat("yyyy-MM-dd").format(date); } else { value = String.valueOf(cell.getNumericCellValue()); } break; case BOOLEAN: value = String.valueOf(cell.getBooleanCellValue()); break; case FORMULA: value = String.valueOf(cell.getCellFormula()); break; default: value = ""; } } return value; } } ``` 最后,可以使用该工具类来读取和写入Excel文档: ```java public class Main { public static void main(String[] args) { // 从Excel中读取数据 try (InputStream is = new FileInputStream("users.xlsx")) { List<User> list = ExcelUtil.readFromExcel(is, User.class); for (User user : list) { System.out.println(user.getName() + ", " + user.getAge()); } } catch (Exception e) { e.printStackTrace(); } // 写入数据Excel中 List<User> list = new ArrayList<>(); list.add(new User("张三", 20)); list.add(new User("李四", 30)); list.add(new User("王五", 40)); try (OutputStream os = new FileOutputStream("users.xlsx")) { ExcelUtil.writeToExcel(list, os); } catch (Exception e) { e.printStackTrace(); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值