基于注解的Excel多Sheet数据导出/导入

目录

介绍

代码

jar pom

注解

工具类

Sheet页设置

BaseBean/ResultForm说明

使用流程示例

Excel模板导出及导入解析

Excel导入工具类

使用流程示例


介绍

Excel导出是我们在项目中经常使用到的功能,市面上成熟的导出工具包用起来比较的繁琐,而且定制化不高,在我们想自己编写一些特殊功能时不太好用,因此决定自己写一个简单的基于注解的Excel多Sheet导出。

在设计Excel导出@ExcelField注解之前,我们项目中也是用到了Swagger工具注解,上面包含了字段的说明标题,因此在编写自定义注解时省略了标题属性,通过直接获取swagger的@ApiModelProperty的字段说明来获取字段的标题,小伙伴们可以通过自己添加@ExcelField注解的自定义属性来替代。

代码

jar pom

本导出工具类是基于阿帕奇的POI5.1.1版本,pom jar描述如下:



    org.apache.poi
    poi
    5.1.0

使用流程为在导出实体类上添加导出注解@ExcelField,设置是否导出数据,或是否是模板导出属性,之后调用下载发放即可,上代码

注解

package com.pride.sun.common;

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

/**
 * Excel自定义注解
 *
 * @author lpw
 * @date 2020-04-19
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelFiled {

    /**
     * 是否是导出属性
     *
     * @return
     */
    boolean isExport() default true;

    /**
     * 是否是导入属性
     *
     * @return
     */
    boolean isImport() default true;

    /**
     * 是否是父ID属性
     *
     * @return
     */
    boolean isPId() default false;

}

工具类

package com.pride.sun.common;

import com.pride.sun.base.BaseBean;
import com.pride.sun.result.ResultForm;
import io.swagger.annotations.ApiModel;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.minbox.framework.web.response.ResponseWrapper;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Excel工具类
 *
 * @param 
 * @author lpw
 */

public class ExcelUtils {


    /**
     * 行高
     */
    private int rowHeight = 400;

    /**
     * 列宽
     */
    private int colWidth = 3000;

    /**
     * 工作页
     */
    private Workbook workbook = new HSSFWorkbook();

    /**
     * 默认标题
     */
    private String defaultTitle;

    /**
     * sheet页集合
     */
    private List sheetList = new ArrayList<>();

    /**
     * Class类工具
     */
    private ClassUtils util = new ClassUtils();

    public ExcelUtils() {
    }

    public ExcelUtils(String title) {
        defaultTitle = title;
    }

    public ExcelUtils(int rowHeight, int colWidth, String title) {
        this.rowHeight = rowHeight;
        this.colWidth = colWidth;
        this.defaultTitle = title;
    }

    /**
     * 默认文档设置文档
     */

    private void initWorkbook() {
        if (CollectionUtils.isNotEmpty(sheetList)) {
            if (StringUtils.isEmpty(defaultTitle)) {
                defaultTitle = getDefaultTitle(sheetList.get(0));
            }
            sheetList.forEach(v -> {
                //设置默认标题行
                if (StringUtils.isEmpty(v.getSheetTitle())) {
                    v.setSheetTitle(getDefaultTitle(v));
                }
                v.parseFieldAnnotation();
                //    创建工作页
                v.setSheet(workbook.createSheet(v.getSheetTitle()));
                //    设置默认列宽
                v.getSheet().setDefaultColumnWidth(colWidth);
                //设置冻结行
                v.getSheet().createFreezePane(0, 2);
                //标题样式
                titleStyleSetting(v);
            });
        }
    }

    /**
     * 加载生成Excel
     *
     * @throws Exception
     */
    public ResultForm initAndDownload() throws Exception {
        initWorkbook();
        createExcel();
        downloadExcel();
        return new ResultForm(ResultForm.SUCCESS, "导出成功");
    }

    /**
     * 导出Excel
     *
     * @param dataList
     * @param 
     */
    public static  ResultForm exportExcel(List dataList, Class eClass) {
        return exportExcel(dataList, eClass, null);
    }

    /**
     * 导出Excel
     *
     * @param dataList
     * @param 
     */
    public static  ResultForm exportExcel(List dataList, Class eClass, String title) {
        try {
            if (eClass == null) {
                return new ResultForm("未指定类对象");
            }
            if (CollectionUtils.isNotEmpty(dataList)) {
                ExcelUtils excel = new ExcelUtils<>();
                excel.defaultTitle = title;
                excel.addSheet(eClass, title, dataList, false);
                return excel.initAndDownload();
            }
            return new ResultForm(ResultForm.TIP, "未查到需要导出的数据");
        } catch (Exception e) {
            return new ResultForm(e);
        }
    }


    /**
     * 下载模板
     *
     * @param eClass
     * @param 
     */
    public static  ResultForm downLoadModel(Class eClass) {
        return downLoadModel(eClass, null);
    }

    /**
     * 下载模板
     *
     * @param eClass
     * @param 
     */
    public static  ResultForm downLoadModel(Class eClass, String title) {
        try {
            if (eClass != null) {
                ExcelUtils excel = new ExcelUtils<>();
                excel.defaultTitle = title;
                excel.addSheet(eClass, title, null, true);
                return excel.initAndDownload();
            }
            return new ResultForm(ResultForm.ERROR, "类对象不能为空");
        } catch (Exception e) {
            return new ResultForm(e);
        }
    }

    /**
     * 添加sheet页
     *
     * @param eClass
     * @param sheetTitle
     * @param dataList
     * @param 
     */
    public  MySheet addSheet(Class eClass, String sheetTitle, List dataList, Boolean isDownLoad) {
        MySheet mySheet = new MySheet<>();
        mySheet.setSheetTitle(sheetTitle);
        mySheet.setSheetClass(eClass);
        mySheet.setDataList(dataList);
        mySheet.setDownloadMode(isDownLoad);
        sheetList.add(mySheet);
        return mySheet;
    }


