预备知识:
注解和反射学习:
自定义和反射的内容比较多就不行细致阐述了,不了解的可以点击下方进行跳转
自定义注解
java反射
poi的maven引入:
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
poi的常用api:
1.创建一个工作簿
Workbook wb = new XSSFWorkbook();
...
try (OutputStream fileOut = new FileOutputStream("workbook.xlsx")) {
wb.write(fileOut);
}
2.创建一个工作表
Sheet sheet1 = wb.createSheet("new sheet");
Sheet sheet2 = wb.createSheet("second sheet");
3.创建一个单元格
Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
自定义Excel注解:
目的:通过反射获取对象中带有Excel
注解的字段,并进行解析导出
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
/**
* 导出到Excel中的名字.
*/
String name() default "";
/**
* 日期格式, 如: yyyy-MM-dd
*/
String dateFormat() default "";
}
自定义ExcelUtil工具类:
目的:通过反射和Excel注解
/**
* Excel的工具类
*/
public class ExcelUtils<T> {
/**
* 工作簿
*/
private Workbook wb;
/**
* 工作表
*/
private Sheet sheet;
/**
* class对象
*/
private Class<T> clazz;
/**
* 导出导入数据
*/
private List<T> list;
/**
* 含有Excel注解的字段
*/
private List<Field> fields;
private ExcelUtils(){
}
public ExcelUtils(Class<T> clazz){
this.clazz = clazz;
}
/**
* 数据导出excel
*
* @param list 目标数据
* @param sheetName 工作表名称
*/
public void exportExcel(List<T> list, String sheetName) {
// 初始化
init(list, sheetName);
// sheet第一行加入名称数据
createTopRow();
// sheet其他行,添加目标数据
try {
createOtherRow(list);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
try(OutputStream outFile = new FileOutputStream("D:3.xlsx")){
wb.write(outFile);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 添加导出数据
*/
private void createOtherRow(List<T> list) throws IllegalAccessException {
for(int rowNum = 1; rowNum <= list.size(); rowNum++) {
Row row = sheet.createRow(rowNum);
T t = list.get(rowNum - 1);
for(int colNum = 0; colNum < fields.size(); colNum++) {
Cell cell = row.createCell(colNum);
Field field = fields.get(colNum);
field.setAccessible(true);
// 单元格设置值
addCell(cell, field, t);
}
}
}
/**
* 单元格中添加数据
*
* @param cell 单元格
* @param field 字段
* @param t list中的一条数据
*/
private void addCell(Cell cell, Field field, T t) throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (String.class == fieldType)
{
cell.setCellValue((String) field.get(t));
}
else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
{
cell.setCellValue((Integer) field.get(t));
}
else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
{
cell.setCellValue((Long) field.get(t));
}
else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
{
cell.setCellValue((Double) field.get(t));
}
else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
{
cell.setCellValue((Float) field.get(t));
}
else if (Date.class == fieldType)
{
String dateFormat = field.getAnnotation(Excel.class).dateFormat();
cell.setCellValue(dateFormat((Date) field.get(t), dateFormat));
}
}
/**
* 时间格式转换
* @param date 日期
* @param dateFormat 日期格式
* @return
*/
private String dateFormat(Date date, String dateFormat) {
if (dateFormat == null || "".equals(dateFormat)) {
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
SimpleDateFormat df = new SimpleDateFormat(dateFormat);
return df.format(date);
}
/**
* sheet第一行加入名称数据
*/
private void createTopRow() {
Row row = sheet.createRow(0);
for(int index = 0; index < fields.size(); index++){
Cell cell = row.createCell(index);
cell.setCellValue(fields.get(index).getAnnotation(Excel.class).name());
}
}
/**
* 数据导出excel
*
* @param data 目标数据
*/
public void exportExcel(List<T> data){
this.exportExcel(data, "sheet");
}
/**
* 初始化
* 1.创建一个工作簿(Workbook)
* 2.根据一个sheetName, 创建一个工作表(sheet)
* 3.通过反射,获取包含Excel注解的字段
*
* @param data 目标数据
* @param sheetName 工作表名称
*/
public void init(List<T> data, String sheetName){
if(data == null) {
this.list = new ArrayList<>();
}
// 创建工作簿
createWorkbook();
// 创建工作表
createSheet(sheetName);
// 初始化Fields
filterFields();
}
/**
* 创建工作簿
*
* @param sheetName sheet的名称
*/
private void createSheet(String sheetName) {
this.sheet = wb.createSheet(sheetName);
}
/**
* 创建工作簿
*/
private void createWorkbook() {
this.wb = new SXSSFWorkbook();
}
/**
* 过滤出带有Excel注解的字段
*/
private void filterFields(){
this.fields = Arrays.
asList(clazz.getDeclaredFields()).
stream().
filter(item -> item.isAnnotationPresent(Excel.class))
.collect(Collectors.toList());
}
}
导出测试:
第一步准备要导出的对象(这边引用了lombok
)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Excel(name = "姓名")
private String name;
@Excel(name = "年龄")
private Integer age;
@Excel(name = "出生日期", dateFormat = "yyyy-MM-dd")
private Date birthday;
}
导出测试:
public class Demo1 {
public static void main(String[] args) throws IOException {
// 准备数据
ArrayList<Student> data = new ArrayList<>();
Student student = new Student();
student.setName("tom");
student.setAge(19);
student.setBirthday(new Date());
data.add(student);
// 导出Excel
ExcelUtils<Student> utils = new ExcelUtils<>(Student.class);
utils.exportExcel(data);
}
}