动态添加字段和注解,形成class类,集合对象动态创建Excel列
一.需求
动态生成Excel列,因为Excel列是通过类对象字段注解来添加,在不确定Excel列数的情况下,就需要动态生成列,对应类对象字段也需要动态生成;
二.ByteBuddy字节码增强动态创建类
1.依赖
<dependencies><dependency><groupId>net.bytebuddy</groupId><artifactId>byte-buddy</artifactId><version>1.11.17</version></dependency>
</dependencies>
2.动态创建类
public Class<? extends ExcelRecordDynamicDTO> getDynamicClass(ChatBatchRequestVO chatBatchRequest) throws NoSuchFieldException, IllegalAccessException, InstantiationException {DynamicType.Builder<ExcelRecordDynamicDTO> dynamicClass = new ByteBuddy().subclass(ExcelRecordDynamicDTO.class);dynamicClass = dynamicClass.defineField("question", String.class, Visibility.PUBLIC).annotateField(AnnotationDescription.Builder.ofType(ExcelColumn.class).define("value", new String("问题")).define("col", 1).build()).defineMethod("getQuestion", String.class, Visibility.PUBLIC).intercept(FieldAccessor.ofBeanProperty()).defineMethod("setQuestion", void.class, Visibility.PUBLIC).withParameters(String.class).intercept(FieldAccessor.ofBeanProperty());for (int i = 0; i < chatBatchRequest.getModelTypeId().length; i++) {dynamicClass = dynamicClass.defineField("answer" + i, String.class, Visibility.PUBLIC).annotateField(AnnotationDescription.Builder.ofType(ExcelColumn.class).define("value", new String(ChatModelTypeEnum.getmodelShowNameByType(chatBatchRequest.getModelTypeId()[i]))).define("col", i + 2).build()).defineMethod("getAnswer" + i, String.class, Visibility.PUBLIC).intercept(FieldAccessor.ofBeanProperty()).defineMethod("setAnswer" + i, void.class, Visibility.PUBLIC).withParameters(String.class).intercept(FieldAccessor.ofBeanProperty());}Class<? extends ExcelRecordDynamicDTO> d = dynamicClass.make().load(ExcelRecordDynamicDTO.class.getClassLoader()).getLoaded();return d;}
动态类如下所示:
public class ExcelRecordDynamicDTO implements Serializable {//动态生成的字段和注解如下所示//@ExcelColum(value="第一列", col=1)//private String col1;
}
3.实例化赋值
//实例化
Class<? extends ExcelRecordDynamicDTO> dy = getDynamicClass(chatBatchRequest);
ExcelRecordDynamicDTO dtp = dy.newInstatnce();//赋值
Field[] cityCode = dto.getClass().getDeclaredFields();
for (Filed f : cityCode) {f.setAccessible(true)f.set(dto, "赋值");
}//获取值
dto.getClass().getDeclaredField("question").get(dto)
4.创建Excel
List<ExcelRecordDynamicDTO> resultList = new ArrayList<>();
resultList.add(dto);ExcelUtil.writeExcel(resultList,dy.newInstance());
三.Excel工具类
1.依赖
<dependencies><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.13</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.13</version></dependency>
</dependencies>
2.Excel代码
注解如下:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelColumn {//标题String value() default "";//Excel从左往右排列位置int col() default 0;
}
Excel工具类:使用apache.poi
public class ExcelUtil {private final static String EXCEL2003 = "xls";private final static EXCEL2007 = "xlsx";public static <T> List<T> readExcel(String path, Class<T> cls, File file) {String fileName = file.getName();if (!fileName.matches("^.+\\.)?i)(xls)$") && !fineName.matches("^.+\\.(?i)(xlsx)$")) {log.error("格式错误");}List<T> dataList = new ArrayList<>();Workbook workbook = null;try {if (fileName.endsWith(EXCEL2007)) {InputStream is = new FileInputStream(new File(path));workbook = new XSSFWorkbook(is);}if (fileName.endsWith(EXCEL2003)) {InputStream is = new FileInputStream(new File(path));workbook = new HSSFWorkbook(is);} if (workbook != null ) {Map<String, List<Field>> classMap = new HashMap<>();List<Field> fields = Stream.of(cls.getDeclaredFields()).collectors.toList());fields.forEach(field -> {ExcelColumn annotaion = field.getAnnotation(ExcelColum.class);if (annotaion != null) {String value = annotation.value();if (StringUtils.isBlank(value)) {return;}if (!classMap.containsKey(value)) {classMap.put(value, new ArrayList<>());}field.setAccessible(true);classMap.get(value).add(field);}});//索引---columnsMap<Integer, List<Field>> refectionMap = new HashMap<>(16);//默认读取第一个sheetSheet sheet = workbook.getSheetAt(0);booleasn firstRow = true;for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);//首行 提取注解if (firstRow) {for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {Cell cell = row.getCell(j);String cellValue = getCellValue(cell);if (classMap.containsKey(cellValue) {reflectionMap.put(j, classMap.get(cellValue));}}firstRow false;} else {//忽略空白行if (row == null) {continue;}try {T t = cls.newInstance();//判断是否为空白行boolean allBlank = true;for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {if (reflectionMap.containsKey(j)) {Cell cell = row.getCell(j);String cellValue = getCellValue(cell);if (StringUtils.isNotBlank(cellValue)) {allBlank = false;}List<Field> fieldList = reflectionMap.get(j);fieldList.foeEach(x -> {try {handleField(t, cellValue, x);} catch (Exception e) {log.error(e);}});}}if (!allBlank) {dataList.add(t);} else {log.warn("ignore!");} } catch (Exception e) {log.error(e);}}}}} catch (Exception e) {log.error(e);} finally {if (workbook != null) {try {workbook.close();} catch (Exception e) {log.error(e);}}}return dataList;}public static <T> List<T> readExcel(Class<T> cls, MultipartFile file) {String fileName = file.getOriginalFilename();if (!fileName.matches("^.+\\.)?i)(xls)$") && !fineName.matches("^.+\\.(?i)(xlsx)$")) {log.error("格式错误");}List<T> dataList = new ArrayList<>();Workbook workbook = null;try {InputStream is = file.getInputStream();if (fileName.endsWith(EXCEL2007)) {workbook = new XSSFWorkbook(is);}if (fileName.endsWith(EXCEL2003)) {workbook = new HSSFWorkbook(is);} if (workbook != null ) {Map<String, List<Field>> classMap = new HashMap<>();List<Field> fields = Stream.of(cls.getDeclaredFields()).collectors.toList());fields.forEach(field -> {ExcelColumn annotaion = field.getAnnotation(ExcelColum.class);if (annotaion != null) {String value = annotation.value();if (StringUtils.isBlank(value)) {return;}if (!classMap.containsKey(value)) {classMap.put(value, new ArrayList<>());}field.setAccessible(true);classMap.get(value).add(field);}});//索引---columnsMap<Integer, List<Field>> refectionMap = new HashMap<>(16);//默认读取第一个sheetSheet sheet = workbook.getSheetAt(0);booleasn firstRow = true;for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);//首行 提取注解if (firstRow) {for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {Cell cell = row.getCell(j);String cellValue = getCellValue(cell);if (classMap.containsKey(cellValue) {reflectionMap.put(j, classMap.get(cellValue));}}firstRow false;} else {//忽略空白行if (row == null) {continue;}try {T t = cls.newInstance();//判断是否为空白行boolean allBlank = true;for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {if (reflectionMap.containsKey(j)) {Cell cell = row.getCell(j);String cellValue = getCellValue(cell);if (StringUtils.isNotBlank(cellValue)) {allBlank = false;}List<Field> fieldList = reflectionMap.get(j);fieldList.foeEach(x -> {try {handleField(t, cellValue, x);} catch (Exception e) {log.error(e);}});}}if (!allBlank) {dataList.add(t);} else {log.warn("ignore!");} } catch (Exception e) {log.error(e);}}}}} catch (Exception e) {log.error(e);} finally {if (workbook != null) {try {workbook.close();} catch (Exception e) {log.error(e);}}}return dataList;}private static <T> void handleField(T t, String value, Field field) trows Exception {Class<?> type = field.getType();if (type == null || type== void.class || StringUtils.isBlank(value)) {return;}if (type == Object.class) {field.set(t, value);} else if (type.getSuperclass() == null || type.getSuperclass() == Number.calss) {if (type == int.class || type == Integer.class) {field.set(t, NumberUtils.toInt(value));} else if (type == long.class || type == Long.calss ) {field.set(t, NumberUtils.toLong(value));} else if (type == byte.class || type == Byte.calss ) {field.set(t, NumberUtils.toByte(value));} else if (type == short.class || type == Short.calss ) {field.set(t, NumberUtils.toShort(value));} else if (type == double.class || type == Double.calss ) {field.set(t, NumberUtils.toDouble(value));} else if (type == float.class || type == Float.calss ) {field.set(t, NumberUtils.toFloat(value));} else if (type == char.class || type == Character.calss ) {field.set(t, NumberUtils.toChar(value));} else if (type == boolean.class) {field.set(t, NumberUtils.toBoolean(value));} else if (type == BigDecimal.class) {field.set(t, new BigDecimal(value));}} else if (type == Boolean.class) {field.set(t, BooleanUtils.toBoolean(value));} else if (type == Data.class) {SimpleDateFprmat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);field.set(t, format.parse(value));} else if (type == String.class) {field.set(t, value);} else {Constructor<?> constructor = type.getConstructor(String.class);field.set(t, constructor .newInstance(value));}}private static String getCellValue(Cell cell) {if (cell == null) {return "";}if (cell.getCellType() == Cell CELL_TYPE_NUMERIC) {if (HSSFDateUtil.isCellDateFormatted(cell)) {return HSSDateUtil.getJavaDate(cell.getNumericCellValue()).toString();}else {return new BigDecimal(cell.getNumericCellValue()).toString();}} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {return StringUtils.trimToEmpty(cell.getStringCellValue());} else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {return StringUtils.trimToEmpty(cell.getCellFormula());} else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {return "";} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {return StringUtils.trimToEmpty(cell.getBooleanCellValue());} else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {return "ERROR";} else {return cell.toString().trim;}}public static <T> void writeExcel(String filePathName, List<T> dataList, ExcelRecordDynamicDTO excelRecordDTO) {Field[] fields = excelRecordDTO.getClass().getDeclaredFields();List<Field> fieldList = Arrays.stream(fields).filter(field -> {ExcelColumn annotaion = field.getAnnoation(ExcelColum.class);if (annotation != null && annotation.col() > 0) {field.setAccessible(true);return true;}return false;}).sorted(Comparator.comparing(field -> {int col = 0;ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);if (annotation != null) {col = annotation.col();}return col;})).collect(Collectors.toList());Workbook wb = new XSSFWorkbook();Sheet sheet = wb.createSheet("Sheet1");AtomicInteger ai = new AtomicInteger();{Row row = sheet.createRow(ai.getAndIncrement());AtomicInteger aj = new AtomicInteger();//写入头部fieldList.forEach(field -> {ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);String columnName = "";if (annotation != null) {columnName = annotation.value();}Cell cell = row.createCell(aj.getAndIncreament());CellStyle cellStyle = wb.createCellStyle();cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());cellSty;e.setFillPattern(CellStyle.SOLID_FOREGROUND);cellSty;e.setAlignment(CellStyle.ALIGN_CENTER);Font font = wb.createFont();font.setBoldweight(Font.BOLDWEIGHT_NORMAL);cellStyle.setFont(font);cell.setCellStyle(cellStyle);cell.setCellValue(columnName);});}if (CollectionUtils.isNatEmpty(dataList)) {dataList.forEach(t -> {Row row1 = sheet.createRow(ai.getAndIncrement());AtomicInteger aj = new AtomicInteger();fieldList.forEach(field -> {Class<?> type = field.getType();Object value = "";try {value = field.get(t);} catch (Exception e) {e.printStackTrace();}Cell cell = row1.createCell(aj.getAndIncrement());if (value != null) {if (type == Date.class) {cell.setCellValue(value.toString());} else {cell.setCellValue(value.toString());}cell.setCellValue(value.toString());}});});}//冻结窗格wb.getSheet("Sheet1").createFreezePane(0, 1, 0, 1);//浏览器下载excel//buildExcelDocument("abbot.xlsx", wb, response);//生成Excel文件buildExcelFile(filePathName, wb);} private static void buildExcelFile(String path, Workbook wb) {File file = new File(path);if (file.exists()) {file.delete();}try {wb.write(newFileOutputStream(file));} catch (Exception e) {e.printStackTrace();}}}
四.附
使用ClassPool动态生成类,实测暂未解决的问题:
1.无法给字段注解属性为int类型的赋值;
2.只能一次创建,无法清除上次动态创建的字段
代码如下:
<dependency><groupId>javassist</groupId><artifactId>javassist</artifactId><version>3.12.1.GA</version></dependency>
public Object getExcelRecordDynamicClass(ChatBatchRequestVO chatBatchRequest) throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException {//默认的类搜索路径ClassPool pool = ClassPool.getDefault();//获取一个ctClass对象 com.example.demo.excel.entity.CitiesVo 这个是包的相对路径
// CtClass ctClass = pool.makeClass("ExcelRecordDynamicDTO");CtClass ctClass = pool.get("cn.com.wind.ai.platform.aigc.test.pojo.excel.ExcelRecordDynamicDTO");for (int i = 0; i < chatBatchRequest.getModelTypeId().length; i++) {//添加属性ctClass.addField(CtField.make("public String answer"+ i +";", ctClass));//添加set方法ctClass.addMethod(CtMethod.make("public void setAnswer"+ i +"(String answer"+ i +"){this.answer"+ i +" = answer"+ i +";}", ctClass));//添加get方法ctClass.addMethod(CtMethod.make("public String getAnswer"+ i +"(){return this.answer"+ i +";}", ctClass));//获取这个字段CtField answer = ctClass.getField("answer"+ i);FieldInfo fieldInfo = answer.getFieldInfo();ConstPool cp = fieldInfo.getConstPool();AnnotationsAttribute attribute = (AnnotationsAttribute) fieldInfo.getAttribute(AnnotationsAttribute.visibleTag);//这里进行了判断 如果说当前字段没有注解的时候 AnnotationsAttribute 这个对象是为空的//所以要针对这个进行新创建 一个 AnnotationsAttribute 对象if(ObjectUtils.isEmpty(attribute)){List<AttributeInfo> attributeInfos =fieldInfo.getAttributes();attribute = !attributeInfos.isEmpty()?(AnnotationsAttribute) attributeInfos.get(0):new AnnotationsAttribute(fieldInfo.getConstPool(), AnnotationsAttribute.visibleTag);}// Annotation 默认构造方法 typeName:表示的是注解的路径Annotation bodyAnnot = new Annotation("cn.com.wind.ai.platform.aigc.test.framework.aop.excel.ExcelColumn", cp);// name 表示的是自定义注解的 方法 new StringMemberValue("名字", cp) 表示给name赋值bodyAnnot.addMemberValue("value", new StringMemberValue(ChatModelTypeEnum.getmodelShowNameByType(chatBatchRequest.getModelTypeId()[i]), cp));
// IntegerMemberValue colValue = new IntegerMemberValue(i + 2, cp);
// bodyAnnot.addMemberValue("col", colValue);attribute.addAnnotation(bodyAnnot);fieldInfo.addAttribute(attribute);}pool.clearImportedPackages();return ctClass.toClass().newInstance();}
相关文章:
动态添加字段和注解,形成class类,集合对象动态创建Excel列
一.需求 动态生成Excel列,因为Excel列是通过类对象字段注解来添加,在不确定Excel列数的情况下,就需要动态生成列,对应类对象字段也需要动态生成; 二.ByteBuddy字节码增强动态创建类 1.依赖 <dependencies><…...

Python爬虫---Scrapy框架---CrawlSpider
CrawlSpider 1. CrawlSpider继承自scrapy.Spider 2. CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求,所以,如果有需要跟进链接的需求,意思就是…...

关机恶搞小程序
1. system("shutdown")的介绍 当system函数的参数是"shutdown"时,它将会执行系统的关机命令。 具体来说,system("shutdown")的功能是向操作系统发送一个关机信号,请求关闭计算机。这将触发操作系统执行一系列…...

《HTML 简易速速上手小册》第9章:HTML5 新特性(2024 最新版)
文章目录 9.1 HTML5 新增标签和属性9.1.1 基础知识9.1.2 案例 1:创建一个结构化的博客页面9.1.3 案例 2:使用新的表单元素创建事件注册表单9.1.4 案例 3:创建一个具有高级搜索功能的搜索表单 9.2 HTML5 表单增强9.2.1 基础知识9.2.2 案例 1&a…...
计算机网络之NAT
NAT(网络地址转换,Network Address Translation)是一种网络技术,用于在一个网络与另一个网络之间重新映射IP地址。NAT最常见的应用是在家庭和小型办公室的路由器中,用于将私有(内部)IP地址转换为…...
SQL - 数据操作语句
SQL - 数据操作语句 文章目录 SQL - 数据操作语句数据操作语言-DML1 新增2 修改3 删除4 清空 数据类型1 数值类型2 字符串类型3 日期时间类型 数据操作语言-DML 概念: DML(Data Manipulation Language), 数据操作语言。对数据表数据的增、删…...

【Python笔记-设计模式】单例模式
一、说明 单例是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 (一) 解决问题 维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。 …...
Java使用io流生成pdf文件
首先生成pdf和正常请求接口一样,直接写~ Controller层: 第一个注解:最顶层增加 Controller 注解(控制器)不多讲了 直接加上。 第二个注解:最顶层增加 CrossOrigin 注解此注解是为了浏览器请求的时候防…...

STL-priority_queue
文档 目录 1.关于priority_queued1的定义 2.priority_queue的使用 1.关于priority_queued1的定义 1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于堆,在堆中可以随时插入元…...
SpringBoot基于注解形式配置多数据源@DS
TOC() 1.引入依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version></dependency>2.配置…...

华清远见作业第三十四天——C++(第三天)
思维导图: 题目: 设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。 代码&#…...

Shell中正则表达式
1.正则表达式介绍 1、正则表达式---通常用于判断语句中,用来检查某一字符串是否满足某一格式 2、正则表达式是由普通字符与元字符组成 3、普通字符包括大小写字母、数字、标点符号及一些其他符号 4、元字符是指在正则表达式中具有特殊意义的专用字符,…...
Flutter Canvas 属性详解与实际运用
在Flutter中,Canvas是一个强大的绘图工具,允许我们以各种方式绘制图形、文字和图像。了解Canvas的属性是开发高度定制化UI的关键。在本篇博客中,我们将深入探讨Flutter中Canvas的一些重要属性,并展示它们在实际应用中的使用。 1.…...

Django配置websocket时的错误解决
基于移动群智感知的网络图谱构建系统需要手机app不断上传数据到服务器并把数据推到前端标记在百度地图上,由于众多手机向同一服务器发送数据,如果使用长轮询,则实时性差、延迟高且服务器的负载过大,而使用websocket则有更好的性能…...

(免费分享)springboot,vue在线考试系统
springboot 在线考试系统 前后端分离 一、项目简介 基于SpringBoot的在线考试系统 二、技术实现 后台框架:SpringBoot,mybatis-plus UI界面:Vue、ElementUI、Axios、Node.js(前后端分离) 数据库:MySQ…...

WebSocket 整合 记录用法
WebSocket 介绍 WebSocket 是基于tcp的一种新的网络协议,可以让浏览器 和 服务器进行通信,然后区别于http需要三次握手,websocket只用一次握手,就可以创建持久性的连接,并进行双向数据传输 Http和WebSocket的区别 Http是短连接,WebSocket’是长连接Http通信是单向的,基于请求…...

推荐5个我常用的软件,简单高效
今天给大家推荐5个我自己也常用的软件,可以解决很多问题,给你的学习和办公带来巨大帮助。 1.快速启动——Keypirinha Keypirinha是一款快速启动软件,可以让用户通过输入关键词来快速打开程序、文件、网页、搜索引擎等。Keypirinha支持…...
代码随想录训练营第三十一天|122.买卖股票的最佳时机II55.跳跃游戏45.跳跃游戏II
122.买卖股票的最佳时机II class Solution { public:int maxProfit(vector<int>& prices) {int earn0;for(int i 0; i < prices.size()-1;i){int x prices[i 1] - prices[i];if(x>0){earnx;}}return earn;} }; 55.跳跃游戏 本题关键在于看覆盖的范围 利…...
python17-Python的字符串格式化
Python提供了“%”对各种类型的数据进行格式化输出,例如如下代码。 # !/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2024/01# @Author : Laopiweight = 180print(老师傅的体重是 %s % weight) 上面程序就是格式化输出的关键代码,这行代码中的 print 函数包含三个部…...

HTTPS 之fiddler抓包--jmeter请求
一、浅谈HTTPS 我们都知道HTTP并非是安全传输,在HTTPS基础上使用SSL协议进行加密构成的HTTPS协议是相对安全的。目前越来越多的企业选择使用HTTPS协议与用户进行通信,如百度、谷歌等。HTTPS在传输数据之前需要客户端(浏览器)与服…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...