EasyExcel合并相同内容单元格及动态标题功能的实现

news2024/9/29 11:23:45

一、最初版本
导出的结果:
在这里插入图片描述
对应实体类代码:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.*;

import java.io.Serializable;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = "学校", order = 1)
    @ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = "姓名", order = 2)
    private String name;

    @ExcelProperty(value = "性别", order = 3)
    private String sex;

    @ExcelProperty(value = "年龄", order = 4)
    private String age;

    @ExcelProperty(value = "城市", order = 5)
    private String city;

    @ExcelProperty(value = "备注", order = 6)
    private String remarks;

    }

对应业务代码:

@ApiOperation(value = "导出学生信息", notes = "导出学生信息")
@PostMapping("/exportStudent")
public void exportStudent(@RequestBody String str, HttpServletResponse response) {
    List<StudentExportVo> list = this.getStudentExportVos();
    ExcelUtils.writeExcel(response, StudentExportVo.class, list, "导出学生信息", "sheet1");
}
//数据制造
private List<StudentExportVo> getStudentExportVos() {
    List<StudentExportVo> list = new ArrayList<>();
    StudentExportVo v1 = new StudentExportVo();
    v1.setSchool("北京大学");
    v1.setName("张三");
    v1.setSex("男");
    v1.setAge("20");
    v1.setCity("北京");
    v1.setRemarks("无");
    list.add(v1);
    StudentExportVo v2 = new StudentExportVo();
    v2.setSchool("北京大学");
    v2.setName("李四");
    v2.setSex("男");
    v2.setAge("22");
    v2.setCity("上海");
    v2.setRemarks("无");
    list.add(v2);
    StudentExportVo v3 = new StudentExportVo();
    v3.setSchool("北京大学");
    v3.setName("王五");
    v3.setSex("女");
    v3.setAge("22");
    v3.setCity("青岛");
    v3.setRemarks("无");
    list.add(v3);
    StudentExportVo v4 = new StudentExportVo();
    v4.setSchool("清华大学");
    v4.setName("赵六");
    v4.setSex("女");
    v4.setAge("21");
    v4.setCity("重庆");
    v4.setRemarks("无");
    list.add(v4);
    StudentExportVo v5 = new StudentExportVo();
    v5.setSchool("武汉大学");
    v5.setName("王强");
    v5.setSex("男");
    v5.setAge("24");
    v5.setCity("长沙");
    v5.setRemarks("无");
    list.add(v5);
    StudentExportVo v6 = new StudentExportVo();
    v6.setSchool("武汉大学");
    v6.setName("赵燕");
    v6.setSex("女");
    v6.setAge("21");
    v6.setCity("深圳");
    v6.setRemarks("无");
    list.add(v6);
    StudentExportVo v7 = new StudentExportVo();
    v7.setSchool("厦门大学");
    v7.setName("陆仟");
    v7.setSex("女");
    v7.setAge("21");
    v7.setCity("广州");
    v7.setRemarks("无");
    list.add(v7);
    return list;
}

二、使用注解的版本
导出的结果:
在这里插入图片描述
对应实体类代码:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = {"学生信息","学校"}, order = 1)
    @ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = {"学生信息","姓名"}, order = 2)
    private String name;

    @ExcelProperty(value = {"学生信息","性别"}, order = 3)
    private String sex;

    @ExcelProperty(value = {"学生信息","年龄"}, order = 4)
    private String age;

    @ExcelProperty(value = {"学生信息","城市"}, order = 5)
    private String city;

    @ExcelProperty(value = {"学生信息","备注"}, order = 6)
    private String remarks;

    }

对应业务代码:同上

@ContentLoopMerge(eachRow = 3) 可以合并单元格,但是他是按指定行数合并,并不能实现内容相同的合并

@ExcelProperty(value = {“学生信息”,“备注”},能实现多个标题,但标题是固定的,不是动态的

三、自定义改造
导出的结果:
在这里插入图片描述

对应实体类代码:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = {"学生信息","学校"}, order = 1)
    //@ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = {"学生信息","姓名"}, order = 2)
    private String name;

    @ExcelProperty(value = {"学生信息","性别"}, order = 3)
    private String sex;

    @ExcelProperty(value = {"学生信息","年龄"}, order = 4)
    private String age;

    @ExcelProperty(value = {"学生信息","城市"}, order = 5)
    private String city;

    @ExcelProperty(value = {"学生信息","备注"}, order = 6)
    private String remarks;

}

对应业务代码:

