Spring Boot 集成 EasyExcel 轻松搞定百万级数据导出

开发
本文将详细介绍如何在 Spring Boot 项目中集成 EasyExcel,实现轻松搞定百万级数据导出。

在企业级应用开发中,数据导出是一个常见的需求。当面临百万级数据导出时,传统的数据导出方式往往会出现性能瓶颈,导致内存溢出、导出速度慢等问题。Spring Boot 框架提供了灵活的开发环境,而 EasyExcel 是一款基于 Java 的高性能 Excel 操作库,能够高效地处理百万级数据导出。本文将详细介绍如何在 Spring Boot 项目中集成 EasyExcel,实现轻松搞定百万级数据导出。

一、环境搭建

在开始之前,我们需要搭建一个 Spring Boot 项目。如果你还没有搭建过 Spring Boot 项目,可以通过 Spring Initializr (https://start.spring.io/) 快速生成一个项目模板。然后,在项目的pom.xml文件中添加 EasyExcel 的依赖。

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- EasyExcel Starter -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.0.5</version>
    </dependency>
</dependencies>

接下来,我们需要配置 Excel 文件的路径和文件名。在application.yml文件中添加以下配置:

excel:
  path: ./excel
  filename-prefix: data_
  headers:
    - id
    - name
    - age
    - department

这里,我们配置了 Excel 文件的存储路径为项目根目录下的excel文件夹,文件名前缀为data_,表头信息包括id、name、age和department。

二、创建 Excel 模型类

为了将数据写入 Excel 文件,我们需要创建一个 Excel 模型类。该类用于表示 Excel 文件中的数据结构,并使用@ExcelProperty注解标记每个字段。

import com.alibaba.excel.annotation.ExcelProperty;

public class DataModel {
    @ExcelProperty("ID")
    private Long id;

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

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

    @ExcelProperty("部门")
    private String department;

    // getter 和 setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }
}

在上面的代码中,我们创建了一个DataModel类,包含了id、name、age和department四个字段。每个字段都使用@ExcelProperty注解标记了对应的表头名称。这样,当我们将数据写入 Excel 文件时,字段值会按照注解中的名称写入对应的列。

三、编写数据导出服务类

数据导出服务类是实现数据导出的核心部分。我们需要从数据库中查询数据,并使用 EasyExcel 将数据写入 Excel 文件。

import com.alibaba.excel.EasyExcel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ExportService {

    @Value("${excel.path}")
    private String excelPath;

    @Value("${excel.filename-prefix}")
    private String filenamePrefix;

    public void exportData(List<DataModel> dataModels) {
        // 生成文件名
        String fileName = excelPath + "/" + filenamePrefix + System.currentTimeMillis() + ".xlsx";
        // 使用 EasyExcel 写入数据
        EasyExcel.write(fileName, DataModel.class).sheet("Sheet1").doWrite(dataModels);
    }
}

在上面的代码中,我们创建了一个ExportService类,用于实现数据导出功能。该类注入了 Excel 文件的存储路径和文件名前缀,并提供了一个exportData方法。在exportData方法中,我们生成了一个唯一的文件名,然后使用 EasyExcel 的write方法将数据写入 Excel 文件。write方法的参数包括文件名、数据模型类和工作表名称,最后通过doWrite方法将数据写入文件。

四、创建控制器类

为了方便用户调用数据导出功能,我们需要创建一个控制器类,暴露 REST API 接口。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class ExportController {

    @Autowired
    private ExportService exportService;

    @GetMapping("/export")
    public String exportData() {
        // 模拟从数据库中查询数据
        List<DataModel> dataModels = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            DataModel dataModel = new DataModel();
            dataModel.setId((long) i);
            dataModel.setName("User" + i);
            dataModel.setAge(30);
            dataModel.setDepartment("Department" + i % 10);
            dataModels.add(dataModel);
        }
        // 调用数据导出服务
        exportService.exportData(dataModels);
        return "Data exported successfully!";
    }
}

在上面的代码中,我们创建了一个ExportController类,用于处理数据导出的请求。该类注入了ExportService类,并提供了一个/export的 GET 请求接口。在exportData方法中,我们模拟了从数据库中查询数据的过程,生成了一个包含 1000000 条数据的列表。然后,调用exportService的数据导出功能,将数据写入 Excel 文件。

五、性能优化

在处理百万级数据导出时,性能优化是关键。EasyExcel 采用流式读写的方式,避免了大量数据对内存的占用。我们可以通过以下方式进行性能优化:

1. 使用异步导出

