EasyExcel(上)——Java如何使用Excel

目录

1.环境搭建

2.简单的写操作演示

2.1 实体类

2.2 写入方法

2.3 效果展示

3.写操作的实体类

3.1 表头的内容和顺序

3.1.1 @ExcelProperty(value)

3.1.2 @ExcelProperty(index)

3.1.3 @ExcelProperty(value,index)

3.1.4 @ExcelProperty(value = {" "," "})

3.2.格式

3.2.1 日期格式和数字格式

3.2.2 单元格格式

3.2.3 单元格内容格式

3.3 合并单元格

4.写操作的写方法

4.1 普通写方法

4.2 写方法的排除和包含

4.3 动态头和无对象写

4.3.1 动态头

4.3.2 无对象写

5.拦截器

5.1 单元格拦截器

5.2 工作表拦截器

5.3 拦截器的使用

6.总结


1.环境搭建

引入以下依赖:

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>easyexcel</artifactId>
   <version>3.2.1</version>
</dependency>

2.简单的写操作演示

2.1 实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @ExcelProperty(value = "用户编号")
    private Integer userId;
    @ExcelProperty(value = "用户名称")
    private String userName;
    @ExcelProperty(value = "用户性别")
    private String userGender;
    @ExcelProperty(value = "用户年龄")
    private Integer userAge;
    @ExcelProperty(value = "备注")
    private String userStandBy;
}

在实体类中用了@ExcelProperty注解来定义标头,即:

2.2 写入方法

方法1:链式写入

public void writeTest(){
        List<User> users = new ArrayList<>();
        users.add(new User(1,"张老师","男",36,"无"));
        users.add(new User(2,"卢老师","男",28,"Java"));
        users.add(new User(3,"王老师","女",32,"请假"));
        
        //通过EasyExcel的write方法写入,参数为excel的路径,以及类信息
        //sheet方法中的参数为工作表名
        //doWrite方法中的参数为具体数据
        EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user.xlsx",
                User.class)
                .sheet("用户数据")
                .doWrite(users);
    }

方法2:创建对象写入

public void writeTest2(){
        List<User> users = new ArrayList<>();
        users.add(new User(1,"张老师","男",36,"无"));
        users.add(new User(2,"卢老师","男",28,"Java"));
        users.add(new User(3,"王老师","女",32,"请假"));

        //创建Excel写对象,参数为要生成文件的路径,实体类的类型
        ExcelWriter excelWriter = EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user.xlsx",
                User.class)
                .build();
        //创建sheet对象
        WriteSheet writeSheet = EasyExcel.writerSheet("用户数据").build();
        //将数据写到sheet表中
        excelWriter.write(users,writeSheet);
        //关闭流,文件流手动关闭
        excelWriter.finish();
    }

2.3 效果展示

3.写操作的实体类

3.1 表头的内容和顺序

表头的内容和顺序都由@ExcelProperty实现,在这个注解里参数value用于定义表头内容,index用于定义表头顺序

3.1.1 @ExcelProperty(value)

public class User {
    @ExcelProperty(value = "用户编号")
    private Integer userId;
    @ExcelProperty(value = "用户名称")
    private String userName;
    @ExcelProperty(value = "用户性别")
    private String userGender;
    @ExcelProperty(value = "用户年龄")
    private Integer userAge;
    @ExcelProperty(value = "备注")
    private String userStandBy;
}

在上面这段代码中userId在Excel中的表头就是用户编号,其他属性类推

注:上段代码在Excel表中的顺序为定义属性的顺序

3.1.2 @ExcelProperty(index)

public class User {
    @ExcelProperty(index = 0)
    private Integer userId;
    @ExcelProperty(index = 1)
    private String userName;
    @ExcelProperty(index = 2)
    private String userGender;
    @ExcelProperty(index = 3)
    private Integer userAge;
    @ExcelProperty(index = 4)
    private String userStandBy;
}

在以上代码中,index数字是几,这一字段就在第几列(注:在Excel中第几列是从0开始算的),在以上代码中,字段在Excel中的名字就是在实体类的属性名。

3.1.3 @ExcelProperty(value,index)

