easyexcel文件上传

easyexcel文件上传

前言:功能开发中,难免碰到数据上传下载功能,excel上传常见用于报表上传,绩效上传,考勤上传…

使用步骤:

1,编写业务层:

1,添加easyexcel依赖

 			<dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>3.2.0</version>
            </dependency>

2,导入模板excel下载
通常有个模版下载功能,在模板里面添加表头,以及数据格式…

3,在导入Excel模版中添加导入数据
4,导入
controller

	@PostMapping("/importxxxRoster")
    @ApiOperation("导入xxx信息")
    public void importxxxRoster(MultipartFile file, HttpServletResponse response) {
        dutyRosterService.importDutyRoster(file, response);
    }

service

 /**
     * 导入xxx信息
     *
     * @param file
     *            文件
     * @param response
     *            响应
     */
    void importxxxRoster(MultipartFile file, HttpServletResponse response);

serviceImpl

 @Override
    public void importxxxRoster(MultipartFile file, HttpServletResponse response) {
        try {
            InputStream is = file.getInputStream();
            // 监听器不能放在容器里面,要通过构造器的方式,放入监听器使用
            xxxxRosterDataListener listener = new xxxxRosterDataListener(this.baseMapper);
            // xxxRosterData 接收导入Excel 实体类
            EasyExcel.read(is, xxxRosterData.class, listener).doReadAll();
            // 获取错误信息集合
            List<xxxRosterErrorData> errorDataList = listener.getErrorDataList();
            if (!CollectionUtils.isEmpty(errorDataList)) {
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("utf-8");
                String fileName = URLEncoder.encode("xxx导入错误详情", "UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                // 导出错误Excel数据
                EasyExcel.write(response.getOutputStream(), xxxRosterErrorData.class).sheet("错误详情").doWrite(errorDataList);
            }
        } catch (IOException e) {
            log.error("导入xxexcel异常:{}", e);
            // 编写异常信息
        }
    }

接收导入Excel 数据实体
xxxRosterData

package com.xx.xx.xx.entity.excel;

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

/**
 * @author psd xxx导入excel 接收数据实体
 *
 */
@Data
public class xxxRosterData {

    /**
     * 值班时间str
     */
    @ExcelProperty(value = "日期",order = 0)
    private String dutyTimeStr;

    /**
     * 人员名称
     */
    @ExcelProperty(value = "人员名称",order = 1)
    private String person;

}

2,编写监听器

package com.xxx.xx.xx.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.xx.xx.common.result.ResultCodeEnum;
import com.xx.xx.common.utils.DateUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author psd 创建xx信息导入监听器
 */
@Data
public class xxxRosterDataListener extends AnalysisEventListener<xxxRosterData> {

    XXXRosterMapper xxxRosterMapper;

    /**
     * 记录批量导入数据
     */
    private List<xxxRosterEntity> batchInsertDutyList = new ArrayList<>();

    /**
     * 记录需要更新的数据
     */
    private List<xxxRosterEntity> batchUpdateDutyList = new ArrayList<>();

    /**
     * 记录错误的数据
     */
    private List<xxxRosterErrorData> errorDataList = new ArrayList<>();

    /**
     * 记录没有问题的数据集合
     */
    private List<xxxxRosterEntity> normalData = new ArrayList<>();


	// 创建构造器 引入用到的service mapper...
    public xxRosterDataListener(xxxRosterMapper dutyRosterMapper) {
        this.xxRosterMapper = xxxRosterMapper;
    }

    /**
     * 每一条数据都会解析
     * 
     * @param data
     *            每行数据
     * @param analysisContext
     */
    @Override
    public void invoke(xxxRosterData data, AnalysisContext analysisContext) {
        // 1、添加常见的行数校验
        
        // 2、参数校验
        if (validateData(data)) {
            // 说明没有问题
           // 3、编写要导入的数据对象信息放入
           normalData.add(xxx);
        }
    }

    /**
     * 常见的数据校验
     * 
     * @param data
     *            每一行的数据集
     * @return 是否异常 true 数据基本判断没有问题,false 说明有异常
     */
    private boolean validateData(xxxxRosterData data) {
        StringBuffer errorMsg = new StringBuffer();
        // 清空字符串
        errorMsg.setLength(ConstantUtils.ZERO);
        // 添加数据校验
        if (StringUtils.isBlank(errorMsg)) {
        	// 说明没有问题	
            return true;
        } else {
            // 记录错误信息 
            errorDataList.add();
            return false;
        }
    }

    /**
     * 所有数据执行完才会调用
     * 
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
       	// 1、获取没有问题的数据
       	// 2、判断哪些是新增的 哪些是需要修改的
       	// 3、批量入库
       	。。。
    }
}

常见遇到的问题:

问题一:

下载模板导入Excel时候明明写了数据,但是错误数据还是为空的问题,或者导入不成功?
原因是:
1,Excel的表头字段名字要和接收的数据Vo对象里面的字段名称一致
比如:
Excel模板中的表头为:

在这里插入图片描述
数据接收对象的字段名称为
在这里插入图片描述
导致接收不到
2,有可能是排序的问题,比如上图日期在第一位,但是数据xxxData实体类接收对象
order = 不是0,也会导致没有接收到数据

问题二:

在监听器添加注解比如@Component … 或者其他注解,使用@Autowired 、或者@Resources注解引入xxxService 、xxxMapper ,引入的service和mapper无法使用
这个是因为监听器不支持这种引入,可以通过构造器方式将数据传递过去,监听器不是放在spring容器中【这点是自己的理解,可能有误】

问题三:

错误信息如何导出?
我们可以在监听器添加@Data注解通过getxxx()方式获取错误数据,可以做成导出Excel功能。

@Data
public class xxxRosterDataListener extends AnalysisEventListener<xxxRosterData> {

    /**
     * 记录错误的数据
     */
    private List<xxxRosterErrorData> errorDataList = new ArrayList<>();
    ......
}
 @Override
    public void importxxxRoster(MultipartFile file, HttpServletResponse response) {
        try {
  			.....
            // 获取错误信息集合
            List<DutyRosterErrorData> errorDataList = listener.getErrorDataList();
            if (!CollectionUtils.isEmpty(errorDataList)) {
				// 导出Excel
            }
        } catch (IOException e) {
			// 抛异常 ...
        }
    }

喜欢我的文章的话,点个阅读或者点个点赞,是我编写博客的动力,持续更新中 ing…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/447159.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Langchain-Chatchat本地部署

1.前言&#xff1a; 最近AI爆发式的火&#xff0c;忆往昔尤记得16,17那会移动互联网是特别火热的&#xff0c;也造富了一批公司和个人&#xff0c;出来了很多精妙的app应用。现在轮到AI发力了&#xff0c;想想自己也应该参与到这场时代的浪潮之中&#xff0c;所以就找了开源的…

割点原理及封装好的割点类

作者推荐 视频算法专题 预备知识 本分析针对&#xff1a;连通无向图G。 搜索树 节点的父子关系&#xff1a;任意 节点的邻接 节点除了已处理 节点&#xff0c;都是它的子 节点。 以任意一点为根开始DFS&#xff0c;计算所有 节点的父子关系。只保留个子 节点到父 节点形成…

linux:线程的控制

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的总结1. 线程的优点2. 线程的缺点3. 线程异常4.线程和进程 二、线程的控制创建线程线程终止线程等待获取返回值 线程分离 总结 前言 本文作为我对于线程的…

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…

GitHub Desktop的常用操作【图形化】

文章目录 【1】仓库的创建和删除【2】文件操作【3】分支原理与分支操作1.分支创建2.分支合并 【4】标签 【1】仓库的创建和删除 在本地创建一个新的仓库&#xff1a; 然后输入仓库的名称&#xff0c;描述&#xff0c;并选择路径&#xff1a; 点击完后就发现我们的仓库创建好…

明日周刊-第1期

打算开一个新的专栏&#xff0c;专门记录一周发生的事情以及资源共享&#xff0c;那么就从第一期开始吧。 1. 一周热点 人工智能技术突破&#xff1a;可能会有关于人工智能领域的最新研究成果&#xff0c;例如新算法的开发、机器学习模型的提升或者AI在不同行业的应用案例。 量…

natfrp和FRP配置SSL的基本步骤和bug排查

获取免费/付费SSL 我直接买了一年的ssl证书 设置 主要参考&#xff1a;https://doc.natfrp.com/frpc/ssl.html 遇到的Bug root域名解析是ALIAS&#xff0c;不是CNAME不要用NATFRP &#xff08;SakuraFrp&#xff09;同步Joplin&#xff0c;会出现webdav错误导致大量笔记被…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Gauge)

数据量规图表组件&#xff0c;用于将数据展示为环形图表。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含单个子组件。 说明&#xff1a; 建议使用文本组件构建当前数值文本和辅…

sql server 恢复数据库、恢复单表数据的方法

如果不小心把某个表的数据删了&#xff0c;可以用之前的备份文件对单表进行数据恢复。 1、新建一个数据库&#xff08;全新的数据库&#xff09;&#xff0c;记得路径&#xff0c;恢复的时候要用到&#xff0c;新建完不要对数据库做什么操作。 2、用需要恢复表的数据库的备份文…

【leetcode热题】排序链表

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; 输入…

人工智能OCR领域安全应用措施

引言 编写目的 随着新一轮科技革命和产业变革的深入发展&#xff0c;5G、大数据、云计算、深度学习等新技术日益成为推动社会进步的核心动力。人工智能&#xff08;AI&#xff09;作为这些新技术的集大成者&#xff0c;正迅速成为新型基础设施建设的战略性支柱&#xff0c;其广…

Spring Boot整合MyBatis Plus配置多数据源

Spring Boot 专栏&#xff1a;https://blog.csdn.net/dkbnull/category_9278145.html Spring Cloud 专栏&#xff1a;https://blog.csdn.net/dkbnull/category_9287932.html GitHub&#xff1a;https://github.com/dkbnull/SpringBootDemo Gitee&#xff1a;https://gitee.com/…

数字化转型导师坚鹏:科技金融政策、案例及营销创新

科技金融政策、案例及营销创新 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚科技金融有哪些利好的政策&#xff1f; 不知道科技金融有哪些成功的案例&#xff1f; 不知道科技金融如何进行营销创新&#xff1f; 课程特色&#xff1a; 以案例的方式解…

Tomcat容器经常重启问题排查

报错代码: INFO [Catalina-utility-2] org.apache.catalina.core.StandardContext.reload Reloading Context with name [] has started1.查看内存占用情况:top 可以发现java线程正常情况下占用高达24%的内存资源 2.继续排查:top -Hp 29580 可以发现主要有子线程Catalina-ut…

基于jsp+mysql+Spring+mybatis的SSM汽车保险理赔管理系统设计和实现

基于jspmysqlSpringmybatis的SSM汽车保险理赔管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

Node-RED在Linux二次开发网关中能源数据实时采集与优化

智能电网与分布式能源系统已成为推动绿色能源转型的重要载体。为了更好地应对多样化的能源供给与需求挑战&#xff0c;以及实现更高效的能源管理&#xff0c;Linux二次开发网关与Node-RED这一创新组合应运而生。 Linux二次开发网关作为高度定制化的硬件平台&#xff0c;其开源特…

MT笔试题

前言 某团硬件工程师的笔试题&#xff0c;个人感觉题目的价值还是很高的&#xff0c;分为选择题和编程题&#xff0c;选择题考的是嵌入式基础知识&#xff0c;编程题是两道算法题&#xff0c;一道为简单难度&#xff0c;一道为中等难度 目录 前言选择题编程题 选择题 C语言中变…

【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱

1 基本定义 一维信号NLM非局部均值滤波算法是一种基于非局部均值思想的滤波方法&#xff0c;它通过对信号进行分块&#xff0c;计算每个块与其他块之间的相似度&#xff0c;以非局部均值的方式去除噪声。该算法的主要思想是在一定范围内寻找与当前块相似的块&#xff0c;以这些…

基于网络爬虫的购物平台价格监测系统的设计与实现

通过对网络爬虫的购物平台价格监测系统的业务流程进行梳理可知&#xff0c;网络爬虫的购物平台价格监测系统主要由前台买家模块、后台卖家模块以及管理员模块构成。前台功能包含登录功能、注册功能、系统首页功能、唯品会商品详情浏览、唯品会商品收藏、唯品会商品点赞、唯品会…

RDD算子介绍(二)

1. coalesce 用于缩减分区&#xff0c;减少分区个数&#xff0c;减少任务调度成本。 val rdd : RDD[Int] sc.makeRDD(List(1, 2, 3, 4), 4) val newRDD rdd.coalesce(2) newRDD.saveAsTextFile("output") 分区数可以减少&#xff0c;但是减少后的分区里的数据分布…