zoukankan      html  css  js  c++  java
  • 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. 测试类
      测试还是用上一篇的测试类,这里就不贴出来了;

    总结

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

  • 相关阅读:
    Nginx 的 server_names_hash_bucket_size 问题
    Linux 查看CPU信息、机器型号等硬件信息
    JS中的prototype[转载]
    memcache适用和不适用场景[转载]
    php的socket通信【转载】
    fastcgi与cgi的区别[转载]
    PHP类和对象
    SVN的配置和使用
    PHP_pear的安装和使用
    [转]Python tips: 什么是*args和**kwargs?
  • 原文地址:https://www.cnblogs.com/guoyuchuan/p/9941120.html
Copyright © 2011-2022 走看看