public class User {
    @ExcelProperty(value = "用户编号",index = 0)
    private Integer userId;
    @ExcelProperty(value = "用户名称",index = 1)
    private String userName;
    @ExcelProperty(value = "用户性别",index = 2)
    private String userGender;
    @ExcelProperty(value = "用户年龄",index = 3)
    private Integer userAge;
    @ExcelProperty(value = "备注",index = 4)
    private String userStandBy;
}

在以上代码中既规定了字段的名字,又规定了在第几列,但不建议这样使用,因为在读一张表的时候可能会冲突

3.1.4 @ExcelProperty(value = {" "," "})

public class ComplexHeadData {
    @ExcelProperty(value = {"用户类别1","用户编号"})
    private Integer userId;
    @ExcelProperty(value = {"用户类别2","用户名称"})
    private String userName;
    @ExcelProperty(value = {"用户类别2","用户年龄"})
    private Integer userAge;
}

这样去写value可以让表头合并,中括号里第一个字符串一样的就合并

3.2.格式

3.2.1 日期格式和数字格式

@DateTimeFormat

设置日期格式

@NumberFormat

设置数字格式

注:设置的只是格式,只是显示的不一样,但写入的依然还是原数据

public class Emp {
    @ExcelProperty("员工ID")
    private Integer empId;
    @ExcelProperty("员工姓名")
    private String empName;
    //格式化小数类型,如果是百分数定义为 #.##% 比如:10.36%
    @NumberFormat("#.#")
    @ExcelProperty("工资")
    private Double salary;
    //格式化时间 yyyy年MM月dd日
    @DateTimeFormat("yyyy年MM月dd日")
    @ExcelProperty("入职时间")
    private Date hireDate;
}

3.2.2 单元格格式

@ContentRowHeight

设置内容列高 

@ColumnWidth

设置内容列宽(实际上也设置标题的宽度,因为在Excel里要格子是对齐的)

@HeadRowHeight

设置标题高度 
 

@ContentRowHeight(30)//设置列高
@ColumnWidth(25)//设置列宽
@HeadRowHeight(60)//设置标题高度
public class Emp {
    @ExcelProperty("员工ID")
    private Integer empId;
    @ColumnWidth(50)//为属性的单元格单独设置列宽
    @ExcelProperty("员工姓名")
    private String empName;
    @ExcelProperty("工资")
    private Double salary;
    @ExcelProperty("入职时间")
    private Date hireDate;
}

3.2.3 单元格内容格式

//头背景设置成红色
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
        fillForegroundColor = 10)

//头字体设置20
@HeadFontStyle(fontHeightInPoints = 20)

//内容的背景色设置成绿色
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
        fillForegroundColor = 17)

//设置内容的字体20
@ContentFontStyle(fontHeightInPoints = 20)

上面的注解既可写在类上方全局生效,也可写在属性上方特定生效

其中表示颜色的数值可通过双击shift键搜索IndexedColors.class查看

3.3 合并单元格

@ContentLoopMerge:可以修饰字段,用于合并单元格

有两个参数:

eachRow :用于行的合并

columnExtend :用于列的合并

@OnceAbsoluteMerge:合并多个单元格

参数一 firstRowIndex:起始行索引 从0开始

参数二 lastRowIndex : 结束行索引

参数三 firstColumnIndex :起始列索引 从0开始

参数四 lastColumnIndex : 结束列索引

//合并(3,3)到(4,4)的单元格
@OnceAbsoluteMerge(firstRowIndex = 3,lastRowIndex = 4,
        firstColumnIndex = 3,lastColumnIndex = 4)
public class MergeData {
    //每隔两行合并一次
    @ContentLoopMerge(eachRow = 2)
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("数字标题")
    private Double doubleData;
}

4.写操作的写方法

4.1 普通写方法

 方法1:链式写入

public void writeTest(){
        List<User> users = new ArrayList<>();
        users.add(new User(1,"张老师","男",36,"无"));
        users.add(new User(2,"卢老师","男",28,"Java"));
        users.add(new User(3,"王老师","女",32,"请假"));
        
        //通过EasyExcel的write方法写入,参数为excel的路径,以及类信息
        //sheet方法中的参数为工作表名
        //doWrite方法中的参数为具体数据
        EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user.xlsx",
                User.class)
                .sheet("用户数据")
                .doWrite(users);
    }