对于大规模数据导出,可以使用异步处理的方式,避免主线程被阻塞。Spring Boot 提供了@Async注解,可以方便地实现异步导出。

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ExportService {

    @Value("${excel.path}")
    private String excelPath;

    @Value("${excel.filename-prefix}")
    private String filenamePrefix;

    @Async
    public void exportData(List<DataModel> dataModels) {
        // 生成文件名
        String fileName = excelPath + "/" + filenamePrefix + System.currentTimeMillis() + ".xlsx";
        // 使用 EasyExcel 写入数据
        EasyExcel.write(fileName, DataModel.class).sheet("Sheet1").doWrite(dataModels);
    }
}

在上面的代码中,我们在exportData方法上添加了@Async注解,将其标记为异步方法。这样,当用户调用数据导出接口时,数据导出将在后台线程中执行,不会阻塞主线程。

2. 分页查询数据

如果数据量非常大,一次性从数据库中查询所有数据可能会导致内存不足。可以通过分页查询的方式,分批次加载数据,并使用 EasyExcel 将数据分批次写入 Excel 文件。

import com.alibaba.excel.EasyExcel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ExportService {

    @Value("${excel.path}")
    private String excelPath;

    @Value("${excel.filename-prefix}")
    private String filenamePrefix;

    public void exportDataByPage() {
        // 生成文件名
        String fileName = excelPath + "/" + filenamePrefix + System.currentTimeMillis() + ".xlsx";
        // 使用 EasyExcel 写入数据
        EasyExcel.write(fileName, DataModel.class).sheet("Sheet1").doWrite(data -> {
            // 分页查询数据
            for (int pageNum = 1; ; pageNum++) {
                List<DataModel> dataModels = queryDataByPage(pageNum, 1000);
                if (dataModels.isEmpty()) {
                    break;
                }
                data.write(dataModels);
            }
        });
    }

    private List<DataModel> queryDataByPage(int pageNum, int pageSize) {
        // 模拟分页查询数据
        List<DataModel> dataModels = new ArrayList<>();
        int start = (pageNum - 1) * pageSize;
        for (int i = start; i < start + pageSize; i++) {
            DataModel dataModel = new DataModel();
            dataModel.setId((long) i);
            dataModel.setName("User" + i);
            dataModel.setAge(30);
            dataModel.setDepartment("Department" + i % 10);
            dataModels.add(dataModel);
        }
        return dataModels;
    }
}

在上面的代码中,我们使用了分页查询的方式,每次查询 1000 条数据,并将数据分批次写入 Excel 文件。这样可以减少内存的占用,并提高数据导出的性能。

六、测试与验证

在完成数据导出功能的开发后,需要进行测试与验证。我们可以通过以下步骤进行测试:

1. 准备测试数据

首先,我们需要准备一些测试数据。可以使用数据生成工具,或者手动创建一些数据。例如,可以创建一个包含 1000000 条记录的数据库表。

2. 调用数据导出接口

启动 Spring Boot 应用程序,并访问/export接口,触发数据导出功能。

3. 检查导出结果

检查生成的 Excel 文件是否包含所有数据,并且数据格式是否正确。可以使用 Excel 软件打开文件,查看数据是否按照预期排列。

4. 测试性能

可以使用性能测试工具,如 JMeter 或 Gatling,对数据导出接口进行测试,记录导出时间、内存占用、CPU 使用率等指标,评估数据导出功能的性能表现。

责任编辑:赵宁宁 来源: Java技术营地
相关推荐

2024-08-05 09:51:00

2024-08-09 08:52:26

2022-08-01 07:02:06

SpringEasyExcel场景

2025-02-17 00:00:45

接口支付宝沙箱

2024-07-31 09:56:20

2024-11-14 10:38:43

2020-04-23 15:59:04

SpringKafka集群

2025-02-05 09:39:00

2011-04-20 14:28:38

SQL优化

2009-09-13 20:28:38

Linq插入数据

2023-02-03 08:21:30

excelMySQL

2015-05-15 14:51:11

TB 级数据云备份

2023-11-13 08:16:08

MySQL数据数据库

2018-11-02 15:45:41

Spring BootRedis数据库

2020-07-14 11:00:12

Spring BootRedisJava

2021-05-11 07:27:30

Html页面Pdf

2025-02-17 07:48:45

2022-09-16 08:04:25

阿里云权限网络

2023-01-10 07:52:15

2020-09-02 17:28:26

Spring Boot Redis集成
点赞
收藏

51CTO技术栈公众号