SpringBoot整合easyExcel实现CSV格式文件的导入导出

文章介绍了在SpringMVC项目中如何处理CSV文件,包括使用ApachePOI库解析和验证文件格式,EasyExcel进行数据读写,以及使用Hutool工具进行CSV文件导出。还提到了POM依赖配置和上传CSV文件的处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一:pom依赖

二:检查CSV内容格式的工具类

三:Web端进行测试

四:拓展使用


一:pom依赖

 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!-- java.lang.NoClassDefFoundError: org/apache/commons/compress/utils/Lists -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.21</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.26</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-csv</artifactId>
            <version>1.9.0</version>
        </dependency>

        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>5.6</version> <!-- 使用最新版本 -->
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.73</version>
        </dependency>

二:检查CSV内容格式的工具类

checkCscUtils.java
package com.example.juc.test.Controller;

/**
 * @Author 
 * @Date Created in  2023/12/5 17:32
 * @DESCRIPTION:  判断csv 文件内容是否正确
 * @Version V1.0
 */

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class checkCscUtils {
    public static boolean isCsvFormatValid(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
             CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.
                     withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim())) {
            // 获取标题
            List<String> headers = parser.getHeaderNames();
            int numberOfColumns = headers.size();

            for (CSVRecord record : parser) {
                // 检查列数是否一致
                if (record.size() != numberOfColumns) {
                    return false;
                }
                // 这里可以添加更多的检查,例如检查数据类型等
            }
        } catch (IOException e) {
            e.printStackTrace();
            // 如果发生异常,认为格式不正确
            return false;
        }
        // 所有检查都通过,则认为格式正确
        return true;
    }
}

三:Web端进行测试



/**
 * @Author 
 * @Date Created in  2023/11/2 10:59
 * @DESCRIPTION: 读取csv格式的文件数据
 * @Version V1.0
 */

@RestController
@RequestMapping("/api/csv")
public class CsvController {

