java自定义Excel导出工具类

时间:2020-10-28 作者:admin

java自定义Excel导出工具

一、引入

预备知识:

  1. java的自定义注解
  2. java反射
  3. poi的常用api

注解和反射学习:

自定义和反射的内容比较多就不行细致阐述了,不了解的可以点击下方进行跳转

自定义注解

java反射

poi的maven引入:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</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);
    }

}

运行结果:
java自定义Excel导出工具类

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。