@ApiOperation(value = "导出学生信息", notes = "导出学生信息")
    @PostMapping("/exportStudent")
    public void exportStudent(@RequestBody String dynamicTitle, HttpServletResponse response) {
        List<StudentExportVo> list = this.getStudentExportVos();
        try {
            String fileName = "学生信息";
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            ServletOutputStream output = response.getOutputStream();
            //需要合并的列
            int[] mergeColumeIndex = {0};
            // 从第二行后开始合并
            int mergeRowIndex = 2;
            //设置动态标题
            List<List<String>> headers = this.getHeaders("学生信息" + dynamicTitle);
            // 头的策略
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 背景设置为白色
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            /*WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short)20);
            headWriteCellStyle.setWriteFont(headWriteFont);*/

            // 内容的策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
            //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            // 背景绿色
            //contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            //设置 自动换行
            contentWriteCellStyle.setWrapped(true);
            //设置 垂直居中
            contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            //设置 水平居中
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            /*WriteFont contentWriteFont = new WriteFont();
            // 字体大小
            contentWriteFont.setFontHeightInPoints((short)20);
            contentWriteCellStyle.setWriteFont(contentWriteFont);*/
            // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

            EasyExcel.write(output, StudentExportVo.class)
                    .sheet("学生信息")
                    .head(headers)
                    .registerWriteHandler(new ExcelMergeHandler(mergeRowIndex, mergeColumeIndex))
                    .registerWriteHandler(horizontalCellStyleStrategy)
//                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(30))
                    .registerWriteHandler(new AbstractColumnWidthStyleStrategy() {
                        @Override
                        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
                            Sheet sheet = writeSheetHolder.getSheet();
                            int columnIndex = cell.getColumnIndex();
                            if(columnIndex == 5){
                                // 列宽100
                                sheet.setColumnWidth(columnIndex, 10000);
                            }else {
                                // 列宽50
                                sheet.setColumnWidth(columnIndex, 5000);
                            }
                            // 行高40
                            sheet.setDefaultRowHeight((short) 4000);
                        }
                    })
                    .doWrite(list);
            output.flush();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }


    private List<List<String>> getHeaders(String dynamicTitle) {
        List<List<String>> headers=new ArrayList<>();
        List<String> schoolHead=new ArrayList<>();
        schoolHead.add(dynamicTitle);
        schoolHead.add("学校");
        List<String> nameHead=new ArrayList<>();
        nameHead.add(dynamicTitle);
        nameHead.add("姓名");
        List<String> sexHead=new ArrayList<>();
        sexHead.add(dynamicTitle);
        sexHead.add("性别");
        List<String> ageHead=new ArrayList<>();
        ageHead.add(dynamicTitle);
        ageHead.add("年龄");
        List<String> cityHead=new ArrayList<>();
        cityHead.add(dynamicTitle);
        cityHead.add("城市");
        List<String> remarksHead=new ArrayList<>();
        remarksHead.add(dynamicTitle);
        remarksHead.add("备注");
        headers.add(schoolHead);
        headers.add(nameHead);
        headers.add(sexHead);
        headers.add(ageHead);
        headers.add(cityHead);
        headers.add(remarksHead);
        return headers;
    }

    //数据制造
    private List<StudentExportVo> getStudentExportVos() {
        List<StudentExportVo> list = new ArrayList<>();
        StudentExportVo v1 = new StudentExportVo();
        v1.setSchool("北京大学");
        v1.setName("张三");
        v1.setSex("男");
        v1.setAge("20");
        v1.setCity("北京");
        v1.setRemarks("无");
        list.add(v1);
        StudentExportVo v2 = new StudentExportVo();
        v2.setSchool("北京大学");
        v2.setName("李四");
        v2.setSex("男");
        v2.setAge("22");
        v2.setCity("上海");
        v2.setRemarks("无");
        list.add(v2);
        StudentExportVo v3 = new StudentExportVo();
        v3.setSchool("北京大学");
        v3.setName("王五");
        v3.setSex("女");
        v3.setAge("22");
        v3.setCity("青岛");
        v3.setRemarks("无");
        list.add(v3);
        StudentExportVo v4 = new StudentExportVo();
        v4.setSchool("清华大学");
        v4.setName("赵六");
        v4.setSex("女");
        v4.setAge("21");
        v4.setCity("重庆");
        v4.setRemarks("无");
        list.add(v4);
        StudentExportVo v5 = new StudentExportVo();
        v5.setSchool("武汉大学");
        v5.setName("王强");
        v5.setSex("男");
        v5.setAge("24");
        v5.setCity("长沙");
        v5.setRemarks("无");
        list.add(v5);
        StudentExportVo v6 = new StudentExportVo();
        v6.setSchool("武汉大学");
        v6.setName("赵燕");
        v6.setSex("女");
        v6.setAge("21");
        v6.setCity("深圳");
        v6.setRemarks("无");
        list.add(v6);
        StudentExportVo v7 = new StudentExportVo();
        v7.setSchool("厦门大学");
        v7.setName("陆仟");
        v7.setSex("女");
        v7.setAge("21");
        v7.setCity("广州");
        v7.setRemarks("无");
        list.add(v7);
        return list;
    }

