easyexcel操作之名称匹配

简单说下需求

现在我有一个excel表格,里面有两张表,分别是a_name表,b_name表,我要在这两张表的基础上新建一张a_b_name表,这张表匹配a,b表的名称,品牌名一样则放在同一行。

示例:

a_name表

奥迪 奥迪A4L 201935 TFSI 进取版 国V	
奥迪 奥迪A4L 201635 TFSI 自动 运动型	
奥迪 奥迪A4L 201630 TFSI 手动 舒适型	
奥迪 奥迪A4L 201630 TFSI 自动 舒适型	
奥迪 奥迪A4L 201635 TFSI 自动 标准型	
奥迪 奥迪A4L 201635 TFSI 自动 舒适型	
奥迪 奥迪A4L 201535 TFSI 纪念舒享版	

请添加图片描述

b_name表

奥迪 奥迪A4L 2016款 奥迪A4L 45 TFSI quattro个性运动型
奥迪 奥迪A4L 2016款 奥迪A4L 45 TFSI quattro运动型
奥迪 奥迪A4L 2015款 奥迪A4L 50 TFSI quattro旗舰型
奥迪 奥迪A4L 2016款 奥迪A4L 30 TFSI 典藏版 自动舒适型
奥迪 奥迪A4L 2016款 奥迪A4L 35 TFSI 典藏版 自动标准型
奥迪 奥迪A4L 2016款 奥迪A4L 35 TFSI 典藏版 S line舒适型

请添加图片描述

a_b_name表

奥迪 奥迪A4L 201935 TFSI 进取版 国V	奥迪 奥迪A4L 2019款 奥迪A4L 35 TFSI 进取型 国V
奥迪 奥迪A4L 201635 TFSI 自动 运动型	奥迪 奥迪A4L 2016款 奥迪A4L 35 TFSI 自动运动型
奥迪 奥迪A4L 201630 TFSI 手动 舒适型	奥迪 奥迪A4L 2016款 奥迪A4L 30 TFSI 手动舒适型
奥迪 奥迪A4L 201630 TFSI 自动 舒适型	奥迪 奥迪A4L 2016款 奥迪A4L 30 TFSI 自动舒适型
奥迪 奥迪A4L 201635 TFSI 自动 标准型	奥迪 奥迪A4L 2016款 奥迪A4L 35 TFSI 自动标准型
奥迪 奥迪A4L 201635 TFSI 自动 舒适型	奥迪 奥迪A4L 2016款 奥迪A4L 35 TFSI 自动舒适型
奥迪 奥迪A4L 201535 TFSI 纪念舒享版	奥迪 奥迪A4L 2015款 奥迪A4L 35 TFSI 百万纪念舒享版型

需要注意的是a和b并不需要完全一样,只需要大部分相同就放在同一行,也就是说直接==比较没用

OK,了解需求后直接开始,我想的是web网页,上传excel表后点击匹配生成,然后生成a_b_name表

1、创建一个maven项目,导入包

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok用来简化实体类:需要安装lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--easyExcel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency></dependencies>

2、yml配置文件

# 服务端口
server:port: 8010# 服务名
spring:main:main:banner-mode: off  #关闭bannerapplication:name: NameMatching# 环境设置:dev、test、prodprofiles:active: dev#返回json的全局时间格式jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8

3、创建实体类

abData

package com.example.namematching.dao;import lombok.Data;
@Data
public class abData {private String abName;
}

abName

@Data
@NoArgsConstructor
@AllArgsConstructor
public class abData {@ExcelProperty({"a_name"})  //excel的表头private String aName;@ExcelProperty({"b_name"})private String bName;
}

4、业务代码

先说下解题思路:

1、首先从excel表中获取a,b表的name集合
2、再将这两个集合利用双循环遍历判断,字符串匹配
3、最后将匹配好的集合存入excel表中

