easyexcel文件上传

news2024/11/16 15:49:19

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…

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux:线程的控制

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

基于美洲狮优化算法(Puma Optimizar Algorithm ,POA)的无人机三维路径规划(提供MATLAB代码)

一、无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化飞行…

架构学习总结:企业架构=业务+数据+技术+应用架构

最近再次研读DAMA数据管理知识体系,结合工作对什么是企业架构?如何开展企业架构设计工作有一些新的认识,供大家参考。企业架构包括企业的业务架构、数据架构、技术架构和应用架构,要想做好企业的信息化数字化建设规划,这四个架构都不可缺少,这四个方面的内容共同组成了企…

药品管理系统|基于SSM 框架+ Mysql+Java+的药品管理系统设计与实现(可运行源码+数据库+设计文档+部署说明)

目录 文末获取源码 系统实现 前台首页功能 用户功能模块 管理员功能 员工功能模块 系统设计 数据库设计 lunwen参考 概述 源码获取 文末获取源码 系统实现 前台首页功能 用户功能模块 管理员功能 员工功能模块 系统设计 数据库设计 lunwen参考 概述 随着科学技术的…

区块链和人工智能的关系以及经典案例

目录 1.区块链与人工智能的关系 2.应用案例&#xff1a;基于区块链的医疗数据共享平台 2.1背景 2.2方案 2.3优势 2.4挑战 区块链技术和人工智能&#xff08;AI&#xff09;是两种不同的技术&#xff0c;但它们之间存在着互补关系。区块链技术提供了一种安全、透明、去中心…

设置文件管理器默认列宽 - Win系统

问题 当我们使用Windows系统自带的文件管理器时&#xff0c;手动调整列宽后&#xff0c;进入其他文件夹并不会生效更改&#xff0c;下文介绍解决方案&#xff0c;即如何设置文件管理器默认列宽。 解决方案 打开文件管理器&#xff0c;调整好每一列的列宽&#xff0c;然后点击…

vim基础命令

目录 前言 一.vim基础命令大全 二.vim熟练的好处 三.入门使用命令 四.使用案例 4.1 gg和G 4.2 i 和 u 和 ESC使用 4.3 y$ 和 p 和 u 使用 五.注意事项 前言 启动vim编辑器后自动进入编辑模式&#xff0c;在此模式中输入命令对应vim一个动作&#xff0c;比如&#xff1a;进入编辑…

Java EE之wait和notify

一.多线程的执行顺序 由于多个线程执行是抢占式执行&#xff0c;就会导致顺序不同&#xff0c;同时就会导致出现问题&#xff0c;就比如俩个线程同时对同一个变量进行修改&#xff0c;我们难以预知执行顺序。 但在实际开发中&#xff0c;我们希望代码按一定的逻辑顺序执行&am…

Visual Basic6.0零基础教学(2)—vb中类的介绍和基本控件的属性

Visual Basic 6.0中类的介绍和基本控件的属性 文章目录 Visual Basic 6.0中类的介绍和基本控件的属性前言一、对象的有关概念1.类2.对象3.对象的三要素4.5. VB程序的执行步骤 二、基本控件属性1.修改控件属性的练习案例 总结 前言 大家好&#xff0c;昨天我们学习了vb的简单介…

elasticsearch 深度分页查询 Search_after(图文教程)

Search_after使用 一. 简介二. 不带PIT的search_after查询2.1 构造数据2.2 search_after分页查询2.2 问题 三. 带PIT的search_after查询3.1 构建第一次查询条件3.2 进行下一页查询3.3 删除PIT 四.参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注…

opencv解析系列 - 基于DOM提取大面积植被(如森林)

Note&#xff1a;简单提取&#xff0c;不考虑后处理&#xff08;填充空洞、平滑边界等&#xff09; #include <iostream> #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include <opencv2/opencv.hpp> using namespace cv…

Feign远程调用错误

说明&#xff1a;记录一次使用Feign远程调用的错误&#xff0c;错误信息如下&#xff1a; },Server stats: [[Server:192.168.222.1:8082; Zone:UNKNOWN; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:…

spring-boot-maven-plugin springboot打包配置问题

目录 一、打包可执行jar 二、打包非可执行jar 三、两种jar对比 springboot项目的pom文件中一般都配置了spring-boot-maven-plugin打包插件。 <!-- 打包插件依赖 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-b…

论文阅读:Iterative Denoiser and Noise Estimator for Self-Supervised Image Denoising

这篇论文是发表在 2023 ICCV 上的一篇工作&#xff0c;主要介绍利用自监督学习进行降噪的。 Abstract 随着深度学习工具的兴起&#xff0c;越来越多的图像降噪模型对降噪的效果变得更好。然而&#xff0c;这种效果的巨大进步都严重依赖大量的高质量的数据对&#xff0c;这种对…

栈和队列——超详细

一、定义 1.栈的定义&#xff1a; 栈是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。 栈顶&#xff08;Top&#xff09;:线性表允许进行插入删除的那一端&#xff1b;栈底 (Bottom) &#xff1a;固…

vs2022的下载及安装教程(Visual Studio 2022)

vs简介 Visual Studio在团队项目开发中使用非常多且功能强大&#xff0c;支持开发人员编写跨平台的应用程序;Microsoft Visual C 2022正式版(VC2022运行库)&#xff0c;具有程序框架自动生成&#xff0c;灵活方便的类管理&#xff0c;强大的代码编写等功能&#xff0c;可提供编…

开发程序员转金融finance、量化quant的解决方案(含CPA、CFA、CQF等证书要求)

开发程序员转金融finance、量化quant的解决方案&#xff08;含CPA、CFA、CQF等证书要求&#xff09; 文章目录 一、开发程序员转金融 & 量化二、金融行业相关证书&#xff08;CPA、CFA等&#xff09;三、量化分析相关证书&#xff08;CQF等&#xff09;1、量化行业准入门槛…

MES系统是怎么进行数据采集的?

在MES管理系统中&#xff0c;数据采集作为最基础也最为关键的一环&#xff0c;对于实现生产过程的透明化、可控好以及优化生产流程具有重要意义。 mes系统是怎么采集数据的? 一、PLC类数据采集&#xff1a;使用C#或C直接编程访问PLC(不需要花钱买组态软件或第三方软件) 二、…

论文学习——基于注意力预测策略的动态多目标优化合作差分进化论

论文题目&#xff1a;Cooperative Differential Evolution With an Attention-Based Prediction Strategy for Dynamic Multiobjective Optimization 基于注意力预测策略的动态多目标优化合作差分进化论&#xff08;Xiao-Fang Liu , Member, IEEE, Jun Zhang, Fellow, IEEE, a…

多模太与交叉注意力应用

要解决的问题 对同一特征点1从不同角度去拍&#xff0c;在我们拿到这些不同视觉的特征后&#xff0c;就可以知道如何从第一个位置到第二个位置&#xff0c;再到第三个位置 对于传统算法 下面很多点检测都是错 loftr当今解决办法 整体流程 具体步骤 卷积提取特征&#xff0c;…