POI实现通用导出Excel表格的工具(JAVA)

需求

一次在查看项目代码时,无意发现项目中一段导出excel文档的接口。但是导出写的很敷衍,就是纯人工导出差别不大。大概有五个类型集合的导出,每个类型都写了一个导出,整个类有2000多行代码。简直不能忍,于是就决定修改这部分代码。先搞个导出的工具类。四处查找之后 ,经过几次修改,最后成型。

引入jar包

        
            org.apache.poi
            poi
            3.9
        
        
            org.apache.poi
            poi-excelant
            3.9
        
        
            org.apache.poi
            poi-scratchpad
            3.9
        

自定义注解

实现导出的时候,我觉定采用注解的形式标注column name
,列宽 ,还有列顺序。等设置。

package com.xescm.whc.annotation;

import com.xescm.whc.utils.DateUtils;
import lombok.Data;

import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author huxingnan
 * @date 2018/3/2113:30
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ExcelColumn {
    String name() default "";//列名
    int index() default 0;//列的顺序
    short width() default 10;//列宽

//注解内部类 列的配置
    @Data
    class ExcellColumnConfig{

        private int index;//列顺序
        private short width;//列宽
        private String columnName;//列名
        private Field field;//对应属性
    }
// 转换器 ,本来可以设计一个接口的,但是目前能用,就没有这么设计。
    class CellDataConvertor{
        public static String convertor(Object o){
            if(o == null){return "";}

            if(o instanceof Date){
               return DateUtils.getDate2String(DateUtils.YYYY_MM_DD_HH_MM_SS,(Date) o);
            }
            if(o instanceof BigDecimal){
                return ((BigDecimal) o).toPlainString();
            }
            return o.toString();
        }
    }
}

工具实现

直接上代码

package com.xescm.whc.utils;

import com.xescm.whc.annotation.ExcelColumn;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 通用的 导出 Excel 文件
 * 需要配合 注解 ExcelColumn
 * @see ExcelColumn
 * @author huxingnan
 * @date 2018/3/21 13:14
 */
public class ExportBeanExcelUtil {

    /**
     *
     * @param dtoList 数据集合
     * @param type 数据类型
     * @param title 工作薄标题
     * @param  泛型类
     * @return HSSFWorkbook 对象
     */
    public static  HSSFWorkbook exportExcell(List dtoList,Class type,String title){
        //1.解析注解  属性名 和 列名
        List columnConfigList = processAnnotation(type);//
        //2. 按照指定顺序 对列进行排序
        columnConfigList = sortColumn(columnConfigList);
        //3.创建工作薄
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet(title);
        //4.初始化列宽 表头
        initTableHeader(sheet,columnConfigList);
        //5. 导出数据
        createTableBody(sheet,columnConfigList,dtoList);
        return wb;
    }


    /**
     * 根据 数据 集合 创建表体
     * @param sheet 工作薄对象
     * @param columnConfigArray 排序后的
     * @param dtoList 数据集合
     * @param  泛型
     */
    private static  void createTableBody(HSSFSheet sheet,   List columnConfigArray, List dtoList) {

        int lineNo = 1;
        HSSFRow row;
        HSSFCell cell;
        try {
            int size = columnConfigArray.size();
            for (T t : dtoList) {
                row = sheet.createRow(lineNo++);
                for (int i = 0; i < size; i++) {
                    cell = row.createCell(i);
                    ExcelColumn.ExcellColumnConfig excellColumnConfig = columnConfigArray.get(i);
                    Field field = excellColumnConfig.getField();
                    field.setAccessible(true);
                    Object cellData = field.get(t);//获取数据
                    String cellDataStr = ExcelColumn.CellDataConvertor.convertor(cellData);//转换数据
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    cell.setCellValue(cellDataStr);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 初始化 表头 设置列宽
     * @param sheet 工作薄 对象
     * @param columnConfigArray 排序后的
     */
    private static void initTableHeader(HSSFSheet sheet, List columnConfigArray) {
        HSSFRow row = sheet.createRow(0);
        int size = columnConfigArray.size();
        HSSFCell cell;
       for (int i = 0 ; i < size;i++){
           cell = row.createCell(i, HSSFCellStyle.ALIGN_CENTER);
           ExcelColumn.ExcellColumnConfig excellColumnConfig =  columnConfigArray.get(i);
           cell.setCellType(Cell.CELL_TYPE_STRING);
           cell.setCellValue(excellColumnConfig.getColumnName());
           short width = excellColumnConfig.getWidth();
           sheet.setColumnWidth(i,width*256);
       }
    }

    /**
     * 解析 注解
     * @param type Class
     * @return columnConfig 集合
     */
    private static List processAnnotation(Class type){
        Field[] fields = type.getDeclaredFields();
        List columnConfigList  = new ArrayList<>();
        for (Field field : fields) {
            ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
            if(annotation != null){
                //列顺序
                int index = annotation.index();
                //列宽度
                short width = annotation.width();
                //当前列名
                String name = annotation.name().equals("")?field.getName():annotation.name();
                ExcelColumn.ExcellColumnConfig excellColumnConfig = new ExcelColumn.ExcellColumnConfig();
                excellColumnConfig.setColumnName(name);
                excellColumnConfig.setField(field);
                excellColumnConfig.setIndex(index);
                excellColumnConfig.setWidth(width);
                columnConfigList.add(excellColumnConfig);
            }
        }
        return columnConfigList;

    }

    /**
     * 排序列 按照 columnConfig 中的index 排序
     *
     * @param columnConfigList columnCofig集合
     * @return columnConfig 排序后的
     */
    private static List sortColumn(List columnConfigList){
        Collections.sort(columnConfigList,new Comparator() {
            @Override
            public int compare(ExcelColumn.ExcellColumnConfig o1, ExcelColumn.ExcellColumnConfig o2) {
                return o1.getIndex()-o2.getIndex();
            }
        });

        return columnConfigList;
    }
}

用例

package com.xescm.whc.domain;

import com.xescm.whc.annotation.ExcelColumn;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 库存冻结单
 */
@Data
public class WhcFrozen implements Serializable {

    private static final long serialVersionUID = 1826699766249042796L;

    /**
     * 冻结单号
     */
    @ExcelColumn(name = "冻结单号")
    private String holdOrderCode;

    /**
     * 批次号
     */
    @ExcelColumn(name = "批次号")
    private String lotNum;

    /**
     * 库位
     */
     //默认的index = 0 
    @ExcelColumn(name = "库位" index='-1')
    private String locationCode;

}

你可能感兴趣的:(POI实现通用导出Excel表格的工具(JAVA))