当前位置: 首页 > news >正文

EasyExcel 自定义转换器、自定义导出字典映射替换、满足条件内容增加样式,完整代码+详细注释说明

虽然最之前是在其他地方看到的,但最终因缘巧合下找到了原文,还是尊重一下原作者。
参考引用了这位佬的博客,确实方便使用。
https://blog.csdn.net/qq_45914616/article/details/137200688?spm=1001.2014.3001.5502

这是一个基于Easyexcel通过注解的方式,
在巨人的肩膀上,对相关方法进行了一定的调整和说明注释,方便使用与定制调整为自己所需要的内容格式。
能做到的事情有:

  1. 通过注解实现自定义字典值映射,满足数字、英文等符合格式的导出字典映射,导入也支持。
  2. 支持字典值映射的单选或多选模式
  3. 支持对满足某些条件的内容,在输出时添加一些样式,比如字体颜色。

以下正文:

1.定义了一个枚举类

/*** @Description: 符号枚举类* @author: CloverAn* @email: * @created: 2023/02/27 21:01*/
public class SymbolConstant {private SymbolConstant() {}public static final String SPE1 = ",";/*** 竖线*/public static final String SPE9 = "\\|";}

多余出来的已经做了删除,这两个使用了所以保留,各位可以自行替换修改。

2.添加自定义注解

import com.data.utils.constant.SymbolConstant;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @Description: 枚举数值的自定义注解* @author: CloverAn* @email:* @created: 2024/06/25 15:57*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumFiledConvert {/*** 枚举映射map  key-value,key-value,key-value,key-value* <p>* key|value,key|value* <p>* 注意,这里的key和value都是英文字符串,所以实际上他可以是数字,也可以是英文,也可以是否个字符串* 例如:0|满勤,0-1|特殊,Y|是,n|error** @return*/String enumMap() default "未匹配到映射字典";/*** 枚举类导入、导出在excel中的分隔符号** @return*/String spiteChar() default SymbolConstant.SPE1;/*** 枚举类导入导出字典分隔符*/String dictChar() default SymbolConstant.SPE9;/*** 单选 or 多选* <p>* 即多个枚举映射,都会比对输出,例如** @return* @EnumFiledConvert(enumMap = "1-篮球,2-足球,3-乒乓球,4-羽毛球",single = false)* <p>* 字段值是"1,2,3,4"* 则最终输出的是"篮球,足球,乒乓球,羽毛球"* <p>* 字典值是"1,2"* 则最终输出的是"篮球,足球"*/boolean single() default true;/*** 条件样式,对满足条件的字符串,设置红色字体*/String fontColorMap() default "";
}

1.这里将原作者的直接使用符号,以及符合使用的 逗号和横杠 调整了以下,因为个人有这一块的需求,最终使用的是 逗号和竖线。
2.修改了默认值,添加了部分注释,更通俗易懂。
3.在作者原有的基础上,增加了字体颜色的注解属性,用于接收指定的判断条件和颜色要求

3.重写EasyExcel转换器接口,对excel读和写方法都进行自定义


