Quantcast
Channel: 小蓝博客
Viewing all articles
Browse latest Browse all 3145

使用SpringBoot实现EasyExcel的读写功能

$
0
0

使用Spring Boot实现EasyExcel的读写功能 📊📥📤

在现代企业应用中,Excel作为常用的数据交换格式,广泛应用于数据分析、报表生成等场景。而在Java生态中,EasyExcel作为阿里巴巴开源的高性能Excel处理工具,因其简洁高效的特点,受到了众多开发者的青睐。结合Spring Boot的快速开发能力,本文将详细介绍如何在Spring Boot项目中集成并实现EasyExcel的读写功能,帮助开发者构建高效的数据处理应用。🚀✨

📌 目录

  1. 项目准备
  2. 环境搭建
  3. 实现Excel写操作
  4. 实现Excel读操作
  5. 完整代码示例
  6. 最佳实践与优化
  7. 总结

🛠️ 项目准备

在开始之前,请确保您的开发环境中已安装以下工具:

  • JDK 8 或以上版本
  • Maven 构建工具
  • IDE(如 IntelliJ IDEA)
  • Spring Boot 框架
  • EasyExcel

🔧 环境搭建

1. 创建Spring Boot项目

使用Spring Initializr或IDE创建一个新的Spring Boot项目,选择以下依赖:

  • Spring Web
  • Spring Boot DevTools
  • EasyExcel(需手动添加)

2. 添加EasyExcel依赖

在项目的 pom.xml文件中添加EasyExcel的依赖:

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- EasyExcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.0.5</version>
    </dependency>

    <!-- Lombok (可选,用于简化代码) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

解释

  • Spring Boot Starter Web:提供构建Web应用所需的基础设施。
  • EasyExcel:用于高效处理Excel文件的库。
  • Lombok:简化Java代码(可选)。

📄 实现Excel写操作

1. 定义数据模型

首先,定义一个用于导出的数据模型。例如,创建一个 User类:

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @ExcelProperty("用户ID")
    private Integer id;

    @ExcelProperty("用户名")
    private String name;

    @ExcelProperty("邮箱")
    private String email;
}

解释

  • @ExcelProperty:指定Excel列的名称。
  • Lombok注解@Data生成getter和setter,@AllArgsConstructor@NoArgsConstructor生成全参和无参构造方法。

2. 创建写入服务

实现一个服务类,用于将数据写入Excel文件:

import com.alibaba.excel.EasyExcel;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ExcelWriteService {

    /**
     * 将用户数据写入Excel文件
     * @param users 用户列表
     * @param filePath 文件路径
     */
    public void writeUsersToExcel(List<User> users, String filePath) {
        EasyExcel.write(filePath, User.class)
                .sheet("用户信息")
                .doWrite(users);
    }
}

解释

  • EasyExcel.write:指定写入的文件路径和数据模型。
  • sheet:定义Excel的工作表名称。
  • doWrite:执行写入操作。

3. 创建Controller接口

提供一个REST接口,触发Excel写操作:

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

import java.util.Arrays;
import java.util.List;

@RestController
public class ExcelController {

    @Autowired
    private ExcelWriteService excelWriteService;

    @GetMapping("/export")
    public String exportExcel() {
        List<User> users = Arrays.asList(
                new User(1, "Alice", "alice@example.com"),
                new User(2, "Bob", "bob@example.com"),
                new User(3, "Charlie", "charlie@example.com")
        );

        String filePath = "users.xlsx";
        excelWriteService.writeUsersToExcel(users, filePath);
        return "Excel文件已生成:" + filePath;
    }
}

解释

  • /export:当访问该URL时,生成并下载Excel文件。
  • 用户数据:示例用户数据列表。

📥 实现Excel读操作

1. 创建读处理类

实现一个监听器,用于处理读取的Excel数据:

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserDataListener extends AnalysisEventListener<User> {

    @Override
    public void invoke(User user, AnalysisContext context) {
        log.info("读取到一条数据: {}", user);
        // 这里可以将数据保存到数据库或进行其他处理
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有数据读取完成!");
    }
}