    /**
     * 获取类标题
     *
     * @param mySheet
     * @return
     */
    private String getDefaultTitle(MySheet mySheet) {
        Annotation[] ans = mySheet.getSheetClass().getAnnotations();
        for (Annotation temp : ans) {
            if (temp instanceof ApiModel) {
                return ((ApiModel) temp).description();
            }
        }
        return null;
    }

    /**
     * 标题、列名相关设置
     */
    private void titleStyleSetting(MySheet mySheet) {
        List> colList = mySheet.getColList();
        Sheet sheet = mySheet.getSheet();
        Row topRow = createRow(mySheet, (short) 600);
        //合并标题行
        mergedRegion(sheet, 0, 0, 0, colList.size() - 1);
        //大标题样式
        CellStyle topCellStyle = createCellStyle();
        topCellStyle.setFont(createFont(null, (short) 0, (short) 0));
        topCellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());
        topCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Cell cell = createCell(topRow, 0, setBorder(topCellStyle));
        cell.setCellValue(mySheet.getSheetTitle());
        Row textRow = createRow(mySheet, (short) 0);
        //列头标题样式
        CellStyle titleCellStyle = createCellStyle();
        titleCellStyle.setFont(createFont(null, (short) 0, (short) 0));
        titleCellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //设置列样式
        for (int i = 0; i < colList.size(); i++) {
            Map fieldMap = colList.get(i);
            String colValue = String.valueOf(fieldMap.get("text"));
            sheet.setColumnWidth(i, getColumnWidth(colValue));
            Cell cell1 = createCell(textRow, i, setBorder(titleCellStyle));
            cell1.setCellValue(colValue);
            addColStyle(mySheet.getStyleList(), null, (short) 0, Short.parseShort(fieldMap.get("color").toString()));
        }
    }

    /**
     * 获取列宽
     *
     * @param value
     * @return
     */
    private Integer getColumnWidth(String value) {
        if (StringUtils.isNotEmpty(value)) {
            try {
                int byteNum = value.getBytes("GBK").length;
                int width = byteNum * 350;
                return width > colWidth ? width : colWidth;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return colWidth;
    }

    /**
     * 创建字体对象
     *
     * @param fontName 字体库名称
     * @param fontSize 字体大小-传0默认14
     * @return
     */
    private Font createFont(String fontName, short fontSize, short color) {
        Font font = workbook.createFont();
        if (StringUtils.isEmpty(fontName)) {
            fontName = "宋体";
        }
        if (fontSize == 0) {
            fontSize = (short) 12;
        }
        if (color == 0) {
            color = 0x08;
        }
        //设置为宋体字
        font.setFontName("宋体");
        //设置字体大小
        font.setFontHeightInPoints(fontSize);
        font.setColor(color);
        return font;
    }


    /**
     * 创建列样式
     *
     * @return
     */
    private CellStyle createCellStyle(short... alignments) {
        CellStyle style = workbook.createCellStyle();
        short alignment = HorizontalAlignment.CENTER_SELECTION.getCode(), vertical = VerticalAlignment.CENTER.getCode();
        if (alignments.length > 0) {
            alignment = alignments[0];
            if (alignments.length > 1) {
                vertical = alignments[1];
            }
        }
        //水平居中
        style.setAlignment(HorizontalAlignment.forInt(alignment));
        //垂直居中
        style.setVerticalAlignment(VerticalAlignment.forInt(vertical));
        return style;
    }

    /**
     * 合并行、列
     *
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     */
    private void mergedRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        if (firstRow > lastRow || firstCol > lastCol) {
            return;
        }
        //    合并行
        CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        sheet.addMergedRegion(region);
    }

    /**
     * 创建单元格
     *
     * @param row
     * @param index
     * @param style
     * @return
     */
    private Cell createCell(Row row, int index, CellStyle style) {
        Cell cell = row.createCell(index);
        if (style != null) {
            cell.setCellStyle(style);
        }
        return cell;
    }

    /**
     * 创建行
     *
     * @return
     */
    private Row createRow(MySheet mySheet, short rowHeight) {
        Row row = mySheet.getSheet().createRow(mySheet.getRowIndex());
        if (rowHeight == 0) {
            rowHeight = (short) this.rowHeight;
        }
        row.setHeight(rowHeight);
        mySheet.setRowIndex(mySheet.getRowIndex() + 1);
        return row;
    }

    /**
     * 创建每一列的样式
     *
     * @param fontName
     * @param fontSize
     * @param color
     * @param alignments
     */
    private void addColStyle(List styleList, String fontName, short fontSize, short color, short... alignments) {
        Font ft = createFont(fontName, fontSize, color);
        CellStyle style = createCellStyle(alignments);
        style.setFont(ft);
        styleList.add(style);
    }

    /**
     * 设置边线
     *
     * @param cellStyle
     */
    private CellStyle setBorder(CellStyle cellStyle) {
        if (cellStyle != null) {
            cellStyle.setBorderLeft(BorderStyle.THIN);
            cellStyle.setBorderBottom(BorderStyle.THIN);
            cellStyle.setBorderRight(BorderStyle.THIN);
            cellStyle.setBorderTop(BorderStyle.THIN);
            return cellStyle;
        }
        return null;
    }

    /**
     * 生成Excel表
     *
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    private void createExcel() throws Exception {
        if (CollectionUtils.isNotEmpty(sheetList)) {
            for (MySheet mySheet : sheetList) {
                List list = mySheet.getDataList();
                if (CollectionUtils.isNotEmpty(list)) {
                    List> colList = mySheet.getColList();
                    List styleList = mySheet.getStyleList();
                    for (Object temp : list) {
                        Row row = createRow(mySheet, (short) 0);
                        for (int i = 0; i < colList.size(); i++) {
                            Map cl = colList.get(i);
                            Cell cell = createCell(row, i, setBorder(styleList.get(i)));
                            String methodName = cl.get("methodName").toString();
                            Object obj = util.valueToGet(temp, methodName);
                            if (obj != null && !(obj instanceof Date)) {
                                cell.setCellValue(obj.toString());
                            } else if (obj != null) {
                                String format = (String) cl.get("dateFormat");
                                if (StringUtils.isNotEmpty(format)) {
                                    cell.setCellValue(DateUtil2.formatDate((Date) obj, format));
                                } else {
                                    cell.setCellValue(DateUtil2.formatDate((Date) obj, DateUtil2.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
                                }
                            } else {
                                cell.setCellValue("");
                            }
                        }
                    }
                }
            }
        }
    }

    private HttpServletResponse getResponse() {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        if (response instanceof ResponseWrapper) {
            response = (HttpServletResponse) ((ResponseWrapper) response).getResponse();
        }
        return response;
    }


    /**
     * 下载
     */
    private void downloadExcel() throws Exception {
        HttpServletResponse response = getResponse();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        OutputStream output = response.getOutputStream();
        response.reset();
        response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(defaultTitle, "UTF8") + ".xls");
        response.setContentType("application/msexcel");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        workbook.write(output);
        output.close();
    }


    class ClassUtils {

        private ClassUtils() {
        }


        /**
         * 反射获取value
         *
         * @param object
         * @return
         * @throws SecurityException
         * @throws NoSuchMethodException
         * @throws InvocationTargetException
         * @throws IllegalArgumentException
         * @throws IllegalAccessException
         */
        private Object valueToGet(Object object, String methodName) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            Method method = object.getClass().getDeclaredMethod(methodName);
            return method.invoke(object);
        }

    }

}