方法2:创建对象写入

public void writeTest2(){
        List<User> users = new ArrayList<>();
        users.add(new User(1,"张老师","男",36,"无"));
        users.add(new User(2,"卢老师","男",28,"Java"));
        users.add(new User(3,"王老师","女",32,"请假"));

        //创建Excel写对象,参数为要生成文件的路径,实体类的类型
        ExcelWriter excelWriter = EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user.xlsx",
                User.class)
                .build();
        //创建sheet对象
        WriteSheet writeSheet = EasyExcel.writerSheet("用户数据").build();
        //将数据写到sheet表中
        excelWriter.write(users,writeSheet);
        //关闭流,文件流手动关闭
        excelWriter.finish();
    }

4.2 写方法的排除和包含

排除

//需要排除的字段放入Set中
        Set<String> sets = new HashSet<>();
        //排除userAge和userStandBy字段
        sets.add("userAge");
        sets.add("userStandBy");
        EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user2.xlsx",User.class)
                .excludeColumnFieldNames(sets)
                .sheet("用户数据")
                .doWrite(users);

包含

//需要写入的字段放入Set当中
        HashSet<String> sets = new HashSet<>();
        //只写入userName和userAge
        sets.add("userName");
        sets.add("userAge");
        EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\user2.xlsx", User.class)
                .includeColumnFieldNames(sets)
                .sheet("用户数据")
                .doWrite(users);

4.3 动态头和无对象写

4.3.1 动态头

动态头是通过一个List<List<String>>实现的,他的每一个List<String>都代表着一列,List<String>里的每一个String都代表一行,例如:

List<List<String>> headers = new ArrayList<>();
headers.add(Arrays.asList("基础信息", "编号"));
headers.add(Arrays.asList("基础信息", "姓名"));
headers.add(Arrays.asList("个人信息", "性别"));

与下面的注解效果一样

public class User {
    @ExcelProperty(value = {"基础信息","编号"})
    private Integer userId;
    @ExcelProperty(value = {"基础信息","姓名"})
    private String userName;
    @ExcelProperty(value = {"个人信息","性别"})
    private String userGender;
}

动态头的使用

public void headTest(){
        EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\head\\head.xlsx")
                //放入动态头
                .head(heads)//生成的动态头
                .sheet("动态头测试")//工作区名字
                .doWrite(new ArrayList<>());//要放入的数据
    }

4.3.2 无对象写

EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\head\\noMode.xlsx")
                .head(heads)//生成的头
                .sheet()
                .doWrite(datas);

无对象写和上面的动态头使用一样,与普通的有对象写的区别就是在write函数中没有对象类型参数

5.拦截器

5.1 单元格拦截器

实现CellWriteHandler接口

public class CustomCellWriteHandler implements CellWriteHandler {

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {

        //单元格数据及状态
        Cell cell = context.getCell();
        //在这里对cell进行操作
        System.out.println(cell.getRowIndex()+"行,"+cell.getColumnIndex()+"列写入完成。");
        //判断是否是第一行第一列数据
        //表头是0行,所以判断是否为1
        if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0){
            //修改第一个数据为程序员
            cell.setCellValue("程序员");
        }

    }
}

5.2 工作表拦截器

实现SheetWriteHandler接口

public class CustomSheetWriteHandler implements SheetWriteHandler {

    @Override
    public void afterSheetCreate(SheetWriteHandlerContext context) {

        //根据sheet名称输出
        System.out.println(context.getWriteSheetHolder().getSheetName()+"写入成功。");

    }
}

5.3 拦截器的使用

EasyExcel.write("E:\\JavaHome\\project\\EasyExcel\\data\\user\\handler.xlsx", User.class)
                //注册单元格拦截器
                .registerWriteHandler(new CustomCellWriteHandler())
                //注册工作表拦截器
                .registerWriteHandler(new CustomSheetWriteHandler())
                .sheet("用户数据")
                .doWrite(users);

6.总结

主要学习了EasyExcel的写操作,包括表头的设置,单元格的格式,内容的格式,无对象写,拦截器等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值