解释

  • invoke:每读取一条数据时调用。
  • doAfterAllAnalysed:所有数据读取完成后调用。

2. 创建读取服务

实现一个服务类,用于从Excel文件中读取数据:

import com.alibaba.excel.EasyExcel;
import org.springframework.stereotype.Service;

@Service
public class ExcelReadService {

    /**
     * 从Excel文件中读取用户数据
     * @param filePath 文件路径
     */
    public void readUsersFromExcel(String filePath) {
        EasyExcel.read(filePath, User.class, new UserDataListener())
                .sheet("用户信息")
                .doRead();
    }
}

解释

  • EasyExcel.read:指定读取的文件路径和数据模型。
  • UserDataListener:处理读取的数据。
  • sheet:定义读取的工作表名称。
  • doRead:执行读取操作。

3. 创建Controller接口

提供一个REST接口,触发Excel读操作:

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

@RestController
public class ExcelController {

    @Autowired
    private ExcelReadService excelReadService;

    @GetMapping("/import")
    public String importExcel() {
        String filePath = "users.xlsx";
        excelReadService.readUsersFromExcel(filePath);
        return "Excel文件已读取:" + filePath;
    }
}

解释

  • /import:当访问该URL时,读取并处理Excel文件。
  • 文件路径:指定要读取的Excel文件路径。

📋 完整代码示例

1. pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>easyexcel-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>easyexcel-demo</name>
    <description>Spring Boot项目集成EasyExcel示例</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
    </parent>
    <dependencies>
        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- EasyExcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- Spring Boot Maven Plugin -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. User.java

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @ExcelProperty("用户ID")
    private Integer id;

    @ExcelProperty("用户名")
    private String name;

    @ExcelProperty("邮箱")
    private String email;
}

3. ExcelWriteService.java

import com.alibaba.excel.EasyExcel;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ExcelWriteService {

    /**
     * 将用户数据写入Excel文件
     * @param users 用户列表
     * @param filePath 文件路径
     */
    public void writeUsersToExcel(List<User> users, String filePath) {
        EasyExcel.write(filePath, User.class)
                .sheet("用户信息")
                .doWrite(users);
    }
}

4. UserDataListener.java

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserDataListener extends AnalysisEventListener<User> {

    @Override
    public void invoke(User user, AnalysisContext context) {
        log.info("读取到一条数据: {}", user);
        // 这里可以将数据保存到数据库或进行其他处理
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有数据读取完成!");
    }
}

5. ExcelReadService.java

import com.alibaba.excel.EasyExcel;
import org.springframework.stereotype.Service;

@Service
public class ExcelReadService {

    /**
     * 从Excel文件中读取用户数据
     * @param filePath 文件路径
     */
    public void readUsersFromExcel(String filePath) {
        EasyExcel.read(filePath, User.class, new UserDataListener())
                .sheet("用户信息")
                .doRead();
    }
}

6. ExcelController.java

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

import java.util.Arrays;
import java.util.List;

@RestController
public class ExcelController {

    @Autowired
    private ExcelWriteService excelWriteService;

    @Autowired
    private ExcelReadService excelReadService;

    /**
     * 导出Excel文件
     * @return 提示信息
     */
    @GetMapping("/export")
    public String exportExcel() {
        List<User> users = Arrays.asList(
                new User(1, "Alice", "alice@example.com"),
                new User(2, "Bob", "bob@example.com"),
                new User(3, "Charlie", "charlie@example.com")
        );

        String filePath = "users.xlsx";
        excelWriteService.writeUsersToExcel(users, filePath);
        return "Excel文件已生成:" + filePath;
    }

    /**
     * 导入Excel文件
     * @return 提示信息
     */
    @GetMapping("/import")
    public String importExcel() {
        String filePath = "users.xlsx";
        excelReadService.readUsersFromExcel(filePath);
        return "Excel文件已读取:" + filePath;
    }
}

📊 工作流程图

graph TD;
    A[用户请求导出Excel] --> B[控制器调用写服务]
    B --> C[写服务调用EasyExcel写入]
    C --> D[生成Excel文件]
    D --> E[返回成功信息]

    A2[用户请求导入Excel] --> B2[控制器调用读服务]
    B2 --> C2[读服务调用EasyExcel读取]
    C2 --> D2[触发监听器处理数据]
    D2 --> E2[返回成功信息]

