Excel导出公共组件设计

Posted shu_lin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Excel导出公共组件设计相关的知识,希望对你有一定的参考价值。

自己动手实现一个Excel导出公共组件!!!!文章主要分为以下几个部分来说明:

1、明确目标

2、技术预研

3、技术方案选型与方案设计

4、技术实施


下面是实现一个Excel导出模块的目标:

  • 通过自定义注解解析需要导出的Excel格式

  • 支持自定义日期显示格式

  • 支持是否显示自增列

  • 支持约定的属性的枚举转换(比如YWG->已完工)

  • 少量数据直接导出(5000条内)

  • 对于大数据量支持分页导出(支持全量数据导出,百万级)

  • 超大规模数据导出(千万级的数据量)


目标明确后就可以开始进行进行技术预研,对比了当前比较流行的三种开源Excel导出技术的特点:

  • JXL

    • 效率低,操作简单

    • 能够修饰单元格属性,格式支持不如POI强大

  • FastExcel

    • 采用纯java开发的excel文件读写组件,支持Excel 97-2003文件格式

    • 内存消耗小

    • 只读取字符信息,诸如颜色/字体等属性都不支持

  • POI

    • 效率高,操作相对复杂

    • 支持公式,宏,图像,图表

    • 支持修饰单元格属性;支持字体,数字,日期操作

    • 3.8版本的POI出来了SXSSFWorkbook,可以支持大数据量的操作,但只支持xlsx格式


Excel导出方式的调研:

  • 直接导出.xls(单表支持65532行)或者.xlsx(单表支持1048576行)后缀的excel文件

  • 导出.txt文件

  • 导出.csv文件

  • 导出.xml文件


技术选型:   

    综合之前的开源技术分析以及导出方式分析,结合自己的业务场景,直接导出Excel是比较好的选择(用户可以直接打开)。开源技术中,JXL可以直接排除,因为效率低;FastExcel其实还不错,内存消耗又小,但是不支持复杂的操作,扩展性不佳;而POI不仅效率高,且支持各种操作(便于未来未知的扩展需求,比如需要导出表格、图像呢?),同时也支持大数据量的操作,非常合适。Excel2007已经普及了,不存在打开的障碍。


技术方案设计:

  • 采用POI作为操作Excel的第三方库

  • 自定义注解,有列号,列名,日期格式化,枚举类型,自增序列

  • 注解解析,解析Excel导出的列和对应的字段

  • 数据解析,根据注解解析结果去解析每一行数据

  • 导出

    • 若数据量少(<5000条),直接全量导出

    • 若数据量大(范围[5000,1048576)),需要分批解析数据然后导出

    • 若数据量超大,超过了Excel2007的表行数限制(1048576),采用导出多份Excel或者多张sheet的方式


定义一个自定义注解,主要包含以下几个属性(序列号,列名,日期格式,枚举名称,是否自增)

  
  1. package com.shulin.winter.annotions;
  2. import java.lang.annotation.*;
  3. /**
  4. * Excel导出注解
  5. * Created by shulin on 16/12/25.
  6. */
  7. @Target(ElementType.FIELD, ElementType.TYPE)
  8. @Retention(RetentionPolicy.RUNTIME)
  9. @Documented
  10. public @interface ExlOut
  11.    /**
  12.     * 列序号,比如第1列是姓名,第2列是电话号码,第3列是地址
  13.     *
  14.     * @return
  15.     */
  16.    int colSeq();
  17.    /**
  18.     * 列名
  19.     *
  20.     * @return
  21.     */
  22.    String colName();
  23.    /**
  24.     * 日期类型格式化
  25.     *
  26.     * @return
  27.     */
  28.    String dateFormat() default "yyyy-MM-dd HH:mm:SS";
  29.    /**
  30.     * 枚举的名称
  31.     *
  32.     * @return
  33.     */
  34.    String enumName() default "";
  35.    /**
  36.     * 是否有自增序列
  37.     *
  38.     * @return
  39.     */
  40.    boolean autoIncrement() default false;

有了这个注解,接下来就是定义注解的解析工作,我们需要将一个使用了这个注解的类的注解表示的相关导出信息解析出来,比如需要导出哪几列,谁前谁后,列名是什么,是否有自增序列,是否需要进行枚举转化等。


在此之前我们先定义一个解析结果类来保存注解解析后的结果:

  
  1. package com.shulin.winter.annotions;
  2. import lombok.Getter;
  3. import lombok.Setter;
  4. /**
  5. * 解析注解后的对象
  6. * Created by shulin on 16/12/25.
  7. */
  8. @Setter
  9. @Getter
  10. public class ExlOutParseResult implements Comparable
  11.    private int colSeq;  //序列
  12.    private String colName;  //列名
  13.    private String fieldName;  //属性名称
  14.    private Class fieldType;    //属性类型
  15.    private String formatStr;   //日期格式
  16.    private Boolean autoIncrement;  //是否自增,全局属性
  17.    private String enumName;     //枚举名
  18.    private String enumMethod;    //枚举方法
  19.    @Override
  20.    public int compareTo(Object o)
  21.        ExlOutParseResult tmp = (ExlOutParseResult) o;
  22.        if (colSeq < tmp.colSeq)
  23.            return -1;
  24.         else if (colSeq > tmp.colSeq)
  25.            return 1;
  26.         else
  27.            return 0;
  28.        
  29.    


接下来就是对一个被注解的类进行解析的过程了:

  
  1. package com.shulin.winter.annotions;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Component;
  4. import java.lang.annotation.Annotation;
  5. import java.lang.reflect.Field;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * Created by shulin on 16/12/25.
  10. */
  11. @Component
  12. @Slf4j
  13. public class ExlOutParser 以上是关于Excel导出公共组件设计的主要内容,如果未能解决你的问题,请参考以下文章

    Vue封装一个导出Excel的组件或公共函数

    偷懒小工具 - Excel导出公共类

    POI导出复杂的excel;excel公共样式类;excel拼接定制类;数据科学计数法转为普通值

    Java开源平台二次开发教程:开源数据网格的Excel导入导出功能

    原PHPExcel导出Excel

    Java通过FreeMarker作为模板导出Excel