一.引入MAVEN依赖
这里主要使用poi-ooxml,lombok和commons-lang3
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
二.自定义注解
1.ExcelColumn注解
ExcelColumn主要用来标记Excel的数据字段的一些信息
@Documented
@Target({
ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelColumn {
/**
* 标题
*
* @return
*/
String title();
/**
* 下标
*
* @return
*/
int index() default 0;
/**
* 标题行坐标
*
* @return
*/
int rowIndex() default 0;
/**
* 类型
*
* @return
*/
ExcelType type() default ExcelType.STRING;
/**
* 格式
*
* @return
*/
String format() default "";
}
2.ExcelSheet 注解
ExcelSheet注解用来描述Excel中工作簿的一些信息
@Documented
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelSheet {
/**
* Sheet 标题
*
* @return
*/
String title() default "";
/**
* Sheet下标
*
* @return
*/
int index() default 0;
}
3.ExcelTemplate注解
ExcelTemplate注解用来工作簿中的一些标题信息和表头信息,用来处理一些导出时需要用的双表头或者需要给工作表添加标题的场合.
@Documented
@Target({
ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelTemplate {
/**
* 单元格内的值
*
* @return
*/
String value() default "";
/**
* 合并行的数量
*
* @return
*/
int rowspan() default 0;
/**
* 起始列
*
* @return
*/
int colIndex();
/**
* 列合并的数量
*
* @return
*/
int colspan() default 0;
}
三.自定义类型
这里定义一个枚举类型的类,用来标记导出时每个字段的类型,这里和ExcelColumn配合使用
public enum ExcelType {
STRING,
DOUBLE,
INT,
DECIMAL,
DATE,
LOCAL_DATE,
LOCAL_DATE_TIME,
LOCAL_TIME;
}
四.导入导出工具类
1.导出数据模型
ExcelData用于存放导出数据,fileName
用来存放要导出Excel文件的文件名,data
用来存放导出到Excel的数据
@Data
public class ExcelData<T> {
private String fileName;
private List<T> data;
}
2.工具类
@Slf4j
@UtilityClass
public class ExcelUtils {
/**
* xls 后缀
*/
private final String XLS = ".xls";
/**
* xlsx 后缀
*/
private final String XLS_X = ".xlsx";
/**
* sheet页的第一行
*/
private final int FIRST_ROW = 0;
/**
* 第一个工作簿
*/
private final int FIRST_SHEET = 0;
/**
* sheet页的第一列
*/
private final int FIRST_COL = 0;
/**
* 科学计数
*/
private final static String E = "e";
private final String TIMEF_FORMAT = "yyyy-MM-dd HH:mm:ss";
private final String DATE_FORMAT = "yyyy-MM-dd";
public <T> List<T> importExcel(MultipartFile file, Class<T> clazz) {
checkFile(file);
Workbook workbook = getWorkBook(file);
List<T> list = new ArrayList<T>();
Field[] fields = getFields(clazz);
if (Objects.nonNull(workbook)) {
Sheet sheet = getSheet(workbook, clazz);
if (sheet == null || sheet.getLastRowNum() == 0) {
return list;
}
// 获得当前sheet的开始行
int firstRowNum = sheet.getFirstRowNum();
// 获得当前sheet的结束行
int lastRowNum = sheet.getLastRowNum();
for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
// 获得当前行
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
Object obj;
try {
obj = clazz.newInstance();
} catch (IllegalAccessException e) {
log.error("【excel导入】clazz映射地址:{},{}", clazz.getCanonicalName(), "excel导入异常!");
throw new RuntimeException("excel导入异常", e);
} catch (InstantiationException e) {