Sheet页设置

package com.pride.sun.common;

import com.alibaba.fastjson.annotation.JSONField;
import com.pride.sun.base.BaseBean;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Sheet;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 自定义Sheet封装类
 *
 * @author lpw
 * @date 2021-07-19
 */
@Data
public class MySheet {

    /**
     * sheet页
     */
    private Sheet sheet;

    /**
     * sheet页映射类
     */
    private Class sheetClass;

    /**
     * sheet标题
     */
    private String sheetTitle;

    /**
     * Sheet样式
     */
    private CellStyle cellStyle;

    /**
     * 起始位置
     */
    private int rowIndex = 0;

    /**
     * 列属性集合
     */
    private List> colList = new ArrayList<>();

    /**
     * 列样式集合
     */
    private List styleList = new ArrayList<>();


    /**
     * 是否是 下载导出模板
     */
    private boolean isDownloadMode = false;

    /**
     * sheet页数据
     */
    private List dataList;


    /**
     * 通过注解获取列相关注解属性
     */
    void parseFieldAnnotation() {
        Field[] fields = sheetClass.getDeclaredFields();
        for (Field temp : fields) {
            if (temp.isAnnotationPresent(ExcelFiled.class) && temp.isAnnotationPresent(ApiModelProperty.class)) {
                ExcelFiled excelFiled = temp.getAnnotation(ExcelFiled.class);
                //swagger注解用于获取字段标题,可替换
                ApiModelProperty api = temp.getAnnotation(ApiModelProperty.class);
                Map fieldMap = new HashMap<>();
                fieldMap.put("width", 6000);
                fieldMap.put("color", 0x08);
                fieldMap.put("text", api.value());
                fieldMap.put("methodName", "get" + convertMethodName(temp.getName()));
                //日期格式设置,这里采用了fastJson的日期注解判断,获取日期格式,可根据需要替换    
                 //到自定义注解ExcelField属性中
                if (temp.getType() == Date.class && temp.isAnnotationPresent(JSONField.class)) {
                    JSONField dateJsonField = temp.getAnnotation(JSONField.class);
                    if (StringUtils.isNotEmpty(dateJsonField.format())) {
                        fieldMap.put("dateFormat", dateJsonField.format());
                    }
                }
                //判断是否是下载Excel模板
                if (isDownloadMode && excelFiled.isImport()) {
                    colList.add(fieldMap);
                } else if (!isDownloadMode && excelFiled.isExport()) {
                    colList.add(fieldMap);
                }
            }
        }
    }

    /**
     * 首字母大写
     *
     * @param fieldName
     * @return
     */
    public String convertMethodName(String fieldName) {
        String newField = fieldName.substring(1);
        return fieldName.substring(0, 1).toUpperCase() + newField;
    }

}

BaseBean/ResultForm说明

其中BaseBean为项目中导出实体的公共父类,及通用属性都放置其中,可根据实际需要修改获去除。

ResultForm为项目中公共返回封装实体,也可根据实际需要去除。

单Sheet页使用流程示例:(sheet页标题默认为实体swagger实体注解,可根据需要修改)

使用流程示例

1,在实体上添加导出注解

基于注解的Excel多Sheet数据导出/导入_第1张图片

2.获取实体集合数据,调用工具导出方法,传入集合,导出实体类.class,Excel标题(可选)默认是swagger的实体注解说明。

 public ResultForm exportAuditedPlanExcel(T t) {
        List dataList= dao.selectList(t);
        return ExcelUtils.exportExcel(dataList, T.class);
    }


    public ResultForm exportDicCommonValue(E e) {
        List beans = dao.selectList(e);
        return ExcelUtils.exportExcel(beans, E.class, “Excel文件名称”);
    }

多sheet导出示例,与单Sheet页导出不冲突,也可使用此方式导出单sheet页。

1.添加实体注解,同上

2.初始化工具类实例

ExcelUtils excel = new ExcelUtils<>("导出文件名称");

3.获取数据集合,添加Sheet页数据。

ExcelUtils excel = new ExcelUtils<>("导出文件名称");
//获取数据集合
List dataList = dao.selectList();
 //第一Sheet页
 excel.addSheet(T.class, "sheet标题", dataList,false);

List dataList2 = dao.selectList();
//第二Sheet页
 excel.addSheet(E.class, "sheet2标题", dataList2,false);

4.调用导出

ExcelUtils excel = new ExcelUtils<>("导出文件名称");
//获取数据集合
List dataList = dao.selectList();
 //第一Sheet页
 excel.addSheet(T.class, "sheet标题", dataList,false);

List dataList2 = dao.selectList();
//第二Sheet页
 excel.addSheet(E.class, "sheet2标题", dataList2,false);
//导出
excel.initAndDownload();

