若依框架中实现Excel导入导出功能

2025-06发布2次浏览

在若依框架(RuoYi)中实现Excel导入导出功能,是一个常见的需求场景。本文将详细介绍如何基于Spring Boot和Apache POI库在若依框架中实现这一功能,并提供代码示例和流程解析。


一、技术背景

  1. 若依框架
    若依框架是一个基于Spring Boot的快速开发平台,内置了权限管理、代码生成器等功能,适合企业级应用开发。

  2. Apache POI
    Apache POI 是一个开源的 Java API,用于操作 Microsoft Office 文件格式(如 Excel)。它支持 .xls.xlsx 格式文件的读写。

  3. Excel 导入导出需求

    • 导出:将数据库中的数据以表格形式导出到 Excel 文件。
    • 导入:将 Excel 文件中的数据解析并存储到数据库中。

二、实现步骤

1. 引入依赖

pom.xml 中添加 Apache POI 的相关依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

2. 创建实体类

假设我们需要操作用户信息表,创建对应的实体类 User

@Data
public class User {
    private Long id;
    private String username;
    private Integer age;
    private String email;
}

3. 实现 Excel 导出功能

(1)定义导出方法

在服务层(Service)中定义导出方法,查询数据库并将结果转换为 Excel 文件。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public ByteArrayOutputStream exportUsers() throws Exception {
        List<User> users = userRepository.findAll(); // 查询所有用户数据

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("用户列表");

        // 设置表头
        Row headerRow = sheet.createRow(0);
        String[] headers = {"ID", "用户名", "年龄", "邮箱"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }

        // 填充数据
        int rowNum = 1;
        for (User user : users) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(user.getId());
            row.createCell(1).setCellValue(user.getUsername());
            row.createCell(2).setCellValue(user.getAge());
            row.createCell(3).setCellValue(user.getEmail());
        }

        // 将工作簿写入字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        workbook.write(byteArrayOutputStream);
        workbook.close();

        return byteArrayOutputStream;
    }
}
(2)控制器层调用

在控制器中调用服务层方法,设置响应头以下载文件。

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/export")
    public ResponseEntity<byte[]> exportUsers() throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = userService.exportUsers();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "users.xlsx");

        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }
}

4. 实现 Excel 导入功能

(1)定义导入方法

在服务层中定义导入方法,解析 Excel 文件并将数据保存到数据库。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> importUsers(InputStream fileInputStream) throws Exception {
        List<User> users = new ArrayList<>();
        Workbook workbook = new XSSFWorkbook(fileInputStream);
        Sheet sheet = workbook.getSheetAt(0);

        for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 跳过表头
            Row row = sheet.getRow(i);
            if (row != null) {
                User user = new User();
                user.setId((long) getCellValue(row.getCell(0)));
                user.setUsername(getCellValue(row.getCell(1)).toString());
                user.setAge((int) getCellValue(row.getCell(2)));
                user.setEmail(getCellValue(row.getCell(3)).toString());
                users.add(user);
            }
        }

        userRepository.saveAll(users); // 批量保存到数据库
        workbook.close();
        return users;
    }

    private Object getCellValue(Cell cell) {
        if (cell == null) return "";
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            default:
                return "";
        }
    }
}
(2)控制器层调用

在控制器中接收上传的文件并调用服务层方法。

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/import")
    public String importUsers(@RequestParam("file") MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            userService.importUsers(inputStream);
            return "导入成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "导入失败:" + e.getMessage();
        }
    }
}

三、扩展讨论

  1. 性能优化

    • 对于大数据量的导出,可以使用分页查询和流式写入方式,避免一次性加载过多数据导致内存溢出。
    • 使用 SXSSFWorkbook 替代 XSSFWorkbook,减少内存占用。
  2. 异常处理

    • 在导入过程中,增加数据校验逻辑,确保字段格式正确。
    • 提供详细的错误提示信息,便于用户排查问题。
  3. 模板下载
    提供一个 Excel 模板供用户下载,确保导入数据格式一致。