Excel通用类工具(二)

前言

上一篇中写到了用反射来处理类中的不用的属性,但是Excel的列名还得手动输入,这样还是比较麻烦的,今天这篇就利用自定义注解来解决手动传入列名的问题;其实很简单的,只需要在上一篇的基础上加一个类就可以了;
本篇所涉及的项目是在上一篇 Excel通用类工具(一) 的项目代码上进行的二次添加;

正文

  1. 新添加一个类
    新添加一个注解类 ExcelName ,完整代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelName {
    String name() default "";
}

这个类主要就是一个注解,对java的注解还不了解的可以点击这里 传送门,因为只需要知道每个属性得列名,所以只定义了一个属性name,该属性的值就是列名;

  1. 改造实体类 pojoA 和 pojoB ,这一只改造一个类:
    pojoA

public class PojoA {
    @ExcelName(name = "名称")
    private String name;
    @ExcelName(name = "数量")
    private int num;
    @ExcelName(name = "价格")
    private double price;
    //省略set/get
}

只需要在每个属性上添加上边的注解就可以了;

  1. 对核心代码进行改造
    改造的代码不多,主要是将类中属性上的注解的值读取出来,放入列名中:

public class ExcelUtil<T> {
    public HSSFWorkbook setExcel(String title, List<T> tList) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException {
        Field[] declaredFields = tList.get(0).getClass().getDeclaredFields();
//        1.创建Excel工作薄对象
        HSSFWorkbook workbook=new HSSFWorkbook();
//        2.创建Excel工作表对象
        HSSFSheet sheet=workbook.createSheet(title);
        HSSFRow row=null;
//        3.创建Excel工作表的第一行,并填充列名
        row=sheet.createRow(0);
        for (int i=0;i<declaredFields.length;i++){
            ExcelName excelName = declaredFields[i].getAnnotation(ExcelName.class);
            if(excelName!=null){
                if(excelName.name()!=null){
                    row.createCell(i).setCellValue(excelName.name());
                }
            }else {
                row.createCell(i).setCellValue("");
            }
        }
       /* for(int i=0;i<columnNames.length;i++){
            row.createCell(i).setCellValue(columnNames[i]);
        }*/
//        4.将数据填充至表格中
        for(int j=1;j<=tList.size();j++){
            T t= tList.get(j-1);
            row=sheet.createRow(j);
            for(int i=0;i<declaredFields.length;i++){
                // 通过反射获取属性值
                String fieldName = declaredFields[i].getName();
                String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                Method declaredMethod = t.getClass().getDeclaredMethod(getMethodName);
                //执行方法
                Object fieldValue = declaredMethod.invoke(t);
                //判断是否为空
                if(fieldValue!=null &&  !"".equals(fieldValue)){
                    //判断属性值类型
                    if(fieldValue instanceof Integer){
                        row.createCell(i).setCellValue(Integer.valueOf(fieldValue.toString()));
                    }else if(fieldValue instanceof Double){
                        row.createCell(i).setCellValue(Double.valueOf(fieldValue.toString()));
                    }else if(fieldValue instanceof Date){
                        row.createCell(i).setCellValue(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(fieldValue));
                    }else {
                       row.createCell(i).setCellValue(fieldValue.toString());
                    }
                }else {
                    row.createCell(i).setCellValue("");
                }
            }
        }
//       5 .自动设置列宽
        for (int i = 0; i < declaredFields.length; i++) {
            sheet.autoSizeColumn(i);
            sheet.setColumnWidth(i,sheet.getColumnWidth(i)*17/10);
        }
        return workbook;
    }
}

较上一篇笔记来说,主要添加的就是第三部的那一部分代码,而原来那部分就是注释了的那一部分,可以看一下有什么区别;还有就是最后添加了第五步的那一部分代码,需要提醒的是这部分代码需要在数据填充完了之后再调用;

  1. 测试类
    测试还是用上一篇的测试类,这里就不贴出来了;

总结

这篇笔记主要是在上一篇的基础上添加了自定义注解,对注解的了解也进一步加深,但还是有许多的不足之处;

posted @ 2018-11-11 00:00  guoyuchuan  阅读(148)  评论(0编辑  收藏  举报