EasyExcel使用(二:写出)

说明:本文介绍 EasyExcel 的写出,关于从 excel 文件中读取数据,参考下面这篇文章:

写出可分不用模板,和使用模板填充两种。

不用模板

(1)搭建环境

先创建一个 Maven 项目,pom.xml 文件如下:

xml 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/>
    </parent>

    <groupId>com.hezy</groupId>
    <artifactId>excel_write_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>excel_write_demo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

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

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.6</version>
        </dependency>
    </dependencies>
</project>

其中,下面这个依赖是 easyexcel 依赖

xml 复制代码
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>easyexcel</artifactId>
	<version>3.3.2</version>
</dependency>

(2)创建对象

创建一个 pojo 对象,对应 excel 文件中的数据

java 复制代码
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentExcel {

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("年龄")
    private Integer age;

    @ExcelProperty("性别")
    private String gender;

    @ExcelIgnore
    private String remark;
}

对象属性上的 @ExcelProperty 里面填 excel 文件中的列名,如果不填会以属性名作为列名;@ExcelIgnore 标记忽略的字段,被标记上的属性不会导出到 excel 文件里。

接着创建一个成员方法,用于生成稍后导出所需要的数据,实际情况就是从数据库中查出来的数据。

java 复制代码
    /**
     * 查询数据
     * @param batch 批次
     * @return 数据
     */
    private List<StudentExcel> selectData(Integer batch) {
        List<StudentExcel> list = ListUtils.newArrayList();
        for (int i = 0; i < batch; i++) {
            list.add(new StudentExcel("张三" + i, 18 + i, "男", "上海市"));
        }
        return list;
    }

(3)导出文件

导出有三种写法,大同小异,第二种可用于分批查询数据库的情况,如果你要使用分批查询,就要考虑事务问题,就是在查询的过程中,其他线程操作了表数据,可能造成导出结果与页面结果不一致。

java 复制代码
    /**
     * 第一种
     */
    @GetMapping("/no-template/one")
    public String excel1() {
        String fileName = "学生信息1.xlsx";
        try (ExcelWriter excelWriter = EasyExcel.write(fileName, StudentExcel.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
            excelWriter.write(selectData(10), writeSheet);
        }
        return "success";
    }

    /**
     * 第二种
     */
    @GetMapping("/no-template/two")
    public String excel2() {
        String fileName = "学生信息2.xlsx";
        EasyExcel.write(fileName, StudentExcel.class)
                .sheet("模板")
                .doWrite(() -> {
                    // 分页查询数据
                    List<StudentExcel> page1 = selectData(10);
                    List<StudentExcel> page2 = selectData(20);
                    List<StudentExcel> pageAll = ListUtils.newArrayList();
                    pageAll.addAll(page1);
                    pageAll.addAll(page2);
                    return pageAll;
                });
        return "success";
    }

    /**
     * 第三种
     */
    @GetMapping("/no-template/three")
    public String excel3() {
        String fileName = "学生信息3.xlsx";
        EasyExcel.write(fileName, StudentExcel.class).sheet("模板").doWrite(selectData(10));
        return "success";
    }

其中,.sheet("模板") 表示设置的 excel 文件工作表名称为"模板"

(4)测试

启动项目,分别调用接口,查看导出文件,都能导出来

设置文件样式

可以在 StudentExcel 对象里,使用注解设置导出文件的样式,如下:

java 复制代码
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ContentRowHeight(36)
@HeadRowHeight(20)
@ColumnWidth(24)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
public class StudentExcel {

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("年龄")
    private Integer age;

    @ExcelProperty("性别")
    private String gender;

    @ExcelIgnore
    private String remark;
}

其中,

  • @ContentRowHeight(36):行高设置为36;

  • @HeadRowHeight(20):行头行高设置为20;

  • @ColumnWidth(24):列宽设置为24;

  • @ContentStyle:内容样式,horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER 为水平居中,垂直居中;

设置完,再次导出,可见样式生效

通过模板导出

上面通过注解设置样式,难以满足实际情况,还可以通过模板导出,创建一个模板,内容(没有内容也是内容)格式如下:

创建一个接口,使用该模板导出,如下:

java 复制代码
    @GetMapping("/template")
    public String excel4() {
        String fileName = "学生信息4.xlsx";
        String templatePath = FileUtil.getWebRoot().getPath() + "/src/main/resources/template/excel/学生信息模板.xlsx";
        EasyExcel.write(fileName, StudentExcel.class).withTemplate(templatePath).sheet("Sheet1").doWrite(selectData(10));
        return "success";
    }

当然,前面给对象设置的那些样式注解就可以去掉了,不然还是会用注解设置的样式

java 复制代码
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
public class StudentExcel {

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("年龄")
    private Integer age;

    @ExcelProperty("性别")
    private String gender;

    @ExcelIgnore
    private String remark;
}

重启项目,调用接口导出,查看导出文件,perfect

模板填充

(1)创建模板

使用模板填充数据,先创建一个模板,如下:

列名下面填对应数据的占位符,用大括号表示,如果填充的数据是集合,用点(.)分割,点前面是集合的变量名,后面是集合内的对象属性名,如果只有一个集合,集合的变量名可省略,就像我上面的这样。

(2)导出

创建一个接口,使用该 excel 模板导出

java 复制代码
    @GetMapping("/template/full")
    public String excel5() {
        String fileName = "学生信息5.xlsx";
        String templatePath = FileUtil.getWebRoot().getPath() + "/src/main/resources/template/excel/full/学生信息模板-填充.xlsx";
        EasyExcel.write(fileName).withTemplate(templatePath).sheet().doFill(selectData(10));
        return "success";
    }

(3)测试

重启项目,调用该接口,可见数据成功导出。但有点小问题,使用模板导出,前面给备注设置的忽略导出注解失效了。

非集合数据

给模板新增一个非集合数据,如下:

如果需要填充的数据,有集合数据,也有非集合数据(键值对数据),就可以使用下面这种写法,分两次填充

java 复制代码
    @GetMapping("/template/full")
    public String excel5() {
        String fileName = "学生信息5.xlsx";
        String templatePath = FileUtil.getWebRoot().getPath() + "/src/main/resources/template/excel/full/学生信息模板-填充.xlsx";
        try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templatePath).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 填充集合数据
            excelWriter.fill(selectData(10), writeSheet);

            // 填充非集合数据
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("recordDate", "2023-01-01");
            excelWriter.fill(dataMap, writeSheet);
        }
        return "success";
    }

重启项目,调用接口,生成的文件如下,可见日期数据也被填入。

参考

更多 EasyExcel 用法,参考官方文档:https://easyexcel.opensource.alibaba.com/docs/current/

更多细节,比如图片怎么插入到文件里,不同的数据类型怎么在导出时转换,也可以查看官网文档。

总结

本文介绍了使用 EasyExcel 如何导出 excel 文件

相关推荐
Penge6662 小时前
Go 接口编译期断言
后端
我是一颗柠檬2 小时前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试
橙淮3 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿3 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影3 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
Ceelog3 小时前
久坐党自救指南:屏幕前 8 小时,身体到底在经历什么
前端·后端
EntyIU4 小时前
JVM内存与GC笔记
java·jvm·笔记
XS0301064 小时前
并发编程 六
java·后端
yaoxin5211234 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道4 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试