    /**
     * 读取传入的csv  文本的内容可以存入数据库
     *
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public ResponseEntity<?> uploadCsv(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("文件不能为空");
        }
        //判断csv文件类型是不是csv文件
        String contentType = file.getContentType();
        String originalFilename = file.getOriginalFilename();
        boolean isCsv = ("text/csv".equals(contentType))
                || (originalFilename != null && originalFilename.endsWith(".csv"));
        if (!isCsv) {
            return ResponseEntity.badRequest().body("文件必须是CSV格式");
        }
        //判断csv文件格式内容是否有误?
        boolean csvFormatValid = checkCscUtils.isCsvFormatValid(file);
        if (csvFormatValid) {
            List<User> userList = new CopyOnWriteArrayList<>();
            try {
                EasyExcel.read(file.getInputStream(), User.class,
                                new PageReadListener<User>(userList::addAll))
                        .excelType(ExcelTypeEnum.CSV)
                        .sheet()
                        .doRead();
            } catch (IOException e) {
                e.printStackTrace();
                return ResponseEntity.status(500).body("文件读取出错");
            }

            // 处理userList...

            return ResponseEntity.ok(userList);
        }
        return ResponseEntity.status(500).body("文件格式出错");
    }

    /**
     * 使用 easyExcel  导出一个csv 格式,但是版本可能与poi 版本冲突
     *
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping("/exportCsv")
    public ResponseEntity<?> exportCsv(HttpServletResponse response) throws IOException {
        // 设置响应头
        response.setContentType("application/csv");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("export_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
                + ".csv");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

        List<Student> userList = getStudents();

        // 使用EasyExcel导出CSV文件response.getOutputStream()
        try {
            EasyExcel.write(response.getOutputStream(), Student.class)
                    .excelType(ExcelTypeEnum.CSV)
                    .sheet("我的学生")
                    .doWrite(userList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ResponseEntity.status(200).body("文件导出成功");
    }



 


    private static List<Student> getStudents() {
        // 创建数据列表
        List<Student> userList = new CopyOnWriteArrayList<>();
        // 添加数据(示例)
        userList.add(new Student("1", "John Doe", "25"));
        userList.add(new Student("2", "Jane Smith", "30"));
        userList.add(new Student("3", "Mike Johnson", "35"));
        return userList;
    }
}

四:拓展使用

使用hutool工具类来进行导出功能

    /**
     * 使用 hutool 工具类生成一个csv格式的文档
     *
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping("/exportCsvHutool")
    public ResponseEntity<?> exportCsvHutool(HttpServletResponse response) throws IOException {
        List<Student> userList = getStudents();
        // 业务处理完成把数据写到流中 响应到页面上
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" +
                new String("exportCsvFileTest.csv".getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
        response.setContentType(String.valueOf(StandardCharsets.UTF_8));
        CsvWriter csvWriter = CsvUtil.getWriter(response.getWriter());
        csvWriter.writeBeans(userList);
        csvWriter.close();

        return ResponseEntity.status(200).body("文件导出成功");
    }

<think>好的,用户想了解如何在Spring Boot中导入CSV文件。我需要分步骤解释清楚。首先,得确定用户的需求是什么,可能他们需要将CSV数据读取到应用里,可能用于处理或者存储到数据库。 首先,我应该考虑CSV文件的解析方式。常用的库有OpenCSV和Apache Commons CSV,两者各有优势。OpenCSV比较流行,文档也多,可能更适合新手。不过用户可能有自己的偏好,所以可能需要提到不同的库选项。 接下来,项目配置部分。用户需要在pom.xml中添加相关依赖,比如OpenCSV的依赖。要给出具体的Maven坐标,这样用户可以直接复制粘贴。同时,确保他们使用的是正确的版本,不过可能版本号可以留空,让用户自行选择最新版。 然后,创建实体类。这部分需要根据CSV的结构定义对应的Java类,用注解来映射字段。比如,用户可能有CSV的列名,用@CsvBindByName注解来绑定。需要提醒用户根据实际CSV结构调整字段和注解。 接下来是读取CSV文件的具体步骤。需要说明如何通过Reader读取文件,然后使用CsvToBeanBuilder来解析。代码示例要清晰,包括异常处理,比如IOException,以及使用ResourceUtils获取文件路径。 如果是上传文件的话,可能需要处理MultipartFile,这部分可以分步骤讲解,包括创建控制器,处理POST请求,将上传的文件转换为输入流,再解析成对象列表。同时,提醒用户处理文件上传的相关配置,比如最大文件大小限制。 另外,如果用户需要将数据存储到数据库,可以简单提到如何集成JPA或者MyBatis,定义Repository接口,调用saveAll方法保存数据。这部分可能需要用户已经有相关的依赖和配置,所以需要适当说明前提条件。 可能还需要考虑异常处理,比如文件不存在、格式错误等情况,提醒用户添加必要的异常捕获和处理逻辑,避免应用崩溃。同时,性能方面,如果处理大文件,可能需要分批次读取或者使用流式处理,避免内存溢出。 最后,总结整个过程,确保每个步骤都覆盖到,并且给出完整的代码示例,让用户能够直接参考实现。可能需要检查代码中的语法是否正确,比如是否正确关闭资源,是否正确使用try-with-resources等。</think>在Spring Boot中导入CSV文件可通过以下步骤实现: --- ### **1. 添加依赖** 在`pom.xml`中添加解析CSV的库(推荐使用OpenCSV): ```xml <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>5.7.1</version> </dependency> ``` --- ### **2. 创建实体类** 假设CSV文件格式如下: ```csv id,name,email 1,张三,[email protected] 2,李四,[email protected] ``` 对应的Java实体类: ```java public class User { @CsvBindByName(column = "id") private Long id; @CsvBindByName(column = "name") private String name; @CsvBindByName(column = "email") private String email; // 省略getter/setter } ``` --- ### **3. 读取CSV文件** #### 方式1:从本地文件读取 ```java public List<User> readCsvFile(String filePath) throws IOException { try (Reader reader = new FileReader(ResourceUtils.getFile(filePath))) { CsvToBean<User> csvToBean = new CsvToBeanBuilder<User>(reader) .withType(User.class) .withIgnoreLeadingWhiteSpace(true) .build(); return csvToBean.parse(); } } ``` #### 方式2:处理上传文件(通过HTTP请求) ```java @PostMapping("/upload") public String uploadCsv(@RequestParam("file") MultipartFile file) { try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) { CsvToBean<User> csvToBean = new CsvToBeanBuilder<User>(reader) .withType(User.class) .build(); List<User> users = csvToBean.parse(); // 后续处理逻辑(如保存到数据库) return "成功导入 " + users.size() + " 条记录"; } catch (IOException e) { return "文件处理失败: " + e.getMessage(); } } ``` --- ### **4. 存储到数据库(可选)** 如果使用Spring Data JPA: ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // 省略getter/setter } public interface UserRepository extends JpaRepository<User, Long> {} // 在Service中调用 @Autowired private UserRepository userRepository; public void saveUsers(List<User> users) { userRepository.saveAll(users); } ``` --- ### **5. 注意事项** 1. **文件编码**:确保读取文件时使用正确的编码(如UTF-8) 2. **异常处理**:添加对空文件、格式错误等情况的处理 3. **性能优化**:大文件建议分批次读取 4. **CSV配置**:通过`CsvToBeanBuilder`自定义分隔符等: ```java .withSeparator(';') // 指定分隔符 .withSkipLines(1) // 跳过标题行 ``` --- ### **完整调用示例** ```java @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private UserRepository userRepository; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { List<User> users = readCsvFile("classpath:data.csv"); userRepository.saveAll(users); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大怪~将军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值