合并单元格相同内容处理类:ExcelMergeHandler

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;
public class ExcelMergeHandler implements CellWriteHandler {
    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public ExcelMergeHandler() {
    }

    public ExcelMergeHandler(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();

        if (curRowIndex > mergeRowIndex) {
            for (int i = 0; i < mergeColumnIndex.length; i++) {
                if (curColIndex == mergeColumnIndex[i]) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }
    }



 /**
     * 当前单元格向上合并
     *
     * @param writeSheetHolder
     * @param cell             当前单元格
     * @param curRowIndex      当前行
     * @param curColIndex      当前列
     */
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
        // 将当前单元格数据与上一个单元格数据比较
        Boolean dataBool = preData.equals(curData);
        //此处需要注意:因为我是按照工程名称确定是否需要合并的,所以获取每一行第二列数据和上一行第一列数据进行比较,如果相等合并,getCell里面的值,是工程名称所在列的下标
        String s1 = cell.getRow().getCell(0).getStringCellValue();
        String s2 = cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue();
        /*BigDecimal d1 = new BigDecimal(cell.getRow().getCell(0).getNumericCellValue());
        BigDecimal d2 = new BigDecimal(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getNumericCellValue());*/
        Boolean bool = s1.compareTo(s2) == 0 ? true:false;
        // 原始的
        // Boolean bool =  cell.getRow().getCell(1).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(1).getStringCellValue());
        if (dataBool && bool) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一个单元格未被合并,则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }
}

总结:

1、使用自定义合并相同内容单元格时,实体类中的注解@ContentLoopMerge需要去掉,要不然会受到影响

2、该段自定义代码中如内容合并、设置动态标题、内容、以及每个列的宽度及字体都是可以根据自定义策略来进行设置的,具体用法可以参考代码注释说明,根据需要进行使用

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

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

相关文章

qt-C++笔记之使用QLabel和QPushButton实现一个bool状态的指示灯

qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯 code review! 文章目录 qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯1.QPushButton实现2.QLabel实现2.QLabel实现-对错符号 1.QPushButton实现 运行 代码 #include <QtWidgets>class Ind…

Spring Boot + MinIO 实现文件切片极速上传技术

文章目录 1. 引言2. 文件切片上传简介3. 技术选型3.1 Spring Boot3.2 MinIO 4. 搭建Spring Boot项目5. 集成MinIO5.1 配置MinIO连接信息5.2 MinIO配置类 6. 文件切片上传实现6.1 控制器层6.2 服务层6.3 文件切片上传逻辑 7. 文件合并逻辑8. 页面展示9. 性能优化与拓展9.1 性能优…

ros2机器人在gazebo中移动方案

原文连接Gazebo - Docs: Moving the robot (gazebosim.org) 很重要的地方&#xff1a;使用虚拟机运行Ubuntu的时候&#xff0c;需要关闭”加速3D图形“的那个选项&#xff0c;否则gazebo无法正常显示。 Moving the robot&#xff08;使用命令移动机器人示例&#xff09; In t…

maven 项目导入异常问题

问题如下 一、 tomcat正再运行的包是哪一个 不同构建、打包情况下分别运行 out\artifacts下 当直接去Project Structure下去构建artifacts 后&#xff0c;运行tomcat 则会在out下target下 reimport项目后,则会在artifacts自动生成部署包。删除tomcat之前deployment 下的包(同…

一种基于外观-运动语义表示一致性的视频异常检测框架 论文阅读

A VIDEO ANOMALY DETECTION FRAMEWORK BASED ON APPEARANCE-MOTION SEMANTICS REPRESENTATION CONSISTENCY 论文阅读 ABSTRACT1. INTRODUCTION2. PROPOSED METHOD3. EXPERIMENTAL RESULTS4. CONCLUSION阅读总结&#xff1a; 论文标题&#xff1a;A VIDEO ANOMALY DETECTION FRA…

线上环境如何正确配置 Django 的 DEBUG?

Author&#xff1a;rab Django Version&#xff1a;3.2 Python Version&#xff1a;3.9 目录 前言一、DEBUG True二、DEBUG False三、页面异常解决总结 前言 由于最近在学习 Django 的知识&#xff0c;于是尝试开发了一套 Blog 系统&#xff0c;在本地测试时是页面显示没问题…

数据智慧:如何利用可视化提升效率

数据可视化是一项强大的工具&#xff0c;能够显著提高工作效率和决策的准确性。下面我就以可视化从业者的角度&#xff0c;简单谈谈数据可视化是如何助力效率提升的。 直观理解复杂数据 数据可视化将抽象的数据转化为图表、图形或仪表盘&#xff0c;使数据更易于理解。这种直观…

智能优化算法应用:基于瞬态优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于瞬态优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于瞬态优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.瞬态优化算法4.实验参数设定5.算法结果6.…