🔧 最佳实践与优化

1. 合理设计数据模型

确保数据模型类(如 User)的字段与Excel列名准确对应,使用**@ExcelProperty**注解明确映射关系,避免数据错位。

2. 处理大数据量

对于大规模数据的读写操作,采用分批处理和流式读取,防止内存溢出。

public class UserDataListener extends AnalysisEventListener<User> {
    private static final int BATCH_SIZE = 1000;
    private List<User> cachedDataList = new ArrayList<>();

    @Override
    public void invoke(User user, AnalysisContext context) {
        cachedDataList.add(user);
        if (cachedDataList.size() >= BATCH_SIZE) {
            saveData();
            cachedDataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
    }

    private void saveData() {
        // 批量保存数据到数据库
    }
}

解释

  • BATCH\_SIZE:定义每批处理的数据量。
  • saveData:实现批量保存逻辑,提高效率。

3. 错误处理

在读写操作中加入异常处理机制,确保程序的稳定性和数据的完整性。

public void writeUsersToExcel(List<User> users, String filePath) {
    try {
        EasyExcel.write(filePath, User.class)
                .sheet("用户信息")
                .doWrite(users);
    } catch (Exception e) {
        // 记录日志或通知管理员
        log.error("写入Excel失败:", e);
    }
}

4. 使用模板

对于复杂的Excel格式,可以使用模板文件,确保生成的Excel符合预期的格式和样式。

EasyExcel.write(filePath, User.class)
        .withTemplate("template.xlsx")
        .sheet()
        .doWrite(users);

解释

  • withTemplate:指定模板文件路径,生成的Excel将基于该模板。

5. 性能优化

  • 设置初始内存缓冲区:通过调整EasyExcel的内存缓冲参数,提升大数据量处理的性能。
  • 并发处理:利用多线程或异步处理,提高读写速度。

📈 实际应用实例

示例:导出用户数据到Excel

  1. 访问 http://localhost:8080/export
  2. 服务端生成 users.xlsx文件,包含用户信息。
  3. 返回提示信息“Excel文件已生成:users.xlsx”。

示例:导入用户数据从Excel

  1. 确保 users.xlsx文件存在于项目根目录。
  2. 访问 http://localhost:8080/import
  3. 服务端读取Excel文件,触发监听器处理数据。
  4. 返回提示信息“Excel文件已读取:users.xlsx”。

📊 HashSet与HashMap对比表

特性HashSetHashMap
接口实现实现 Set接口实现 Map接口
存储方式存储独立元素存储键值对
元素唯一性每个元素唯一每个键唯一,值可重复
内部结构基于 HashMapkey存储自身实现哈希表结构
常用方法add(),remove(),contains()put(),get(),remove(),containsKey()
适用场景存储唯一对象,快速查找存储键值映射,快速访问和更新
性能高效的元素存储和查找高效的键值对存储和查找

解释

  • 接口实现HashSet实现了 Set接口,专注于元素的唯一性;HashMap实现了 Map接口,专注于键值对的存储和管理。
  • 存储方式HashSet仅存储元素本身,而 HashMap存储的是键值对,键必须唯一。

🎯 总结

Spring Boot项目中集成EasyExcel,能够极大地简化Excel文件的读写操作,提高开发效率和代码的可维护性。通过本文的详细介绍,您可以:

  • 快速搭建Spring Boot项目并集成EasyExcel。
  • 实现高效的Excel读写功能,处理大规模数据。
  • 掌握数据模型设计、错误处理、性能优化等关键技术。

掌握EasyExcel的读写功能,不仅能提升数据处理的效率,还能为构建复杂的数据交互应用提供强有力的支持。无论是导出报表还是导入数据,结合Spring Boot的便利性,开发者可以轻松应对各种Excel相关的需求。💪🌟

SpringBoot #EasyExcel #Java #数据处理 #编程技巧


Viewing all articles
Browse latest Browse all 3145

Trending Articles