1、获取excel表格数据

    //从excel中读取数据public List<aData> getExcelData(String fileName, List<aData> dataList, int sheet) {ReadListener<aData> listener = new ReadListener<aData>() {@Overridepublic void onException(Exception exception, AnalysisContext context) {// 异常处理逻辑}@Overridepublic void invoke(aData data, AnalysisContext context) {dataList.add(data); // 将数据添加到List集合中}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 所有数据读取完成后的逻辑}};//sheet()读哪个工作表EasyExcel.read(fileName, aData.class, listener).sheet(sheet).doRead();return dataList;}

这里要注意的是 aData.class这个对应excel表格的列

请添加图片描述

而aData为

@Data
@NoArgsConstructor
@AllArgsConstructor
public class aData {private String aName;
}

2、通过匹配得到a_b_name集合

匹配思路:1、获取两个字符串的Jaccard 相似度(这个Jaccard 相似度指两个集合交集和并集的比值)2、Jaccard 相似度最大的添加到集合中  

将字符串切割为单词集合
Hashset集合:无序且不重复,提供了两个方法来获取交并集,分别是retainAll和addAll

​ retainAll:交集

​ addAll:并集

举例:

Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5, 6));boolean changed = set1.retainAll(set2);
System.out.println(set1);      // 输出: [3, 4]
System.out.println(changed);   // 输出: trueSet<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5, 6));boolean changed = set1.addAll(set2);
System.out.println(set1);      // 输出: [1, 2, 3, 4, 5, 6]
System.out.println(changed);   // 输出: true

匹配相似字符串的的代码

// 计算 Jaccard 相似度private static double calculateJaccardSimilarity(String str1, String str2) {Set<String> set1 = new HashSet<>(Arrays.asList(splitString(str1)));Set<String> set2 = new HashSet<>(Arrays.asList(splitString(str2)));Set<String> intersection = new HashSet<>(set1);intersection.retainAll(set2);Set<String> union = new HashSet<>(set1);union.addAll(set2);return (double) intersection.size() / union.size();}// 切分字符串为单词集合private static String[] splitString(String str) {return str.split("\\s+");}

3、创建表并导入匹配后的数据