中小型企业怎么选SD-WAN?

随着网络技术的发展&#xff0c;SD-WAN作为一种高效灵活的网络连接被越来越多的企业选用。在SD-WAN的组网过程中&#xff0c;中小型企业需要怎么做&#xff0c;以确保SD-WAN的成功实施&#xff1f;本文将详细介绍中小型企业在SD-WAN组网时需要考虑的关键因素&#xff0c;助力企…

IDEA shorten command line介绍和JAR manifest 导致mybatis找不到接口类处理

如果类路径太长&#xff0c;或者有许多VM参数&#xff0c;程序就无法启动。原因是大多数操作系统都有命令行长度限制。在这种情况下&#xff0c;IntelliJIDEA将试图缩短类路径。最好选中 classpath file模式。 shorten command line 选项提供三种选项缩短类路径。 none&#x…

node.js mongoose中间件(middleware)

目录 简介 定义模型 注册中间件 创建doc实例&#xff0c;并进行增删改查 方法名和注册的中间件名相匹配 执行结果 分析 错误处理中间件 手动抛出错误 注意点 简介 在mongoose中&#xff0c;中间件是一种允许在执行数据库操作前&#xff08;pre&#xff09;或后&…

机器学习---聚类(原型聚类、密度聚类、层次聚类)

1. 原型聚类 原型聚类也称为“基于原型的聚类” (prototype-based clustering)&#xff0c;此类算法假设聚类结构能通过一 组原型刻画。算法过程&#xff1a;通常情况下&#xff0c;算法先对原型进行初始化&#xff0c;再对原型进行迭代更新求解。著 名的原型聚类算法&#…

SQL进阶理论篇(十四):CBO优化器是如何计算代价的?

文章目录 简介能调整的代价模型的参数有哪些&#xff1f;mysql.server_costmysql.engine_cost 如何修改这些代价参数&#xff1f;代价模型具体是如何计算的参考文献 简介 大部分RDBMS都支持基于代价的优化器CBO&#xff0c;但其实CBO仍然存在缺陷&#xff08;比如参数配置的不…

OpenAI 疑似正在进行 GPT-4.5 灰度测试!

‍ 大家好&#xff0c;我是二狗。 今天&#xff0c;有网友爆料OpenAI疑似正在进行GPT-4.5灰度测试&#xff01; 当网友询问ChatGPT API调用查询模型的确切名称是什么时&#xff1f; ChatGPT的回答竟然是 gpt-4.5-turbo。 也有网友测试之后发现仍然是GPT-4模型。 这是有网友指…

解决腾讯云CentOS 6硬盘空间不足问题:从快照到数据迁移

引言&#xff1a; 随着数据的不断增加&#xff0c;服务器硬盘空间不足变成了许多运维人员必须面对的问题。此主机运行了httpd&#xff08;apache服务&#xff09;&#xff0c;提供对外web访问服务,web资源挂载在**/data/wwwroot目录下,http日志存放在/data/wwwlogs目录下&…

【MATLAB源码-第101期】基于matlab的蝙蝠优化算BA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 蝙蝠算法&#xff08;BA&#xff09;是一种基于群体智能的优化算法&#xff0c;灵感来源于蝙蝠捕食时的回声定位行为。这种算法模拟蝙蝠使用回声定位来探测猎物、避开障碍物的能力。在蝙蝠算法中&#xff0c;每只虚拟蝙蝠代表…

【Hadoop精讲】HDFS详解

目录 理论知识点 角色功能 元数据持久化 安全模式 SecondaryNameNode(SNN) 副本放置策略 HDFS写流程 HDFS读流程 HA高可用 CPA原则 Paxos算法 HA解决方案 HDFS-Fedration解决方案&#xff08;联邦机制&#xff09; 理论知识点 角色功能 元数据持久化 另一台机器就…

SpringCloud微服务 【实用篇】| Docker镜像、容器、数据卷操作

目录 一&#xff1a;Docker基本操作 1. 镜像操作 镜像相关命令 2. 容器操作 容器相关命令 3. 数据卷&#xff08;容器数据管理&#xff09; 数据卷 操作数据卷 挂载数据卷 挂载的方式区别 前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…

MySQL面试经典50题

本文使用的MySQL版本为5.7.21&#xff0c;需要的数据表创建如下&#xff1a; 1.学生表student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10))…

jdk 线程池与 tomcat 线程池对比

一、线程池的作用 1. 提高性能&#xff1a;线程的创建需要开辟虚拟机栈、本地方法栈、程序计数器等线程私有空间&#xff0c;同时也会一比一的创建一个内核线程&#xff0c;在线程销毁时需要回收这些系统资源。频繁地创建和销毁线程会大大浪费系统资源&#xff0c;这时候就需要…