上面的最后一个布尔参数为设置是否是下载模板属性,此属性控制sheet页是否按照实体注解顺序只导出标题列,不导出数据,方便后面导入解析。当我们遇到需要下载Excel导入模板,并且需要有其他sheet页的数据作参考时,可通过这个属性来控制,如第一sheet是导入模板(数据集合可传null),第二sheet页为字典值。则可根据此属性控制。

以上为导出的完整示例及代码。

Excel模板导出及导入解析

上面我们介绍了导出工具代码及流程,并在最后说明了一个布尔参数isDownLoadModel

在自定义注解@ExcelField中我们也看到了有个属性值isImport.这个属性是用来标记是否为导出模板列,可以控制这个属性的值在实体中标识是否是导出模板属性,并且后续我们会根据这个属性来判断并解析导入Excel的数据。

注:导入为单sheet页导入,默认为第一个sheet页的数据,可根据自己需要扩展

Excel导入工具类

package com.pride.sun.common;


import com.pride.sun.base.BaseBean;
import com.pride.sun.exception.TipException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.apache.poi.ss.usermodel.CellType.BLANK;

/**
 * @author lpw.
 * @des Excel 导入 工具类
 */
public class ExcelReadUtil {

    private Class claze;

    private final String format = "yyyy-MM-dd HH:mm:ss";

    public ExcelReadUtil(Class claze) {
        this.claze = claze;
    }


    /**
     * 基于注解读取excel
     *
     * @param file 文件
     * @return List List 集合
     */
    public  List readExcel(MultipartFile file) throws Exception {
        verifyExcelFile(file);
        POIFSFileSystem fs = null;
        Field field;
        List list = new ArrayList<>();
        T entity = null;
        // 带注解并排序好的字段
        List fieldList = getFieldList();
        int size = fieldList.size();
        fs = new POIFSFileSystem(file.getInputStream());
        HSSFWorkbook workbook = new HSSFWorkbook(fs);
        HSSFSheet sheet = workbook.getSheetAt(0);
        // 不准确
        int rowLength = sheet.getLastRowNum();
        //第三行开始遍历
        for (int i = 2; i <= rowLength; i++) {
            HSSFRow row = sheet.getRow(i);
            entity = (T) claze.newInstance();
            for (int j = 0; j < size; j++) {
                try {
                    HSSFCell cell = row.getCell(j);
                    field = fieldList.get(j);
                    field.setAccessible(true);
                    field.set(entity, covertAttrType(field, cell));
                } catch (Exception e) {
                    String eMsg = "第" + (i + 1) + "行 第" + (j + 1) + "列;";
                    throw new TipException(eMsg + e.getMessage());
                }
            }
            list.add(entity);
        }
        return list;
    }

    /**
     * 导入文件校验
     *
     * @param file
     */
    private void verifyExcelFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new TipException("文件大小不能为空");
        }
        String fileName = file.getOriginalFilename();
        if (StringUtils.isEmpty(fileName)) {
            throw new TipException("文件名称不能为空");
        }
        String lastName = fileName.substring(fileName.indexOf("."));
        if (!".xls".equals(lastName) && !".xlsx".equals(lastName)) {
            throw new TipException("无法解析的Excel文件格式");
        }

    }


    /**
     * 获取带注解的字段
     *
     * @return
     */
    private List getFieldList() {
        Field[] fields = claze.getDeclaredFields();
        // 无序
        List fieldList = new ArrayList();
        int length = fields.length;
        Field field = null;
        // 获取带注解的字段
        for (int i = 0; i < length; i++) {
            field = fields[i];
            if (field.isAnnotationPresent(ExcelFiled.class)) {
                ExcelFiled excelFiled = field.getAnnotation(ExcelFiled.class);
                if (excelFiled.isImport()) {
                    fieldList.add(field);
                }
            }
        }
        return fieldList;
    }

    /**
     * 类型转换 将cell 单元格格式转为 字段类型
     */
    private Object covertAttrType(Field field, HSSFCell cell) {
        if (null == cell || cell.getCellType() == BLANK) {
            return null;
        }
        // 字段类型
        String fieldType = field.getType().getSimpleName();
        try {
            String cellValue = getValue(cell);
            if (StringUtils.isNotEmpty(cellValue)) {
                if ("String".equals(fieldType)) {
                    return cellValue;
                } else if ("Date".equals(fieldType)) {
                    //首先根据日期注解进行解析日期
                    if (field.isAnnotationPresent(DateTimeFormat.class)) {
                        DateTimeFormat timeFormat = field.getAnnotation(DateTimeFormat.class);
                        if (StringUtils.isNotEmpty(timeFormat.pattern())) {
                            return DateUtil2.parseToDate(cellValue, timeFormat.pattern());
                        }
                    }
                    return DateUtils.parseDate(cellValue, new String[]{format});
                } else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
                    return Integer.parseInt(cellValue);
                } else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
                    return Double.parseDouble(cellValue);
                } else if ("BigDecimal".equals(fieldType)) {
                    return new BigDecimal(cellValue);
                } else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
                    return new Long(cellValue);
                } else {
                    throw new TipException("excel 单元格 格式暂不支持");
                }
            } else {
                return null;
            }
        } catch (Exception e) {
            if (e instanceof ParseException) {
                throw new TipException("时间格式转换失败", e);
            } else {
                e.printStackTrace();
                throw new TipException("格式转换失败");
            }
        }

    }


    /**
     * 格式转为String
     *
     * @param cell
     * @return
     */
    public String getValue(Cell cell) {
        if (cell == null) {
            return "";
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getRichStringCellValue().getString().trim();
            case NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date dt = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
                    return DateFormatUtils.format(dt, format);
                } else {
                    // 防止数值变成科学计数法
                    String strCell = "";
                    Double num = cell.getNumericCellValue();
                    BigDecimal bd = new BigDecimal(num.toString());
                    if (bd != null) {
                        strCell = bd.toPlainString();
                    }
                    // 去除 浮点型 自动加的 .0
                    if (strCell.endsWith(".0")) {
                        strCell = strCell.substring(0, strCell.indexOf("."));
                    }
                    return strCell;
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            case BLANK:
                return "";
            default:
                return "";
        }
    }

}

