EasyExcel 导入、导出文件,参数校验,异常返回

导入数据

实体类

package net.rjgf.wbwf.nanning.domain;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import net.rjgf.common.domain.PageEntity;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;

/**
 * 
 *
 * @author 
 * @date 2022-08-12
 */
public class ImportDedicatedLine implements Serializable {
    private static final long serialVersionUID = 1L;

    @ExcelIgnore
    private PageEntity page;

    /**
     * 主键
     */
    @ExcelIgnore
    private Long id;

    /**
     * 业务主键
     */
    @NotNull(message = "业务标识*不能为空")
    @ExcelProperty(value = "业务标识*")
    private String businessId;

    /**
     * 专线类型
     */
    @NotNull(message = "专线类型*不能为空")
    @ExcelProperty(value = "专线类型*")
    private String type;
}

控制器层


    /**
     * 上传数据
     *
     * @param file 支持.xlsx
     * @return 提示消息
     */
    @PostMapping("/import")
    public Message importDedicatedLine(MultipartFile file) {
        return new Message(importDedicatedLineService.importDedicatedLine(file));
    }

业务层

  /**
     * 上传数据
     *
     * @param file 支持.xlsx
     * @return 提示消息
     */
    @Override
    public List<String> importDedicatedLine(MultipartFile file) {
        List<String> messageList = new ArrayList<String>();
        try {
            //文件流
            EasyExcel.read(file.getInputStream(),
                    //实体类
                    ImportDedicatedLine.class,
                    //监听器
                    new ImportDedicatedLineListener(importDedicatedLineRepository, securityUtils))
                    .sheet("专线").doRead();
        } catch (ExcelAnalysisException e) {
            StringTokenizer st = new StringTokenizer(e.getMessage(), "|");
            while (st.hasMoreElements()) {
                messageList.add(st.nextElement().toString());
            }
            return messageList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return messageList;
    }

监听器

package net.rjgf.wbwf.nanning.listen.easyexcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import net.rjgf.common.util.SecurityUtils;
import net.rjgf.wbwf.nanning.domain.ImportDedicatedLine;
import net.rjgf.wbwf.nanning.repository.ImportDedicatedLineRepository;
import net.rjgf.wbwf.nanning.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.NotNull;
import java.text.MessageFormat;
import java.util.*;

/**
 * 
 *
 * @author 
 * @date 2022-08-12
 */
public class ImportDedicatedLineListener extends AnalysisEventListener<ImportDedicatedLine> {


    private ImportDedicatedLineRepository importDedicatedLineRepository;

    private SecurityUtils securityUtils;

    /**
     * 读取五百条数据,批量插入一次。
     */
    private static final int BATCH_COUNT = 500;

    /**
     * 记录Excel读取的行数
     */
    private int count = 0;

    /**
     * 保存读取成功的Excel数据
     */
    private List<ImportDedicatedLine> list = new ArrayList<>(BATCH_COUNT * 2);

    /**
     * 保存读取失败的Excel消息
     */
    private List<String> errorMessage = new ArrayList<>();

    /**
     * 行头
     */
    private Map headMap = new HashMap<>();

    /**
     * Sprinboot参数校验
     */
    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 构造函数初始化监听器
     */
    public ImportDedicatedLineListener(ImportDedicatedLineRepository importDedicatedLineRepository, SecurityUtils securityUtils) {
        this.importDedicatedLineRepository = importDedicatedLineRepository;
        this.securityUtils = securityUtils;
    }


    /**
     * 获取表头名
     *
     * @param headMap
     * @param context
     */
    @Override
    public void invokeHeadMap(Map headMap, AnalysisContext context) {
        this.headMap = headMap;
    }

	//利用SpringBoot自带的注解进行参数校验 
    public void validate(ImportDedicatedLine importDedicatedLine) {

        Set<ConstraintViolation<ImportDedicatedLine>> validate = validator.validate(importDedicatedLine);
        if (validate.size() > 0) {
            StringBuilder sb = new StringBuilder();
            validate.forEach(it -> {
                sb.append(it.getMessage());
                sb.append("\t");
            });
            throw new ExcelAnalysisException(sb.toString());
        } else {
            importDedicatedLine.setCreateBy(securityUtils.getCurrentUser().getId().toString());
            importDedicatedLine.setCreateTime(new Date());
            this.count = this.count + 1;
        }

    }

    /**
     * 解析到一条数据,对每条数据进行操作
     */
    @Override
    public void invoke(ImportDedicatedLine importDedicatedLine, AnalysisContext analysisContext) {

        validate(importDedicatedLine);

        list.add(importDedicatedLine);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }


    /**
     * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
     *
     * @param exception
     * @param context
     * @throws Exception
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        String mes = null;
        if (exception instanceof ExcelDataConvertException) {
            //转换格式发生的异常,不会进入invoke解析,这里要++ 把解析失败数据也加上
            this.count = this.count + 1;
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            // 获取列名
            String columnName = (String) this.headMap.get(excelDataConvertException.getColumnIndex());
            // 获取行
            int row = excelDataConvertException.getRowIndex();
            // 获取出错的单元块
            String cellData = excelDataConvertException.getCellData().toString();
            mes = MessageFormat.format("错误发生在{0}行,{1}列,数据为:{2}", (row + 1), columnName, cellData);
        }
        // 自定义抛出的异常
        else {
            mes = MessageFormat.format("错误发生在{0}行,原因为:{1},", this.count, exception.getMessage());
        }
        errorMessage.add(mes);
    }


    /**
     * 读取所有数据完毕进行的操作
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (list.size() > 0) {
            saveData();
            list.clear();
        }
        StringBuilder sb = new StringBuilder();
        String countMessage = MessageFormat.format(
                "一共{0}条数据,成功导入{1}条数据,重复数据不会插入:",
                this.count, this.count - this.errorMessage.size());
        sb.append(countMessage);
        //将错误信息用字符串返回
        if (this.errorMessage.size() > 0) {
            errorMessage.forEach((it) -> {
                sb.append("|");
                sb.append(it);
            });
        }
        throw new ExcelAnalysisException(sb.toString());
    }

    /**
     * 具体执行读取到的excel数据进行存储的逻辑,比如写入到mysql等操作
     */
    private void saveData() {
        importDedicatedLineRepository.batchInsert(list);
    }

}

导出数据

这里导出到服务器硬盘

  @Override
    public String exportDedicatedLine(ImportDedicatedLine importDedicatedLine) {

        String fileName = "xxx" + DateUtil.getNowYYYYMMDDHHMMSS2() + ExcelTypeEnum.XLSX.getValue();
        String filePath = uploadDir + fileName;

        ExcelWriter excelWriter = EasyExcel.write(filePath).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(0, "专线").head(ImportDedicatedLine.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();

        //获取总数据量
        int count = importDedicatedLineRepository.getCount(importDedicatedLine);
        //最大导出数量
        int exportCount = 500;

        if (count > exportCount) {
            //分批查询数据库次数
            int countTime = count / exportCount + 1;
            for (int i = 0; i < countTime; i++) {
                Page page = PageHelper.startPage(i + 1, exportCount);
                List<ImportDedicatedLine> exportList = importDedicatedLineRepository
                        .selectImportDedicatedLineList(importDedicatedLine);
                excelWriter.write(exportList, writeSheet);
            }
        } else {
            List<ImportDedicatedLine> exportList = importDedicatedLineRepository
                    .selectImportDedicatedLineList(importDedicatedLine);
            excelWriter.write(exportList, writeSheet);
        }
        //刷新流
        excelWriter.finish();
        return fileName;
    }
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: Spring Boot 是一个用于创建基于 Spring 框架的独立、生产级别的应用程序的框架。EasyExcel 是一个基于 Java 的开源框架,可以方便地读写 Excel 文件。使用 EasyExcel 可以轻松地进行 Excel 文件导入导出,非常适合在 Spring Boot 项目中使用。 下面是在 Spring Boot 项目中使用 EasyExcel 进行 Excel 文件导入导出的基本步骤: 1. 添加 EasyExcel 依赖 在项目的 pom.xml 文件中添加 EasyExcel 依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency> ``` 2. 编写 Excel 导出代码 使用 EasyExcel 可以非常方便地进行 Excel 文件导出。例如,以下代码可以将一个 List 对象导出为 Excel 文件: ```java // 定义 Excel 表头 List<List<String>> head = new ArrayList<>(); head.add(Arrays.asList("姓名", "年龄")); // 定义 Excel 数据 List<List<Object>> data = new ArrayList<>(); data.add(Arrays.asList("张三", 18)); data.add(Arrays.asList("李四", 20)); data.add(Arrays.asList("王五", 22)); // 导出 Excel 文件 String fileName = "example.xlsx"; String sheetName = "Sheet1"; EasyExcel.write(fileName).sheet(sheetName).head(head).sheet().doWrite(data); ``` 3. 编写 Excel 导入代码 使用 EasyExcel 进行 Excel 文件导入也非常方便。例如,以下代码可以从 Excel 文件中读取数据并转换为一个 List 对象: ```java // 定义读取 Excel 文件的监听器 public class ExcelListener extends AnalysisEventListener<Object> { private List<Object> data = new ArrayList<>(); @Override public void invoke(Object object, AnalysisContext context) { data.add(object); } @Override public void doAfterAllAnalysed(AnalysisContext context) {} public List<Object> getData() { return data; } } // 读取 Excel 文件 String fileName = "example.xlsx"; ExcelListener listener = new ExcelListener(); EasyExcel.read(fileName, listener).sheet().doRead(); List<Object> data = listener.getData(); ``` 4. 将 Excel 文件导入数据库 读取 Excel 文件之后,可以将数据存入数据库中。以下代码演示了将读取的 Excel 文件中的数据存入 MySQL 数据库的过程: ```java // 定义实体类 @Data public class Person { private String name; private Integer age; } // 保存数据数据库 List<Person> persons = new ArrayList<>(); for (Object obj : data) { List<Object> row = (List<Object>) obj; Person person = new Person(); person.setName((String) row.get(0)); person.setAge((Integer) row.get(1)); persons.add(person); } personRepository.saveAll(persons); ``` 以上就是使用 EasyExcel 进行 Excel 文件导入导出的基本步骤。根据实际需求,可以对以上代码进行相应的修改和扩展。 ### 回答2: Spring Boot 是一个开源的Java开发框架,可以帮助开发人员快速构建基于Spring的应用程序。EasyExcel 是一种基于Java的Excel读写工具,它提供了简单便捷的API,可以方便地实现Excel的导入导出功能。 在Spring Boot中使用EasyExcel进行导入导出操作非常简单。首先,我们需要在pom.xml文件中添加EasyExcel的依赖项,以便可以使用它的功能。然后,我们可以创建一个Controller类来处理导入导出的请求。 对于导入操作,我们可以使用EasyExcel提供的@ExcelProperty注解来标记实体类的字段与Excel的列的映射关系。然后,我们可以使用EasyExcel的read方法来读取Excel文件,并将数据转换为实体类对象。最后,我们可以对读取到的数据进行相应的业务操作,比如存储到数据库中。 对于导出操作,我们可以使用EasyExcel的@ExcelProperty注解标记实体类的字段,并使用EasyExcel的write方法来将实体类列表写入Excel文件。我们可以通过指定文件路径或输出流的方式进行导出。 除了基本的导入导出功能,EasyExcel还提供了一些高级特性,比如读取大文件、多sheet处理、自定义读写处理器等。这些特性可以帮助我们更好地应对复杂的Excel导入导出需求。 总而言之,Spring Boot结合EasyExcel提供了一种简单快捷的方式来实现Excel的导入导出功能。无论是处理简单的Excel文件还是应对复杂的导入导出需求,Spring Boot和EasyExcel都能够提供强大的支持。 ### 回答3: Spring Boot 是一种简化了开发过程的Java框架,而EasyExcel是一种用于操作Excel文件的开源库。通过结合使用Spring Boot和EasyExcel,我们可以方便地实现Excel文件导入导出功能。下面将详细介绍如何使用Spring Boot和EasyExcel来实现导入导出功能。 首先,我们需要在Spring Boot的项目中引入EasyExcel的依赖。在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.6</version> </dependency> ``` 接着,我们可以创建一个Controller类来处理导入导出的请求。在该类中,我们可以定义两个方法,一个用于导入Excel文件,另一个用于导出Excel文件。 对于导入功能,我们可以使用EasyExcel提供的`read()`方法来读取Excel文件,并将读取到的数据转换为一个List对象。以下是一个简单的导入方法的示例代码: ```java @PostMapping("/import") public void importExcel(@RequestParam("file") MultipartFile file) throws IOException { List<DataDTO> dataList = EasyExcel.read(file.getInputStream()).head(DataDTO.class).sheet().doReadSync(); // 处理导入数据 } ``` 对于导出功能,我们可以使用EasyExcel提供的`write()`方法来创建一个Excel文件,并将数据写入到该文件中。以下是一个简单的导出方法的示例代码: ```java @GetMapping("/export") public void exportExcel(HttpServletResponse response) throws IOException { List<DataDTO> dataList = getDataList(); // 获取导出数据 response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("data.xlsx", "utf-8")); EasyExcel.write(response.getOutputStream()).sheet("Data").doWrite(dataList); } ``` 在上述代码中,我们首先获取需要导出数据(getDataList()方法需要根据实际情况实现),然后设置响应头信息,最后使用`write()`方法将数据写入到响应的输出流中。 通过以上步骤,我们在Spring Boot项目中成功实现了使用EasyExcel进行Excel文件导入导出功能。我们可以根据具体需求对导入数据进行处理,也可以根据实际情况设置导出文件的格式和名称。同时,EasyExcel还提供了更多的功能和选项,如设置表头、导入数据校验等,可以根据具体需求进行使用。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值