import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.data.keepriskexport.utils.constant.SymbolConstant;
import org.springframework.util.StringUtils;import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** 导入导出针对枚举类型的转换器** @author CloverAn*/
public class EasyExcelConvert implements Converter<Object> {/*** 枚举列表*/private Map<String, String> enumMap = new HashMap<>();/*** 条件列表*/private Map<String, String> fontColorMap = new HashMap<>();/*** excel转化后的类型** @return*/@Overridepublic Class<?> supportJavaTypeKey() {return Object.class;}/*** excel中的数据类型,统一设置字符串** @return*/@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/*** 导入转换** @param cellData            当前单元格对象* @param contentProperty     当前单元格属性* @param globalConfiguration* @return* @throws Exception*/@Overridepublic Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {String cellMsg = cellData.getStringValue();Field field = contentProperty.getField();EnumFiledConvert enumFiledConvert = field.getAnnotation(EnumFiledConvert.class);if (enumFiledConvert == null) {return null;}String enumStr = enumFiledConvert.enumMap();// 解析枚举映射关系getEnumMap(enumStr, true);// 是否为单选boolean single = enumFiledConvert.single();// 如果是单选,默认Java属性为integerif (single) {String res = enumMap.get(cellMsg);return StringUtils.hasText(res) ? Integer.valueOf(res) : null;} else {// 多选分隔符String spiteChar = enumFiledConvert.spiteChar();// 多选枚举,默认Java属性为字符串,格式为 key1,key2,key3List<String> strStr = Arrays.asList(cellMsg.split(spiteChar)).stream().map(s -> String.valueOf(enumMap.get(s))).collect(Collectors.toList());String str = String.join(spiteChar, strStr);return str;}}/*** 导出转化** @param value               当前值* @param contentProperty     当前单元格属性* @param globalConfiguration* @return* @throws Exception*/@Overridepublic WriteCellData<?> convertToExcelData(Object value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {Field field = contentProperty.getField();EnumFiledConvert enumFiledConvert = field.getAnnotation(EnumFiledConvert.class);if (enumFiledConvert == null) {return new WriteCellData();}// 解析枚举字符串String enumStr = enumFiledConvert.enumMap();getEnumMap(enumStr, false);// 是否为单选boolean single = enumFiledConvert.single();//条件样式String conditions = enumFiledConvert.fontColorMap();//解析条件样式getConditionsMap(conditions);// 如果是单选,默认Java属性为integerif (single) {//输出内容原始值String valueOf = String.valueOf(value);//输出内容转换,字典值String orDefault = enumMap.getOrDefault(valueOf, "");//创建输出内容WriteCellData writeCellData = new WriteCellData(orDefault);setWriteCellStyle(writeCellData, orDefault);return writeCellData;} else {// 多选分隔符String spiteChar = enumFiledConvert.spiteChar();// 多选枚举,默认Java属性为字符串,格式为 key1,key2,key3List<String> strStr = Arrays.asList(String.valueOf(value).split(spiteChar)).stream().map(s -> String.valueOf(enumMap.get(s))).collect(Collectors.toList());String str = String.join(spiteChar, strStr);WriteCellData writeCellData = new WriteCellData(str);return writeCellData;}}/*** 根据注解配置的枚举映射字符串进行解析到map中** @param mapStr* @param readOrWrite 读excel 、 写excel*/private void getEnumMap(String mapStr, boolean readOrWrite) {String[] enumS = mapStr.split(SymbolConstant.SPE1);for (String anEnum : enumS) {String[] data = anEnum.split(SymbolConstant.SPE9);if (readOrWrite) {// 读excel excel中的数据都是value,转换成keyenumMap.put(data[1], data[0]);} else {// 写excel  Java中的数据都是key,转换成valueenumMap.put(data[0], data[1]);}}}/*** 根据注解配置的枚举映射字符串进行解析到map中* 只有写出的时候生效*/private void getConditionsMap(String conditions) {if (conditions != null && !conditions.isEmpty()) {String[] conditionsMaps = conditions.split(SymbolConstant.SPE1);for (String condition : conditionsMaps) {String[] data = condition.split(SymbolConstant.SPE9);// 写excel  Java中的数据都是key,转换成valuefontColorMap.put(data[0], data[1]);}}}/**** 取到什么颜色,填充什么颜色,没有则不填充。** @param writeCellData*/private void setWriteCellStyle(WriteCellData writeCellData, String orDefault) {//输出样式转换,颜色值,默认黑色short orDefaultStyle = 0;//条件,满足条件则修改内容,可以叠加更多的条件,只要符合k-v规则,即比较k,填充v//因为这里是中文k 和 颜色索引,这里比较的就是中文,如果能保障k不重复,则k可以是数字、字符等,对应的v也就可以是数字、字符等,//这样就可以按照需求对单元格式进行一定的操作编辑//需要注意的是,这里用的转换之后的输出值进行的比较,有需要使用原始值的可以自行微调一下if (fontColorMap != null && fontColorMap.containsKey(orDefault)) {WriteFont writeFont = new WriteFont();WriteCellStyle writeCellStyle = new WriteCellStyle();orDefaultStyle = Short.parseShort(fontColorMap.getOrDefault(orDefault, ""));writeFont.setColor(orDefaultStyle);writeCellStyle.setWriteFont(writeFont);writeCellData.setWriteCellStyle(writeCellStyle);}}
}

1.这里面只是修改了部分直接引用字符的地方,将其使用字典值代替。
2.在作者原有的基础上,增加和调整了满足条件后,对字体颜色标记的功能。相关样式可以自己做调整,比如添加背景色等。
逻辑也跟简单,就是拿到转换之后的值,通过这个值,与注解传递的值进行比较,满足条件则添加样式。
因为添加样式只存在于导出的时候,所以只需要关注导出的方法体即可。多选的我暂时没有场景,没有添加,实际逻辑是一样的。

4.测试实体类(因为我懒。不是,要尊重作者! )

import com.alibaba.excel.annotation.ExcelProperty;
import com.example.test.excel.EasyExcelConvert;
import com.example.test.excel.EnumFiledConvert;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @Author 996* @Date 2024/3/20*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExcelDto {@ExcelProperty(value = "姓名")private String name;@ExcelProperty(value = "性别",converter = EasyExcelConvert.class)@EnumFiledConvert(enumMap = "0|保密,1|男,2|女")private Integer sex;@ExcelProperty(value = "爱好",converter = EasyExcelConvert.class)@EnumFiledConvert(enumMap = "1|篮球,2|足球,3|乒乓球,4|羽毛球",, fontColorMap = "篮球|2",single = false)private String hobbies;
}

使用时,只需要 2个步骤 ,(1)在实体类上添加自定义注解,(2)在原生的 @ExcelProperty 注解中,指定自定义解析Convert。
这时导出,对应字段列的值,就会被替换成对应的数据项。
需要注意:
1.跟原作者不一样,这里多个字典值之间使用的还是逗号,但是k-v的映射关系使用的是竖线
2.这里的k-v不一定要符合现在的这种数字和中文的组合,只需要保证k-v分别为字符串,且内容不含逗号竖线即可。比如其他字典映射:Y|是     Y-1|特例1     N|bushi     是|正确的答案     只要符合对应的格式即可,更加灵活。
3.可以修改自定义注解中的符号,以调整对应的格式,但是需要注意,不是所有的都可以直接兼容,需要进行一定的转义,这一点肯定难不倒聪明的你。
4.注意第三个属性的注解,多加了fontColorMap,前面的是输出的值,可以对应enumMap里面的字典值转换,后面的是颜色索引,这里的2标识为红色,可以看org.apache.poi.ss.usermodel.IndexedColors; 中的IndexedColors.RED.getIndex()枚举,颜色索引很全。

基于以上字体颜色修改的逻辑,我们能够拿到所有输出的值的内容,包括原始值,那么我们就可以通过一系列的条件,来实现我们对某些特定内容的数据进行样式调整,包括但不限于字体调整、字体颜色调整、字体颜色调整、数据值调整、单元格背景颜色调整、单元格边框调整等等等等

5.输出

这个大家都会,这里摘一部分代码套用

//数据集合,这里是用的实体类
List<ClockCount> countList = new ArrayList<>();ExcelWriter excelWriterCount = EasyExcel.write("文件完整路径,含后缀").build();
WriteSheet writeSheetCount = EasyExcel.writerSheet("表格中sheet名称").build();//我这是用实体类进行的文件输出
writeSheetCount.setClazz(ClockCount.class);
//写出数据
excelWriterCount.write(countList , writeSheetCount);
excelWriterCount.finish();

执行导出即可完成。通过循环,或者针对同一文件名,相同sheet名称或者不相同名称,可以实现对同一表格相同sheet页或多个sheet页数据写出,这个就和原生一致了。

相关文章:

EasyExcel 自定义转换器、自定义导出字典映射替换、满足条件内容增加样式,完整代码+详细注释说明

虽然最之前是在其他地方看到的&#xff0c;但最终因缘巧合下找到了原文&#xff0c;还是尊重一下原作者。 参考引用了这位佬的博客&#xff0c;确实方便使用。 https://blog.csdn.net/qq_45914616/article/details/137200688?spm1001.2014.3001.5502 这是一个基于Easyexcel通过…...

C语言学习笔记 Day10(指针--中)

Day10 内容梳理&#xff1a; 目录 Chapter 7 指针 7.4 指针 & 数组 &#xff08;1&#xff09;指针操作数组元素 &#xff08;2&#xff09;指针加减运算 1&#xff09;加法 2&#xff09;减法 &#xff08;3&#xff09;指针数组 7.5 多级指针 Chapter 7 指针 …...

网页显示打印 pdf

文件服务使用 minio&#xff0c;使用 nginx 反向代理。 将文件存放在 minio 上&#xff0c;如果是公开的文件&#xff0c;则统一放到一个桶&#xff0c;设置为公开只读。 如果是私有文件&#xff0c;则使用临时链接&#xff0c;给有权限的用户查看和打印。 要实现在 html 页…...

1948-2024.5金融许可信息明细数据

1948-2024.5金融许可信息明细数据 1、时间&#xff1a;1948-2024.5 2、指标&#xff1a;来源表、机构编码、机构名称、所属银行、机构类型、业务范围、机构住所、地理坐标、行政区划代码、所属区县、所属城市、所属省份、邮政编码、发证日期、批准日期、发证机关、流水号、是…...

【笔记】从零开始做一个精灵龙女-画贴图阶段(终)

这篇主要是细节&#xff0c;包括花纹和其它一些细化 皮肤 脖子 脖子一定要压暗&#xff0c;不然前后关系体现不出来 脸 1. 忘了有uv缝了&#xff0c;记得打开投影模式画 顺着头发轨迹长的方向画出发际线 背包手镯 1.先画出暗色花纹&#xff1a; 2.再加亮色&#xff0c;亮…...

从MySQL到Elasticsearch:创建酒店索引案例

在现代的数据管理中&#xff0c;Elasticsearch&#xff08;简称ES&#xff09;因其强大的搜索功能和灵活的索引结构而受到广泛欢迎。本篇博客将介绍如何根据MySQL数据库中的酒店表定义&#xff0c;创建一个相应的Elasticsearch索引。 MySQL与Elasticsearch的对比 在开始之前&…...

Webkit与Web Push API:提升用户体验的推送技术

Web Push API是一种允许网站向用户发送通知的Web技术&#xff0c;即使用户没有打开网站也能接收到信息。这项技术可以显著提升用户的参与度和满意度。Webkit&#xff0c;作为Safari和其他浏览器的内核&#xff0c;对Web Push API的支持情况如何&#xff1f;本文将深入探讨Web P…...

Java线程池的拒绝策略

在 Java 线程池中&#xff0c;常见的拒绝策略&#xff1a; AbortPolicy&#xff08;中止策略&#xff09; 特点&#xff1a;直接抛出 RejectedExecutionException 异常来拒绝新任务的提交。应用场景&#xff1a;适用于对系统的稳定性要求较高&#xff0c;不希望丢失任务&#…...

【C++进阶】继承

【C进阶】继承 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承父类成员访问方式的变化 1.3 继承类模…...

立体相机镜面重建(一)镜面标定

无论是单目、双目或者是多屏幕镜面重建&#xff0c;都需要事先对屏幕和相机的相对位置进行标定&#xff0c;求得相机到屏幕之间的相对变换关系。如果求得屏幕和相机之间的变换关系呢&#xff1f;接下来是标定流程。 &#xff08;一&#xff09;准备&#xff1a; 1&#xff09…...

【如何有效解决前端Vue中的常见难题】

&#x1f41f;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢编程&#x1fab4; &#x1f419;个人主页&#x1f947;&#xff1a;Aic山鱼&#x1f420;WeChat&#xff1a;z7010cyy &#x1f988;系列专栏&#xff1a;&#x1f3de;️ 前端-JS基础专栏✨前端-Vue框架专栏…...

CLAMP-1靶机渗透测试

一、靶机下载地址 https://www.vulnhub.com/entry/clamp-101,320/ 二、信息收集 1、主机发现 # 使用命令 nmap 192.168.145.0/24 -sn | grep -B 2 "00:0C:29:88:B4:BF" 2、端口扫描 # 使用命令 nmap 192.168.145.0/24 -p- -sV 3、指纹识别 # 使用命令 whatweb …...

JavaScript中的Truthy Falsy值以及等号判断

1.Falsy & Truthy Falsy的值false&#xff0c;0&#xff0c;-0&#xff0c; “”&#xff0c; null&#xff0c; undefined&#xff0c;NaNTruthy的值除了以上之外的其他值 2.等号判断 console.log(10 10); console.log(0 ); console.log(0 false); console.log( fa…...

uniapp——展开和收起

案例展示 代码 后台返回的数据格式如下&#xff1a; {1: "大富科技速度快放假手动阀",2: "第三方斯蒂芬斯蒂芬是的开发时间",4: "45345345",5: "电饭锅电饭锅地方" }<view class"tipTitle">温馨提示</view> &l…...

WebGL2学习(2): GLSL ES 3.0

更多精彩内容尽在 dt.sim3d.cn &#xff0c;关注公众号【sky的数孪技术】&#xff0c;技术交流、源码下载请添加VX&#xff1a;digital_twin123 WebGL 2.0 给 GLSL 带来了重大变化。WebGL 1.0 中使用的 GLSL 版本是 GLSL ES 1.0。 WebGL 2.0 中仍然可用。但是&#xff0c;通过编…...

[大模型实战] DAMODEL云算力平台部署LLama3.1大语言模型

[大模型实战] DAMODEL云算力平台部署LLama3.1大语言模型 目录 一、LLama3.1二、DAMODEL云算力平台2.1 提供的服务2.1.1 AI训练2.1.2 AI推理2.1.3 高性能计算2.1.4 图像&#xff0f;视频渲染2.1.5 定制化部署 2.2 支持的GPU 三、在DAMODEL部署LLama3.13.1 在DAMODEL创建实例&…...

驱动开发系列09 - Linux设备模型之设备,驱动和总线

一:概述 Linux 设备模型(LDM)是 Linux 内核中引入的一个概念。用于管理内核对象(那些需要引用计数的对象、例如文件、设备、总线甚至驱动程序),以及描述它们之间的层次结构,以及这些内核对象之间绑定关系。Linux 设备模型引入了对象生命周期管理、引用计数、以及面向对象…...

HTML实现弹出层

leopard/ˈlepərd/ 豹子&#xff0c;豹纹 弹出层指的是鼠标悬停于某个元素之上时显示的一个界面组件。 关注和理解特性&#xff1a;z-index属性和动态生成HTML元素。 HTML5新增&#xff1a; figure:媒体内容(图像&#xff0c;音频&#xff0c;视频)&#xff0c;用于包含一…...

Android控件详解

在Android应用程序中&#xff0c;界面由布局和组件组成。布局相当于框架&#xff0c;而控件则是框架里面的内容。了解过Android布局后&#xff0c;如果要设计ui界面&#xff0c;还需要了解和掌握各个控件的应用。 一个界面的设计&#xff0c;先从创建容器开始&#xff0c;再向…...

记忆化搜索专题篇

目录 斐波那契数 不同路径 最长递增子序列 猜数字大小II 矩阵中的最长递增路径 声明&#xff1a;下面将主要使用递归记忆化搜索来解决问题&#xff01;&#xff01;&#xff01; 斐波那契数 题目 思路 斐波那契数的特点就是除了第一个数是0&#xff0c;第二个数是1&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...