之前写有一个比较简单粗暴的 通用的excel导入导出工具类.
这个工具类呢也用了挺久了的,有兴趣的也可以去看一下哈。
最近又新写了一个 基于注解+反射实现的Excel导入导出 工具类,已发 maven 中央仓库。
本文主要讲新工具的功能点和简单实现过程,以及依赖引入参考。
源码:https://github.com/Sanchar-H/excel-helper.git
功能点说明
- 将excel的指定单个sheet页数据转换为对象集合List<T>
- 将excel的指定多个sheet页数据转换为对象集合列表List<List<T>>
- 将对象集合 List<T> 写入Excel,单sheet页模式,可添加单元格下拉框
- 将对象集合列表 List<List<T>> 写入Excel,单sheet页和多sheet页模式均可,可添加单元格下拉框
依赖引入
当前最新版本是1.0.2,后续会持续更新,引入依赖之后按照文章后面的参考示例使用即可
<dependency>
<groupId>cn.sanchar.excel</groupId>
<artifactId>excel-helper</artifactId>
<version>1.0.2</version>
</dependency>
#简单实现过程
首先需要创建注解
EnableExcelImport 注解,必须有这个注解才能导入
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableExcelImport {
/**
* sheet 页名-列表
*/
String[] sheetNames() default {};
/**
* sheet 索引-列表
*/
int[] sheetIndexes() default {};
/**
* 开始行-列表
*/
int[] startRowIndexes() default {};
}
EnableExcelExport 注解,必须有这个注解才能导出到Excel里面
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableExcelExport {
/**
* 文件格式
*/
String fileType() default "xlsx";
/**
* sheet 页名-列表
*/
String[] sheetNames() default {};
/**
* 是否隐藏Sheet页-列表
*/
boolean[] isHiddenSheets() default {};
/**
* 是否需要表头-列表
*/
boolean[] isIncludeHeaders() default {};
/**
* 开始行-列表
*/
int[] startRowIndexes() default {};
/**
* 开始列-列表
*/
short[] startColumnIndexes() default {};
}
SheetColumn 注解,实体类字段上有这个注解才导出或者导入该字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SheetColumn {
/**
* 表头列名
*/
String name();
/**
* 日期&时间格式
*/
String format() default "yyyy/m/d h:mm:ss";
/**
* 列索引
*/
int index() default -1;
/**
* 列宽
*/
int width() default 4;
/**
* 必输
*/
boolean required() default false;
/**
* 导入字段
*/
boolean imported() default true;
/**
* 导出字段
*/
boolean exported() default true;
}
三个注解创建好之后,下面就开始封装Excel导入导出的工具类了,由于工具类的代码量比较多,这里就不贴出来了,有兴趣可以去 githup 上看源码, githup 链接在文章开头和末尾均有。
注解使用示例
/**
* description: 员工基本信息导入导出
*
* @author shencai.huang@hand-china.com
* @date 2021/9/27 4:54 下午
* lastUpdateBy: shencai.huang@hand-china.com
* lastUpdateDate: 2021/9/27
*/
@EnableExcelImport(sheetIndexes = {0, 1, 2}, startRowIndexes = 1)
@EnableExcelExport(isIncludeHeaders = true)
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@SheetColumn(name = "姓名", index = 0, required = true)
private String fullName;
@SheetColumn(name = "性别", index = 1, required = true)
private String gender;
@SheetColumn(name = "年龄", index = 2, required = true)
private BigDecimal age;
@SheetColumn(name = "地址", index = 3)
private String address;
@SheetColumn(name = "电话", index = 4, width = 6)
private String phone;
@SheetColumn(name = "邮箱", index = 5, width = 10)
private String email;
@SheetColumn(name = "入职时间", index = 6, width = 6, format = "yyyy-m-d")
private Date joinTime;
@SheetColumn(name = "离职时间", index = 7, width = 10)
private Date leaveTime;
// getter and setter...
}
工具类调用示例如下
public static void main(String[] args) throws IOException {
File file = new File("/Users/sch/DATA/Temp/11.xlsx");
if (!file.exists()) {
file.createNewFile();
}
// 单sheet页数据导出参考
ExcelUtils.singleListToStream(initData(), new FileOutputStream(file), Employee.class);
// 单sheet页数据读取参考
List<Employee> employees = ExcelUtils.singleParseToList(new FileInputStream(file), Employee.class);
System.out.println(employees);
// 多sheet页数据导出参考-导出可以不用配置EnableExcelExport的sheet页名或者索引
ExcelUtils.listToStream(Arrays.asList(initData(), initData(), initData()), new FileOutputStream(file), Employee.class);
// 多sheet页数据导入参考-导入需要配置EnableExcelImport,指定导出的sheet页名或者索引
// 比如:sheetIndexes = {0, 1, 2}
// 没有配置则默认只读取第一个sheet的数据,即导出结果 employeeListList.size = 1
List<List<Employee>> employeeListList = ExcelUtils.parseToList(new FileInputStream(file), Employee.class);
System.out.println(employeeListList);
// 多sheet页数据导出带下拉框参考
ExcelUtils.listToStream(Arrays.asList(initData(), initData(), initData()), new FileOutputStream(file), Employee.class, validationDataList());
}
public static List<Employee> initData() {
List<Employee> employees = Lists.newArrayList();
employees.add(new Employee("张三", "男", new BigDecimal(18), "深圳", "15211111111", "zhangsan@sanchar.cn", new Date(), new Date()));
employees.add(new Employee("李四", "女", new BigDecimal(23), "北京", "15299999999", "lisi@sanchar.cn", new Date(), new Date()));
employees.add(new Employee("王五", "男", new BigDecimal(28), "广州", "15288888888", "wangwu@sanchar.cn", new Date(), new Date()));
employees.add(new Employee("赵六", "女", new BigDecimal(21), "桂林", "15277777777", "zhaoliu@sanchar.cn", new Date(), new Date()));
employees.add(new Employee("邓七", "男", new BigDecimal(20), "成都", "15266666666", "dengqi@sanchar.cn", new Date(), new Date()));
return employees;
}
public static List<ExcelBox> validationDataList() {
List<ExcelBox> excelBoxes = Lists.newArrayList();
String[] genders = {"男", "女", "未知"};
excelBoxes.add(new ExcelBox().boxName("性别").sheetIndex(0).values(genders).firstRow(1).firstCol(1));
String[] ages = {"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"};
excelBoxes.add(new ExcelBox().boxName("年龄").sheetIndex(0).values(ages).firstRow(1).firstCol(2));
String[] addresses = {"上海", "北京", "广州", "深圳", "成都", "武汉", "桂林", "杭州", "厦门"};
excelBoxes.add(new ExcelBox().boxName("地址").sheetIndex(0).values(addresses).firstRow(1).firstCol(3));
return excelBoxes;
}
该工具类只是做了一些简单的封装,有兴趣的小伙伴或者该工具类未满足您当前的开发需求,可以基于该工具类进行二次封装处理哈,比如数据导出的时候excel表格需要有下拉框(当前已集成有),必输字段非必输字段的颜色控制等都可以集成到该工具类里边