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 文件

相关推荐
YuTaoShao12 分钟前
【LeetCode 热题 100】51. N 皇后——回溯
java·算法·leetcode·职场和发展
码事漫谈13 分钟前
C++模板元编程从入门到精通
后端
_風箏13 分钟前
Java【代码 14】一个用于判断磁盘空间和分区表是否需要清理的工具类
后端
_風箏16 分钟前
Java【代码 13】前端动态添加一条记后端使用JDK1.8实现map对象根据key的部分值进行分组(将map对象封装成指定entity对象)
后端
_風箏19 分钟前
Java【代码 12】判断一个集合是否包含另一个集合中的一个或多个元素 retainAll() 及其他方法
后端
null不是我干的31 分钟前
基于黑马教程——微服务架构解析(一)
java·微服务·架构
Java中文社群34 分钟前
Coze开源版?别吹了!
人工智能·后端·开源
Bonnie_121535 分钟前
04-netty基础-Reactor三种模型
java·nio·jetty
懂得节能嘛.38 分钟前
【SpringAI实战】ChatPDF实现RAG知识库
java·后端·spring
探索java43 分钟前
Spring 解析 XML 配置文件的过程(从读取 XML 到生成 BeanDefinition)
xml·java·spring·xmlbeanfactory