如果fileName不存在表则会自动创建excel表

 public void buildSheet(String fileName, List<abData> abData, String sheetName) {// 这里 需要指定写用哪个class去写try (ExcelWriter excelWriter = EasyExcel.write(fileName, abData.class).build()) {// 这里注意 如果同一个sheet只要创建一次WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();excelWriter.write(abData, writeSheet);}}

4、最后调用方法

注意这里的fileName如果你是部署到服务其中要改为

    void text(){//如果不存在则创建String fileName = "D:\\spring-blp\\NameMatching\\src\\main\\resources\\static\\车型名称映射.xlsx"; // Excel文件路径List<aData> aDataList = new ArrayList<>(); // 存储数据的List集合List<aData> bDataList = new ArrayList<>(); // 存储数据的List集合aDataList = getExcelData(fileName, aDataList, 0);bDataList = getExcelData(fileName, bDataList, 1);List<abData> dataList = new ArrayList<>();for (int j = 0; j < aDataList.size(); j++) {double max=0;int index = 0;String aName = aDataList.get(j).getAName();for (int i = 0; i < bDataList.size(); i++) {String bName = bDataList.get(i).getAName();double v = calculateJaccardSimilarity(aName, bName);if (v==1){dataList.add(new abData(aName,bDataList.get(i).getAName()));break;}if (max<v){max=v;index=i;}}dataList.add(new abData(aName,bDataList.get(index).getAName()));}String fileNameAB = "D:\\spring-blp\\NameMatching\\src\\main\\resources\\static\\abName.xlsx"; // Excel文件路径buildSheet(fileNameAB,dataList,"a_b_name");}

5、运行获得结果

请添加图片描述

请添加图片描述

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

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

相关文章

Mysql高级——锁(1)

锁 1. 概述 在数据库中&#xff0c;除传统的计算资源&#xff08;如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。为保证数据的一致性&#xff0c;需要对并发操作进行控制&#xff0c;因此产生了锁。同时锁机制也为实现MySQL的各个隔…

Windows下定时下载Linux服务器的数据库备份文件(pscp+bat脚本+定时任务)

下载传输软件pscp Download PuTTY: latest release (0.79) 创建bat执行脚本 echo 删除旧的备份文件 del D:\db_bk\*.dbecho 下载新的备份文件 D:\Programs\pscp -P 22 -pw youPassword youName192.168.1.1:/home/backup/test.db D:\db_bk\ 设置定时任务 1.使用任务计划程…

【数据结构】Java对象的比较

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVA数据结构》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力…

React +AntD + From组件重复提交数据(已解决)

开发场景&#xff1a; react Hooks andt 提交form表单内容给数据库(使用antd的form组件) 问题描述 提交是异步的&#xff0c;请提交方式是POST 方式 提交表单内容给后端&#xff0c;却产生了两次提交记录&#xff08;当然&#xff0c;数据新增了两条数据&#xff09;。可以…

GitKraken for Mac:强大且跨平台的Git客户端

如果你正在寻找一个强大、直观且跨平台的Git客户端&#xff0c;那么GitKraken绝对值得你考虑。在本文中&#xff0c;我们将详细介绍GitKraken的各项功能和优势&#xff0c;以帮助你了解它如何帮助你更有效地管理和提交代码。 GitKraken是一款真正的跨平台工具&#xff0c;可以在…

UE4/5:通过Blender制作BlendShape导入【UE4/5曲线、变形目标,blender形态键】

UE4/5里面&#xff0c;我们经常可以在一些骨骼模型上面看到相关的曲线&#xff0c;如Metahuman里面就是通过这个曲线来改变人物的脸部表情。 而这里笔者将教导如何去制作这种曲线。 这种曲线都是存在于骨骼模型上的&#xff0c;所以我们要么直接制作骨骼模型导入ue&#xff0…

EF执行迁移时提示provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的

ef在执行时提示provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的。 只需要在数据库链接字符串后增加EncryptTrue;TrustServerCertificateTrue;即可 再次执行

2022年亚太杯APMCM数学建模大赛D题储能系统中传热翅片的结构优化求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 D题 储能系统中传热翅片的结构优化 原题再现 高效储能技术是解决可再生能源和余热资源波动性和间歇性的核心技术。相变蓄热以其较高的储能密度和近恒温蓄热放热而得到广泛应用。固-液相变材料具有相变前后相变潜热高、体积变化小等特点&#x…

数据仓库扫盲系列(1):数据仓库诞生原因、基本特点、和数据库的区别

数据仓库的诞生原因 随着互联网的普及&#xff0c;信息技术已经深入到各行各业&#xff0c;并逐步融入到企业的日常运营中。然而&#xff0c;当前企业在信息化建设过程中遇到了一些困境与挑战。 1、历史数据积存。 过去企业的业务系统往往是在较长时间内建设的&#xff0c;很…

前端 js 之 浏览器工作原理 和 v8引擎 01

嘿&#xff0c;老哥&#xff0c;来了就别跑 &#xff01;学完 &#xff0c;不亏 &#x1f602; 文章目录 一、输入url 之后做了什么二、简单了解下浏览器内核三、浏览器渲染过程 &#xff08;渲染引擎&#xff09;四、js 引擎五、chrome五、v8 引擎原理八、浏览器性能优化九、前…

Jenkins+vue发布项目

在Jenkins 中先创建一个任务名称 然后进行下一步&#xff0c;放一个项目 填写一些参数 参数1&#xff1a; 参数2&#xff1a; 参数3&#xff1a;参数4&#xff1a; 点击保存就行了 配置脚本 // git def git_url http://gitlab.xxxx.git def git_auth_id GITEE_RIVER…

突破Java编程的关键:揭示封装、继承和多态的核心原理与实际应用

Java中的封装、继承和多态知识点是学习java必备的基础知识&#xff0c;看似简单&#xff0c;真正理解起来还是有一定难度的&#xff0c;今天小编再次通过实例代码给大家讲解java 封装继承多态知识&#xff0c;感兴趣的朋友一起学习下吧。 封装 所谓的封装就是把类的属性和方法…