Excel 导入

依赖

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

service 读取excel文件的行数据

DataExcelListener<DeviceTemplateExcel> listener = new DataExcelListener<DeviceTemplateExcel>();
// headRowNumber(1):表示第一行为表头,从第二行取值
ExcelReader excelReader = EasyExcelFactory.read( file.getInputStream() , DeviceTemplateExcel.class, listener).headRowNumber(1).build();
excelReader.readAll();
List<DeviceTemplateExcel> data = listener.getDatas();
excelReader.finish();
    @Override@Transactional(rollbackFor = Exception.class)public RP importDevice(MultipartFile file, Long productId) throws IOException {DataExcelListener<DeviceTemplateExcel> listener = new DataExcelListener<DeviceTemplateExcel>();// headRowNumber(1):表示第一行为表头,从第二行取值ExcelReader excelReader = EasyExcelFactory.read( file.getInputStream() , DeviceTemplateExcel.class, listener).headRowNumber(1).build();excelReader.readAll();List<DeviceTemplateExcel> data = listener.getDatas();excelReader.finish();if (data.size() == 3) {return RP.failure("导入失败,请检查导入文件是否正确");}Product product = productService.getById(productId);if (product == null) {throw new ServiceException("产品不存在");}List<String> deviceSnList = data.stream().map(DeviceTemplateExcel::getDeviceSn).collect(Collectors.toList());List<Device> repeatList = baseMapper.selectList(Wrappers.<Device>update().lambda().in(Device::getDeviceSn, deviceSnList));List<Device> deviceList = new ArrayList<>();//导出失败原因List<DeviceFailureExportExcel> exportExcels = new ArrayList<>();for (DeviceTemplateExcel entity : data) {if (StringUtils.isBlank(entity.getDeviceName()) || StringUtils.isBlank(entity.getDeviceSn())) {DeviceFailureExportExcel reason = new DeviceFailureExportExcel();reason.setDeviceName(entity.getDeviceName());reason.setDeviceSn(entity.getDeviceSn());reason.setFailureReason(StringUtils.isBlank(entity.getDeviceName()) ? "设备名称不能为空!" : "设备序列号不能为空!");exportExcels.add(reason);continue;}//数据库中的判重Optional<Device> deviceOpt = repeatList.stream().filter(item -> item.getDeviceSn().equals(entity.getDeviceSn())).findFirst();//还未新增的设备判重Optional<Device> deviceAddOpt = deviceList.stream().filter(item -> item.getDeviceSn().equals(entity.getDeviceSn())).findFirst();if (deviceOpt.isPresent() || deviceAddOpt.isPresent()) {DeviceFailureExportExcel reason = new DeviceFailureExportExcel();reason.setDeviceName(entity.getDeviceName());reason.setDeviceSn(entity.getDeviceSn());reason.setFailureReason("设备序列号已存在!");exportExcels.add(reason);continue;}Device device = new Device();device.setDeviceName(entity.getDeviceName());device.setDeviceSn(entity.getDeviceSn());device.setProductId(productId);device.setTenantId(AuthUtil.getTenantId()); deviceList.add(device);}if (deviceList.size() > 0) {this.saveBatch(deviceList);}if (exportExcels.size() > 0) {return RP.failure("请重新处理失败的数据!");} else {return RP.failure("操作成功");}}

监听类

package com.sinenux.iot.core.exect;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;import java.util.ArrayList;
import java.util.List;/*** 解析监听器*/
public class DataExcelListener<T> extends AnalysisEventListener<T> {/*** 自定义用于暂时存储data* 可以通过实例获取该值*/private List<T> datas = new ArrayList<>();/*** 每解析一行都会回调invoke()方法** @param object  读取后的数据对象* @param context 内容*/@Override@SuppressWarnings("unchecked")public void invoke(Object object, AnalysisContext context) {T data = (T) object;//数据存储到list,供批量处理,或后续自己业务逻辑处理。datas.add(data);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {//解析结束销毁不用的资源//注意不要调用datas.clear(),否则getDatas为null}/*** 返回数据** @return 返回读取的数据集合**/public List<T> getDatas() {return datas;}/*** 设置读取的数据集合** @param datas 设置读取的数据集合**/public void setDatas(List<T> datas) {this.datas = datas;}}

实体类 DeviceTemplateExcel

  注意这里 lombok的@Data注解 和EasyExcel有冲突 不能使用  @Data 要用 get set 方法

package com.sinenux.iot.core.exect;import com.alibaba.excel.annotation.ExcelProperty;import java.io.Serializable;/*** 设备导入模板* 注意这里 lombok的@Data注解 和EasyExcel有冲突 不能使用  @Data 要用 get set 方法** @author xulk*/public class DeviceTemplateExcel implements Serializable {private static final long serialVersionUID = 1L;@ExcelProperty(value = "设备名称", index = 0)private String deviceName;@ExcelProperty(value = "设备序列号(不可重复)", index = 1)private String deviceSn;public String getDeviceName() {return deviceName;}public void setDeviceName(String deviceName) {this.deviceName = deviceName;}public String getDeviceSn() {return deviceSn;}public void setDeviceSn(String deviceSn) {this.deviceSn = deviceSn;}
}

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

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

相关文章

MFC CList<CRect, CRect> m_listRect;的用法

CList<CRect, CRect&> 是 MFC&#xff08;Microsoft Foundation Classes&#xff09;中定义的一个双向链表模板类&#xff0c;用于存储 CRect 对象。在使用 CList 时&#xff0c;你可以执行多种操作&#xff0c;比如添加、移除、查找和遍历元素。以下是一些常见的用法…

SAP 生产订单报工函数BAPI_PRODORDCONF_CREATE_TT不返回报错信息

最近财务一直反馈MES报工的数据都没有成本,然后去查看原因发现是财务当月的KP26的价格没有进行维护,导致没有收集到工单的报工成本。 但是在前台操作CO11 报工的时候,系统会给出报错的信息 但是我们在调用函数BAPI_PRODORDCONF_CREATE_TT的时候,系统并没有返回报错的信息…

普通测径仪和智能测径仪的五大区别

在工业自动化和精密测量的领域中&#xff0c;测径仪是不可或缺的重要工具。随着科技的进步&#xff0c;测径仪也在不断地进行技术革新和升级&#xff0c;从传统的普通测径仪发展到如今的智能测径仪。本文将详细探讨普通测径仪与智能测径仪之间的五大区别。 一、测量精度与稳定…

【Tlias智能学习辅助系统】01 准备工作

Tlias智能学习辅助系统 01 创建员工、部门表创建springboot工程&#xff0c;引入对应的起步依赖(web、mybatis、mysql驱动、lombok)准备 Mapper、Service、Controller 等基础结构MapperServiceControllerpojo封装类application.properties 接口开发规范 创建员工、部门表 -- 创…

oracle sql--计算某一日期到当前日期的间隔天数

oracle sql–计算某一日期到当前日期的间隔天数 如题&#xff0c;是在工作中遇到的一个报表需求问题。用户需要查询“创建时间到当下的天数”&#xff0c;于是我这个可怜的打工仔就开始干活了。。。&#xff08;苦涩ing&#xff09;我发现oracle sql的自带函数和普通的sql貌似…

FPGA基础:触发器和锁存器

目录 锁存器&#xff08;Latch&#xff09;D触发器&#xff08;Flip-Flop&#xff09;最基本时序电路时序块&#xff08;Sequential blocks&#xff09;:同步与异步触发器概念触发器分类触发器的Verilog实现1. 上升沿触发的触发器2. 带异步复位、上升沿触发的触发器3. 带异步复…

raid配置与实战10

一、raid理论 1、raid概述 raid&#xff08;磁盘阵列&#xff09;&#xff1a;是用不同的硬盘分区&#xff0c;组成一个逻辑上的硬盘&#xff0c;高可用&#xff08;冗余&#xff09;。 2、raid级别 2.1、raid0条带化存储 数据分散在多个物理磁盘上的存储方式&#xff0c;…

新媒体时代,LCD电子价签赋予零售场景新活力

近年来&#xff0c;全球企业迅速掀起了数字化转型的浪潮&#xff0c;加速了新零售科技的发展与应用。在实体零售门店中&#xff0c;商品货架显示逐渐趋向智能化和多样化。然而&#xff0c;在信息传播日益碎片化和视频化的时代&#xff0c;零售门店如何更有效地吸引消费者的注意…

英飞凌 AURIX TriCore 单片机开发入门

文章目录 目的硬件准备AURIX™ Development StudioInfineon MemtoolAURIX™ iLLD Drivers总结 目的 英飞凌的32位 AURIX™ TriCore™ 系列单片机 经常用于汽车和工业领域。开发该系列单片机比较常用的开发环境有 HighTec 和 AURIX™ Development Studio 。本文将基于后者&…

TalkingData数据统计的力量

在数字化时代&#xff0c;数据已成为企业竞争的关键资源。而TalkingData作为一家领先的第三方数据平台&#xff0c;其数据统计能力无疑是推动企业智能化转型的重要力量。 首先&#xff0c;TalkingData的数据统计能力体现在其庞大的用户基础和丰富的数据来源上。通过与数千家应…

Java-常用模块

文章目录 日期时间stream流 日期时间 jdk8新的日期时间类 解析和格式化DateTimeFormatter类&#xff08;线程安全&#xff09; LocalDateTime类 Instant类 Duration类String time "2013-02-11 11:00:00";DateTimeFormatter dateTimeFormatter DateTimeFormatter.o…

linux镜像虚拟机创建共享文件夹详细步骤 -- 和本地电脑传输文件

主机与虚拟机之间传递文件&#xff0c;最快捷的方法莫过于共享文件夹。此方法不需要复制文件&#xff0c;而且可以节省硬盘空间。 具体设置步骤如下&#xff1a; 打开自己的电脑&#xff0c;创建共享的文件夹&#xff0c;完成后鼠标右击刚刚创建的共享文件夹&#xff0c;选择…

设计模式 18 迭代器模式 Iterator Pattern

设计模式 18 迭代器模式 Iterator Pattern 1.定义 迭代器模式 (Iterator Pattern) 是一种行为型设计模式&#xff0c;它提供了一种访问集合元素的标准方法&#xff0c;而无需暴露集合的内部表示。 提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而又不需要暴露该…

python猜数游戏限制次数

1、游戏规则 在这个游戏中&#xff0c;计算机会随机生成一个1到100之间的整数&#xff0c;玩家需要在限定的次数内猜测这个数字是多少。如果玩家猜对了数字&#xff0c;游戏结束&#xff0c;玩家获胜;如果玩家用完了所有的猜测次数仍然没有猜对&#xff0c;游戏结束&#xff0…

Redis之内存管理过期、淘汰机制

1.Redis内存管理 我们的redis是一个内存型数据库&#xff0c;我们的数据也都是放在内存中的&#xff0c;内存是有限的空间&#xff0c;当数据满了之后&#xff0c;我们要怎么样继续保证redis的可用性呢?我们就需要采取点管理措施和机制来保证我们redis的可用性。 在redis.co…

一套saas模式云MES系统源码,基于springboot+vue.js+uniapp开发

一套saas模式云MES系统源码&#xff0c;基于springbootvue.jsuniapp开发 MES系统简介 MES系统&#xff0c;即制造执行系统&#xff08;Manufacturing Execution System&#xff09;&#xff0c;是一种面向制造企业车间执行层的生产信息化管理系统。它位于上层的企业资源规划&a…

Day01_CET4-Read synonymous substitutions

文章目录 1.减少2.增加3.原因4.赞扬 1.减少 diminish v.减少 dwindle v.逐渐减少 lessen v.减少 slash v.削减 &#xff08;cut down&#xff09; slump v.暴跌&#xff1b;n.衰退 recession n.衰退 &#xff08;economic disruption&#xff09; lower v.降低 depress…

应用案例|精密制造中使用复合机器人得到显著提升

精密制造行业对设备的精度、稳定性和效率要求极高&#xff0c;而复合机器人凭借其多功能性、高度灵活性和精准控制能力&#xff0c;正逐渐成为该领域的新宠。以下是一个富唯智能复合机器人在精密制造中的应用案例。 案例背景 某知名汽车零部件制造企业&#xff0c;专注于生产…

【JS】并发控制

需求 控制网络请求并发数控制并发按顺序返回结果 码 /** * 控制并发 * param {Function} fn 逻辑处理函数 * param {Array} arr 发送的数据 * param {Number} [max3] 并发数 默认3 * param {Number} [orderfalse] 按顺序返回执行结果 默认false * param {Number} [retry1] 重试…

vue项目集成萤石云在Web系统中实现实时摄像头监控及控制功能

需求 需求&#xff1a; 开发人员在产线上放置一个萤石摄像头&#xff0c;前端在可视化大屏上实时监控&#xff0c;且控制左右上下功能。 效果 萤石云接入web前期准备工作 阅读萤石云API文档&#xff1a;萤石云开放平台开发者文档 阅读萤石云控制API文档&#xff1a;萤石云摄…