使用流程示例

1.先在实体上设置导入属性,同导入,关键属性为isImport

2.下载模板,同导出示例

3.用户填充数据后,导入excel

ResultForm importExcelData(MultipartFile excelFile)

4.创建导入工具实例,解析

ExcelReadUtil excelReadUtil = new ExcelReadUtil(T.class);
List beanList = excelReadUtil.readExcel(excelFile);

2022-07-14更新:附日期工具类DateUtil2.java,其中SystemException可替换成别的异常类,如RuntimeException。

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class DateUtil2 {

    public final static Logger logger = LogManager.getLogger(DateUtil2.class);


    public static final String DATE_PATTERN = "yyyy-MM-dd";

    public static final String TIME_PATTERN = "HH:mm:ss";

    public static final String DATE_TIME_PATTERN = DATE_PATTERN + " " + TIME_PATTERN;

    public final static String FORMAT_DATE_DEFAULT = "yyyy-MM-dd";

    public final static String FORMAT_DATE_YYYYMMDD = "yyyyMMdd";

    public final static String FORMAT_DATE_YYYY_MM_DD = "yyyy-MM-dd";

    public final static String FORMAT_DATE_PATTERN_1 = "yyyy/MM/dd";

    public final static String FORMAT_DATE_PATTERN_2 = "yyyy/M/dd";

    public final static String FORMAT_DATE_PATTERN_3 = "yyyy/MM/d";

    public final static String FORMAT_DATE_PATTERN_4 = "yyyy/M/d";

    public final static String FORMAT_DATE_YYYY_MM_DD_HHMMSS = "yyyyMMddHHmmss";

    public final static String FORMAT_DATE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public final static String FORMAT_DATE_YYYY_MM_DD_HHMM = "yyyy-MM-dd HHmm";

    public final static String FORMAT_DATE_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

    public final static String FORMAT_DATE_HH_MM = "HH:mm";

    public final static String FORMAT_DATE_HH_MM_SS = "HH:mm:ss";

    public final static String FORMAT_DATE_HHMM = "HHmm";

    public final static String FORMAT_DATE_HHMMSS = "HHmmss";

    public static final String FORMAT_DATE_YYMMDD = "yyMMdd";

    public static final String FORMAT_WORK_TIME = "yyyy-MM-dd HHmmss";

    public static final String FORMAT_DATE_YYYY_MM_DDHHMMSS = "yyyy-MM-ddHHmmss";

    /**
     * 锁对象
     */
    private static final Object LOCK_OBJ = new Object();

    private static Map> sdfMap = new HashMap<>();

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal tl = sdfMap.get(pattern);
        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (tl == null) {
            synchronized (LOCK_OBJ) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    // 这里是关键,使用ThreadLocal替代原来直接new SimpleDateFormat
                    tl = ThreadLocal.withInitial(() -> new SimpleDateFormat(pattern));
                    sdfMap.put(pattern, tl);
                }
            }
        }
        return tl.get();
    }

    /**
     * 是用ThreadLocal来获取SimpleDateFormat,这样每个线程只会有一个SimpleDateFormat
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        return getSdf(pattern).format(date);
    }

    public static Date parseToDate(String dateStr, String pattern) throws ParseException {
        return getSdf(pattern).parse(dateStr);
    }


    /**
     * 把int的20170812的日期,转换成toPattern的字符串格式
     *
     * @param dateInt
     * @param pattern
     * @param toPattern
     * @return
     * @throws ParseException
     */
    public static String parseIntToString(String dateInt, String pattern, String toPattern) {
        Date date = null;
        try {
            date = getSdf(pattern).parse(dateInt);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return formatDate(date, toPattern);
    }

    public static String parseInt8ToString(Integer dateInt, String toPattern) {
        if (dateInt == null) {
            return "";
        }
        String dateString = dateInt.toString();
        return parseIntToString(dateString, "yyyyMMdd", toPattern);
    }

    /**
     * 把int的20170812的日期,转换成toPattern的字符串格式
     *
     * @param dateInt
     * @param pattern
     * @param toPattern
     * @return
     * @throws ParseException
     */
    public static Date parseIntToDate(String dateInt, String pattern, String toPattern) throws ParseException {
        return getSdf(pattern).parse(dateInt);
    }

    /**
     * 比较两个时间是否相等。
     *
     * @param d1 时间1
     * @param d2 时间2
     * @return 相等则true。因为数据库中读出的数据为Timestamp类型(Date的子类),
     * 当它与Date类型进行比较时,总是为false,即使是同一个时间.因此写了这个方法,用于兼容这两种类型的时间比较.
     * @author slx
     * @date 2009-7-13 上午10:08:52
     * @modifyNote
     */
    public static boolean equalsDate(Date d1, Date d2) {
        if (d1 != null && d2 != null) {
            return d1.getTime() == d2.getTime();
        }
        return false;
    }

    /**
     * 判断后面的一天是否是前面一天的下一天
     *
     * @param day     基准日期
     * @param nextDay 比较日期
     * @return 如果比较日期是基准日期的下一天则返回true,否则为false
     * @author slx
     */
    public static boolean isNextDay(Date day, Date nextDay) {
        return (getBetweenDays(day, nextDay) == -1);
    }

    /**
     * 判断两个日期是否是同一天
     *
     * @param day
     * @param otherDay
     * @author slx
     */
    public static boolean isSameDayxxxxxxxx(Date day, Date otherDay) {
        return (getBetweenDays(day, otherDay) == 0);
    }

    /**
     * 计算两个日期相差的天数.不满24小时不算做一天
     *
     * @param fDate 日期1
     * @param sDate 日期2
     * @return 日期1 - 日期2 的差
     * @author slx
     * @date 2009-7-10 下午03:15:54
     * @modifyNote
     */
    public static int getBetweenDays(Date fDate, Date sDate) {
        return (int) ((fDate.getTime() - sDate.getTime()) / 86400000L);
    }

    /**
     * 计算两个日期相差的天数.不满24小时不算做一天
     *
     * @param fDate
     * @param sDate
     * @return
     * @throws SystemException
     */
    public static int getBetweenDays(Integer fDate, Integer sDate) throws SystemException {
        Date coutDate = new Date();
        Date cinDate = new Date();
        try {
            cinDate = DateUtil2.parseToDate(fDate.toString(), "yyyyMMdd");
        } catch (Exception e) {
            logger.error("转换开始时间出错", e);
            throw new SystemException("转换开始时间出错");
        }
        try {
            coutDate = DateUtil2.parseToDate(sDate.toString(), "yyyyMMdd");
        } catch (Exception e) {
            logger.error("转换结束时间出错", e);
            throw new SystemException("转换结束时间出错");
        }
        return (int) ((coutDate.getTime() - cinDate.getTime()) / 86400000L);
    }

    /**
     * 日期相加指定年
     *
     * @param date     日期
     * @param addYears 要添加的年数
     * @return 相加后的日期
     * @author slx
     * @date 2009-9-10 上午10:26:22
     * @modifyNote
     */
    public static Date addYears(Date date, int addYears) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.YEAR, addYears);
        return calender.getTime();
    }

    /**
     * 加指定月
     *
     * @param date      日期
     * @param addMonths 月数
     * @return 相加后的日期
     * @author slx
     * @date 2009-9-10 上午10:26:57
     * @modifyNote
     */
    public static Date addMonth(Date date, int addMonths) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.MONTH, addMonths);
        return calender.getTime();
    }

    /**
     * 加指定天数
     *
     * @param date    日期
     * @param addDays 天数
     * @return 相加后的日期
     * @author slx
     * @date 2009-9-10 上午10:27:22
     * @modifyNote
     */
    public static Date addDay(Date date, int addDays) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.DAY_OF_YEAR, addDays);
        return calender.getTime();
    }

    /**
     * 加指定小时
     *
     * @param date
     * @param addHours
     * @return
     */
    public static Date addHour(Date date, int addHours) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.HOUR, addHours);
        return calender.getTime();
    }

    /**
     * 加指定分钟
     *
     * @param date
     * @param addMinutes
     * @return
     */
    public static Date addMinute(Date date, int addMinutes) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.MINUTE, addMinutes);
        return calender.getTime();
    }


    /**
     * 得到一年的第一天
     *
     * @param year 年
     * @return 一年的第一天
     * @author slx
     * @date 2009-9-10 上午11:14:23
     * @modifyNote
     */
    public static Date getFirstDateOfYear(int year) {
        Calendar calender = Calendar.getInstance();
        calender.set(Calendar.YEAR, year);
        calender.set(Calendar.DAY_OF_YEAR, calender.getActualMinimum(Calendar.DAY_OF_YEAR));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到一年的最后一天
     *
     * @param year 年
     * @return 一年的最后一天
     * @author slx
     * @date 2009-9-10 上午11:14:42
     * @modifyNote
     */
    public static Date getLastDateOfYear(int year) {
        Calendar calender = Calendar.getInstance();
        calender.set(Calendar.YEAR, year);
        calender.set(Calendar.DAY_OF_YEAR, calender.getActualMaximum(Calendar.DAY_OF_YEAR));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 判断当前日期是否是所在月份的最后一天
     *
     * @param date 日期
     * @return 是最后一天为 true
     * @author slx
     * @date 2009-9-10 上午10:54:36
     * @modifyNote
     */
    public static boolean isLastDayOfMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int day = calender.get(Calendar.DAY_OF_MONTH);
        int lastDay = calender.getActualMaximum(Calendar.DAY_OF_MONTH);
        return day == lastDay;
    }

    /**
     * 得到指定月的最后一天
     *
     * @param year  年
     * @param month 月
     * @return 最后一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     */
    public static Date getLastDayOfMonth(int year, int month) {
        Calendar calender = Calendar.getInstance();
        calender.set(year, month - 1, 1);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DAY_OF_MONTH));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到日期所在月的最后一天
     *
     * @param date 日期
     * @return 所在月的最后一天
     * @author slx
     * @date 2009-9-10 上午10:54:25
     * @modifyNote
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DAY_OF_MONTH));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 设置到当前月的最后时刻
     *
     * @param calender
     * @author slx
     * @date 2010-10-18 上午11:04:56
     * @modifyNote
     */
    private static void setEndTimeOfDay(Calendar calender) {
        calender.set(Calendar.HOUR_OF_DAY, calender.getActualMaximum(Calendar.HOUR_OF_DAY));
        calender.set(Calendar.MINUTE, calender.getActualMaximum(Calendar.MINUTE));
        calender.set(Calendar.SECOND, calender.getActualMaximum(Calendar.SECOND));
        calender.set(Calendar.MILLISECOND, calender.getActualMaximum(Calendar.MILLISECOND));
    }

    /**
     * 得到指定月的第一天
     *
     * @param year  年
     * @param month 月
     * @return 第一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     */
    public static Date getFirstDayOfMonth(int year, int month) {
        Calendar calender = Calendar.getInstance();
        calender.set(year, month - 1, 1);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMinimum(Calendar.DAY_OF_MONTH));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到指定日期所在月的第一天
     *
     * @param date 日期
     * @return 第一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMinimum(Calendar.DAY_OF_MONTH));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 设置到月份开始的时刻
     *
     * @param calender
     * @author slx
     * @date 2010-10-18 上午11:06:12
     * @modifyNote
     */
    private static void setStartTimeOfDay(Calendar calender) {
        calender.set(Calendar.HOUR_OF_DAY, calender.getActualMinimum(Calendar.HOUR_OF_DAY));
        calender.set(Calendar.MINUTE, calender.getActualMinimum(Calendar.MINUTE));
        calender.set(Calendar.SECOND, calender.getActualMinimum(Calendar.SECOND));
        calender.set(Calendar.MILLISECOND, calender.getActualMinimum(Calendar.MILLISECOND));
    }

    public static Date getStartTimeOfDay(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    public static Date getEndTimeOfDay(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        setEndTimeOfDay(calender);
        return calender.getTime();

    }

    /**
     * 得到当前年月
     *
     * @return 格式:2008-11
     * @throws ParseException
     * @author yongtree
     * @date 2008-11-22 上午11:25:24
     */
    public static String getThisYearMonth() {
        return getYearMonth(new Date());
    }

    /**
     * 得到年月
     *
     * @return 格式:2008-11
     * @throws ParseException
     * @author slx
     * @date 2010年4月16日13:09:23
     */
    public static String getYearMonth(Date date) {
        Calendar today = Calendar.getInstance();
        today.setTime(date);
        return (today.get(Calendar.YEAR)) + "-" + ((today.get(Calendar.MONTH) + 1) >= 10 ? (today.get(Calendar.MONTH) + 1) : ("0" + (today.get(Calendar.MONTH) + 1)));
    }

    public static String getYear() {
        Calendar today = Calendar.getInstance();
        today.setTime(new Date());
        return String.valueOf(today.get(Calendar.YEAR));
    }

    public static String getMonth() {
        Calendar today = Calendar.getInstance();
        today.setTime(new Date());
        return String.valueOf(today.get(Calendar.MONTH) + 1);
    }

    public static String getDate() {
        Calendar today = Calendar.getInstance();
        today.setTime(new Date());
        return String.valueOf(today.get(Calendar.DATE));
    }


    /**
     * 计算两个日期之间相差的月份数
     * 
日期顺序不分先后不会返回负数 *
不足一个月不算做一个月 * * @param date1 日期1 * @param date2 日期2 * @return 月数 * @author slx * @date 2010年4月16日11:32:51 * @modifyNote */ public static int getBetweenMonths(Date date1, Date date2) { int iMonth = 0; int flag = 0; Calendar objCalendarDate1 = Calendar.getInstance(); objCalendarDate1.setTime(date1); Calendar objCalendarDate2 = Calendar.getInstance(); objCalendarDate2.setTime(date2); if (objCalendarDate2.equals(objCalendarDate1)) { return 0; } if (objCalendarDate1.after(objCalendarDate2)) { Calendar temp = objCalendarDate1; objCalendarDate1 = objCalendarDate2; objCalendarDate2 = temp; } if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1.get(Calendar.DAY_OF_MONTH)) { flag = 1; } if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR)) { iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR)) * 12 + objCalendarDate2.get(Calendar.MONTH) - flag) - objCalendarDate1.get(Calendar.MONTH); } else { iMonth = objCalendarDate2.get(Calendar.MONTH) - objCalendarDate1.get(Calendar.MONTH) - flag; } return iMonth; } /** * 计算两个日期之间相差的年份数 *
日期顺序不分先后不会返回负数 *
不足一个年不算做一个年 * * @param date1 日期1 * @param date2 日期2 * @return 年数 * @author slx * @date 2010年4月16日12:01:46 * @modifyNote */ public static int getBetweenYears(Date date1, Date date2) { return getBetweenMonths(date1, date2) / 12; } public static boolean before(Date date1, Date date2) { if (date1 == null || date2 == null) { return false; } Calendar c1 = new GregorianCalendar(); c1.setTime(date1); Calendar c2 = new GregorianCalendar(); c2.setTime(date2); return c1.before(c2); } public static boolean after(Date date1, Date date2) { if (date1 == null || date2 == null) { return false; } Calendar c1 = new GregorianCalendar(); c1.setTime(date1); Calendar c2 = new GregorianCalendar(); c2.setTime(date2); return c1.after(c2); } /** * 当前时间是否失效 * * @param expiresDate * @return */ public static boolean isExpires(Date expiresDate) { return after(new Date(), expiresDate); } /** * 是否同一天 * * @param date1 * @param date2 * @return */ public static boolean isSameDate(Date date1, Date date2) { Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); boolean isSameYear = cal1.get(Calendar.YEAR) == cal2 .get(Calendar.YEAR); boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH); boolean isSameDate = isSameMonth && cal1.get(Calendar.DAY_OF_MONTH) == cal2 .get(Calendar.DAY_OF_MONTH); return isSameDate; } /** * 判断两个日期是否相差一天 * * @return */ public static boolean isYesterday(Date oldDate, Date newDate) { Calendar oldCal = Calendar.getInstance(); Calendar newCal = Calendar.getInstance(); oldCal.setTime(oldDate); newCal.setTime(newDate); return Math.abs(newCal.get(Calendar.DAY_OF_YEAR) - oldCal.get(Calendar.DAY_OF_YEAR)) == 1; } /** * 校验日期格式是否合法 * * @param date * @param format * @return */ public static boolean isValidDate(String date, String format) { boolean convertSuccess = true; // 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写; SimpleDateFormat sdf = new SimpleDateFormat(format); try { // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 sdf.setLenient(false); sdf.parse(date); } catch (ParseException e) { // e.printStackTrace(); // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对 convertSuccess = false; } return convertSuccess; } public static Integer getInt8Value(String date, String pattern) throws ParseException { Date d = DateUtil2.parse(date, pattern); return getInt8Value(d); } public static Integer getInt8Value(Date date) { String year = getIntYear(date).toString(); String month = getIntMonth(date).toString(); String date1 = getIntDate(date).toString(); if (month.length() < 2) { month = "0" + month; } if (date1.length() < 2) { date1 = "0" + date1; } return Integer.parseInt(year + month + date1); } public static Integer getIntYear(Date date) { Calendar today = Calendar.getInstance(); today.setTime(date); return today.get(Calendar.YEAR); } public static Integer getIntMonth(Date date) { Calendar today = Calendar.getInstance(); today.setTime(date); return today.get(Calendar.MONTH) + 1; } public static Integer getIntDate(Date date) { Calendar today = Calendar.getInstance(); today.setTime(date); return today.get(Calendar.DATE); } public static String getStringDate(Integer date) { String newDate = null; if (date.toString().length() == 8) { newDate = date.toString().substring(0, 4) + "-" + date.toString().substring(4, 6) + "-" + date.toString().substring(6, 8); } return newDate; } public final static int compareDate(String stringValue1, Date date2) throws ParseException { Date date1 = tryParse(stringValue1); if (date1 == null) { throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0); } if (date2 == null) { throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0); } return date1.compareTo(date2); } public final static int compareDate(String stringValue1, String stringValue2) throws ParseException { Date date1 = tryParse(stringValue1); if (date1 == null) { throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0); } Date date2 = tryParse(stringValue2); if (date2 == null) { throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0); } return date1.compareTo(date2); } public final static Date tryParse(String stringValue) throws ParseException { Date date = parse(stringValue, FORMAT_DATE_YYYY_MM_DD); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_YYYYMMDD); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_YYYY_MM_DD_HHMMSS); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_YYYY_MM_DD_HH_MM_SS); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_YYYY_MM_DD_HHMM); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_PATTERN_1); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_PATTERN_2); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_PATTERN_3); if (date != null) { return date; } date = parse(stringValue, FORMAT_DATE_PATTERN_4); if (date != null) { return date; } return date; } public final static Date parse(String stringValue, String formatPattern) throws ParseException { return parseToDate(stringValue, formatPattern); } public final static Date getCurrentDate() { return Calendar.getInstance().getTime(); } /** * 计算2个日期差多少年多少月多少天 * * @param calendarBirth * @param calendarNow * @return */ public static int[] getNeturalAge(Calendar calendarBirth, Calendar calendarNow) { int diffYears = 0, diffMonths, diffDays; int dayOfBirth = calendarBirth.get(Calendar.DAY_OF_MONTH); int dayOfNow = calendarNow.get(Calendar.DAY_OF_MONTH); if (dayOfBirth <= dayOfNow) { diffMonths = getMonthsOfAge(calendarBirth, calendarNow); diffDays = dayOfNow - dayOfBirth; if (diffMonths == 0) { diffDays++; } } else { if (isEndOfMonth(calendarBirth)) { if (isEndOfMonth(calendarNow)) { diffMonths = getMonthsOfAge(calendarBirth, calendarNow); diffDays = 0; } else { calendarNow.add(Calendar.MONTH, -1); diffMonths = getMonthsOfAge(calendarBirth, calendarNow); diffDays = dayOfNow + 1; } } else { if (isEndOfMonth(calendarNow)) { diffMonths = getMonthsOfAge(calendarBirth, calendarNow); diffDays = 0; } else { calendarNow.add(Calendar.MONTH, -1);// 上个月 diffMonths = getMonthsOfAge(calendarBirth, calendarNow); // 获取上个月最大的一天 int maxDayOfLastMonth = calendarNow.getActualMaximum(Calendar.DAY_OF_MONTH); if (maxDayOfLastMonth > dayOfBirth) { diffDays = maxDayOfLastMonth - dayOfBirth + dayOfNow; } else { diffDays = dayOfNow; } } } } // 计算月份时,没有考虑年 diffYears = diffMonths / 12; diffMonths = diffMonths % 12; return new int[]{diffYears, diffMonths, diffDays}; } /** * 获取两个日历的月份之差 * * @param calendarBirth * @param calendarNow * @return */ public static int getMonthsOfAge(Calendar calendarBirth, Calendar calendarNow) { return (calendarNow.get(Calendar.YEAR) - calendarBirth .get(Calendar.YEAR)) * 12 + calendarNow.get(Calendar.MONTH) - calendarBirth.get(Calendar.MONTH); } /** * 判断这一天是否是月底 * * @param calendar * @return */ public static boolean isEndOfMonth(Calendar calendar) { int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); return dayOfMonth == calendar.getActualMaximum(Calendar.DAY_OF_MONTH); } /** * 根据开始时间和结束时间返回时间段内的时间集合 * * @param beginDate * @param endDate * @return List */ public static List getDatesBetweenTwoDate(String beginDate, String endDate) throws ParseException { List lDate = new ArrayList<>(); lDate.add(beginDate);//把开始时间加入集合 Date d1 = parseToDate(beginDate, DATE_PATTERN); Date d2 = parseToDate(endDate, DATE_PATTERN); Calendar cal = Calendar.getInstance(); //使用给定的 Date 设置此 Calendar 的时间 cal.setTime(d1); while (true) { //根据日历的规则,为给定的日历字段添加或减去指定的时间量 cal.add(Calendar.DAY_OF_MONTH, 1); // 测试此日期是否在指定日期之后 if (d2.after(cal.getTime())) { lDate.add(formatDate(cal.getTime(), DATE_PATTERN)); } else { break; } } lDate.add(endDate);//把结束时间加入集合 return lDate; } /** * 根据开始时间和结束时间返回时间段内的时间集合 * * @param beginDate * @param endDate * @return List */ public static List getDatesBetweenTwoDate(String beginDate, String endDate, String fromDatePattern, String toDatePattern) { List lDate = new ArrayList<>(); //把开始时间加入集合 lDate.add(beginDate); Date d1 = null; Date d2 = null; try { d1 = parseToDate(beginDate, fromDatePattern); d2 = parseToDate(endDate, fromDatePattern); } catch (Exception e) { e.printStackTrace(); } Calendar cal = Calendar.getInstance(); //使用给定的 Date 设置此 Calendar 的时间 cal.setTime(d1); while (true) { //根据日历的规则,为给定的日历字段添加或减去指定的时间量 cal.add(Calendar.DAY_OF_MONTH, 1); // 测试此日期是否在指定日期之后 if (d2.after(cal.getTime())) { lDate.add(formatDate(cal.getTime(), toDatePattern)); } else { break; } } //把结束时间加入集合 lDate.add(endDate); return lDate; } /** * 计算两个日期相差多少分钟 * * @param startTime * @param endTime * @return */ public static Long getDifferMinutes(Date startTime, Date endTime) { long nm = 1000 * 60; Long diff = endTime.getTime() - startTime.getTime(); Long minutes = diff / nm; return minutes; } }

导入完成。

以上就是Excel导出及导入的工具代码说明,此工具类比较简单,小伙伴们可根据实际需要编写扩展更多场景及功能。

其他:转载需附本文链接及说明,尊重劳动

你可能感兴趣的:(java,开发语言,后端)