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

【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)

文章目录

  • 前言
  • 正文
    • 一、POM依赖
    • 二、核心Java文件
      • 2.1 自定义表头注解 ExcelColumnTitle
      • 2.2 自定义标题头的映射接口
      • 2.3 自定义有序map存储表内数据
      • 2.4 表头工厂
      • 2.5 表flag和表头映射枚举
      • 2.6 测试用的实体
        • 2.6.1 NameAndFactoryDemo
        • 2.6.2 StudentDemo
      • 2.7 启动类
      • 2.8 测试控制器
    • 三、测试
      • 测试1
      • 测试2
      • 测试3
      • 测试4

前言

日前,看到一个比较奇怪的导出功能。

需要根据不同的页面,以及指定不同的字段列表(任意顺序),然后导出对应的表格。

先假设一个场景:
假如你的系统有多个列表展示页,每页中可以依据筛选条件,调整展示的列的个数,顺序等。然后要求导出的时侯,导出一摸一样的格式。也就是“所见即所得”的表格。

那么基于以上场景,我们就来考虑下如何实现?
本文就是对以上场景功能的一个实现。目前仅支持单sheet,不支持数据聚合等。

正文

本文项目环境:
java 8,springboot2.2.0, easyexcel

一、POM依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.11</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></exclusion></exclusions></dependency></dependencies>

二、核心Java文件

此处粘贴全部的java文件
在这里插入图片描述

2.1 自定义表头注解 ExcelColumnTitle

package headbean;import java.lang.annotation.*;/*** 列名标题注解,标注列的标题** @author feng*/
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelColumnTitle {String value();
}

2.2 自定义标题头的映射接口

此接口仅仅是用于规范实体,以及用于辅助实现导出功能。

package headbean;/*** excel头部映射接口,用于规范导出的实体类** @author feng*/
public interface ExcelHeadMapInterface {
}

2.3 自定义有序map存储表内数据

这个是表格导出时,字段数量,顺序的关键。

package headbean;import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;/*** 表格数据专用的map,带顺序,而且初始化的时候,依据指定的表头变量字段名确定导出数据的顺序** @author feng*/
public class ExcelDataLinkedHashMap<V> extends LinkedHashMap<String, V> {private static final long serialVersionUID = -8554095999151235982L;/*** 头部字段名缓存*/private final Set<String> headColumnNamesCache;/*** ExcelDataLinkedHashMap构造器** @param headColumnNames 表头字段变量名,例如:[name,studentNo,age,className]*/public ExcelDataLinkedHashMap(List<String> headColumnNames) {// 字段名去重headColumnNames = headColumnNames.stream().distinct().collect(Collectors.toList());// 构建字段名缓存this.headColumnNamesCache = new HashSet<>(headColumnNames);// 指定列数据排列顺序for (String headColumnName : headColumnNames) {this.put(headColumnName, null);}}@Overridepublic V put(String key, V value) {// 只保存字段名缓存中的key以及valueif (headColumnNamesCache.contains(key)) {return super.put(key, value);}return null;}
}

2.4 表头工厂

负责实现初始化表头字段名,以及后期使用时,从中获取表头信息。
核心功能是解析自定义的表头注解。

package factory;import enums.ExcelHeadBeanFlagEnum;
import headbean.ExcelColumnTitle;
import headbean.ExcelHeadMapInterface;import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class ExcelHeadMapFactory {/*** 全局表头名映射,ExcelHeadMapInterface实现类型为key,它内部变量的变量名和中文名映射为value*/private static final Map<Class<? extends ExcelHeadMapInterface>, Map<String, String>> HEAD_NAME_MAP = new HashMap<>();public static void addHeadClass(Class<? extends ExcelHeadMapInterface> headClass) {HEAD_NAME_MAP.put(headClass, mapToPrepareHead(headClass));}public static Map<String, String> getHeadMap(Class<? extends ExcelHeadMapInterface> headClass) {return HEAD_NAME_MAP.get(headClass);}public static Map<String, String> getHeadMapByFlag(String flag) {return getHeadMap(ExcelHeadBeanFlagEnum.getHeadClass(flag));}private static Map<String, String> mapToPrepareHead(Class<?> excelHeadClass) {Map<String, String> namedMap = new HashMap<>();Field[] declaredFields = excelHeadClass.getDeclaredFields();for (Field declaredField : declaredFields) {boolean annotationPresent = declaredField.isAnnotationPresent(ExcelColumnTitle.class);if(annotationPresent) {ExcelColumnTitle excelProperty = declaredField.getAnnotation(ExcelColumnTitle.class);String chineseFieldName = excelProperty.value();// 保存字段名和中文变量名namedMap.put(declaredField.getName(), chineseFieldName);}}return namedMap;}
}

2.5 表flag和表头映射枚举

这个枚举,如果你的系统这类功能很多。可以设计为数据库的方式做映射。然后以查字典表的方式,来处理。当然使用枚举大概率是够用了。

package enums;import headbean.ExcelHeadMapInterface;
import headbean.NameAndFactoryDemo;
import headbean.StudentDemo;
import lombok.AllArgsConstructor;
import lombok.Getter;import java.util.Arrays;/*** 表头flag枚举,映射flag与对应的实体类型;主要是可以根据flag找到对应实体类型。** @author feng*/
@Getter
@AllArgsConstructor
public enum ExcelHeadBeanFlagEnum {NAME_AND_FACTORY_DEMO("NameAndFactoryDemo", NameAndFactoryDemo.class),STUDENT_DEMO("StudentDemo", StudentDemo.class);private final String flag;private final Class<? extends ExcelHeadMapInterface> headClass;public static Class<? extends ExcelHeadMapInterface> getHeadClass(String flag) {return Arrays.stream(values()).filter(bean -> bean.getFlag().equals(flag)).findFirst().orElseThrow(RuntimeException::new).getHeadClass();}
}

2.6 测试用的实体

2.6.1 NameAndFactoryDemo
package headbean;import lombok.Data;@Data
public class NameAndFactoryDemo implements ExcelHeadMapInterface {@ExcelColumnTitle("名字")private String name;@ExcelColumnTitle("工厂")private String factory;
}
2.6.2 StudentDemo
package headbean;import lombok.Data;@Data
public class StudentDemo implements ExcelHeadMapInterface {@ExcelColumnTitle("姓名")private String name;@ExcelColumnTitle("年龄")private Integer age;@ExcelColumnTitle("学号")private String studentNo;@ExcelColumnTitle("班级")private String className;
}

2.7 启动类

主要是项目启动后,注册表头数据到内存。

package org.feng;import factory.ExcelHeadMapFactory;
import headbean.ExcelHeadMapInterface;
import headbean.NameAndFactoryDemo;
import headbean.StudentDemo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import java.util.ArrayList;
import java.util.List;@SpringBootApplication
public class ExcelDemoApplication implements CommandLineRunner {public static void main(String[] args) {SpringApplication.run(ExcelDemoApplication.class, args);}@Overridepublic void run(String... args) throws Exception {List<Class<? extends ExcelHeadMapInterface>> needRegisterExcelHeadClassList = new ArrayList<>();needRegisterExcelHeadClassList.add(NameAndFactoryDemo.class);needRegisterExcelHeadClassList.add(StudentDemo.class);needRegisterExcelHeadClassList.forEach(ExcelHeadMapFactory::addHeadClass);}
}

2.8 测试控制器

package org.feng;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import enums.ExcelHeadBeanFlagEnum;
import factory.ExcelHeadMapFactory;
import headbean.ExcelDataLinkedHashMap;
import headbean.ExcelHeadMapInterface;
import headbean.NameAndFactoryDemo;
import headbean.StudentDemo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.function.BiFunction;@Controller
@RequestMapping("/excel")
public class ExcelDemoController {@GetMapping("/exportDy")public String exportDy(@RequestParam("flag")String flag,@RequestParam("table")List<String> table, HttpServletResponse response) throws IOException {String fileName = System.currentTimeMillis() + ".xlsx";Class<? extends ExcelHeadMapInterface> headClass = ExcelHeadBeanFlagEnum.getHeadClass(flag);Map<String, String> namedPrepareHeadMap = ExcelHeadMapFactory.getHeadMap(headClass);Map<String, String> head = new LinkedHashMap<>();for (String fieldName : table) {head.put(namedPrepareHeadMap.get(fieldName), fieldName);}List<Map<String, String>> excelDataList = new ArrayList<>();excelDataList.add(head);// 制造假数据for (BiFunction<Class<? extends ExcelHeadMapInterface>, List<Map<String, String>>, Boolean> biFunction : bizList) {Boolean applied = biFunction.apply(headClass, excelDataList);if(applied) {break;}}byte[] bytes = easyOut(excelDataList);response.setHeader("Content-disposition", "attachment;filename=" + fileName);response.setContentType("application/x-msdownload");response.setCharacterEncoding("utf-8");response.getOutputStream().write(bytes);response.getOutputStream().flush();return "success";}static final List<BiFunction<Class<? extends ExcelHeadMapInterface>, List<Map<String, String>>, Boolean>> bizList = new ArrayList<>();@PostConstructprivate void init() {bizList.add(this::genStudentDemoData);bizList.add(this::genNameAndFactoryDemoData);}private boolean genStudentDemoData(Class<? extends ExcelHeadMapInterface> headClass, List<Map<String, String>> excelDataList) {if(headClass == StudentDemo.class) {Map<String, String> headMap = excelDataList.get(0);for (int i = 0; i < 5; i++) {Collection<String> fieldNames = headMap.values();Map<String, String> data = new ExcelDataLinkedHashMap<>(new ArrayList<>(fieldNames));excelDataList.add(data);data.put("name", "张三"+(i+1));data.put("age", "年龄"+(i+1));data.put("studentNo", "学号"+(i+1));data.put("className", "班级"+(i+1));}return true;}return false;}private boolean genNameAndFactoryDemoData(Class<? extends ExcelHeadMapInterface> headClass, List<Map<String, String>> excelDataList) {if(headClass == NameAndFactoryDemo.class) {Map<String, String> headMap = excelDataList.get(0);for (int i = 0; i < 5; i++) {Collection<String> fieldNames = headMap.values();Map<String, String> data = new ExcelDataLinkedHashMap<>(new ArrayList<>(fieldNames));excelDataList.add(data);data.put("name", "张三"+(i+1));data.put("factory", "工厂"+(i+1));}return true;}return false;}/*** 导出数据(单sheet)* @param exportData key 是sheet名称,value是每个sheet里面的数据,支持自定义表头*/public static byte[] easyOut(List<Map<String, String>> exportData) {return easyOut(Collections.singletonMap("Sheet", exportData));}/*** 导出数据(多sheet)* @param exportData key 是sheet名称,value是每个sheet里面的数据,可以自定义*/public static byte[] easyOut(Map<String, List<Map<String, String>>> exportData) {// 导出数据ByteArrayOutputStream out = new ByteArrayOutputStream();com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(out).build();int i=0;for (Map.Entry<String, List<Map<String, String>>> entry: exportData.entrySet()) {WriteSheet writeSheet = EasyExcel.writerSheet(i, entry.getKey()).head(head(entry.getValue().get(0))).build();i++;excelWriter.write(data(entry.getValue(), true), writeSheet);}excelWriter.finish();return out.toByteArray();}private static List<List<String>> head(Map<String, String> cellData) {List<List<String>> head = new ArrayList<>();for (String key: cellData.keySet()) {head.add(Collections.singletonList(key));}return head;}private static List<List<String>> data(List<Map<String, String>> sheetData, boolean skipHead) {List<List<String>> data = new ArrayList<>();for (int i = 0; i < sheetData.size(); i++) {if(i == 0 && skipHead) {continue;}data.add(new ArrayList<>(sheetData.get(i).values()));}return data;}
}

三、测试

测试1

http://localhost:8080/excel/exportDy?flag=StudentDemo&table=name,studentNo,age,className

获得的表格内容为:
在这里插入图片描述

测试2

http://localhost:8080/excel/exportDy?flag=StudentDemo&table=name,studentNo,age

获得的表格内容为:
在这里插入图片描述

测试3

http://localhost:8080/excel/exportDy?flag=NameAndFactoryDemo&table=factory,name
获得的表格内容为:
在这里插入图片描述

测试4

http://localhost:8080/excel/exportDy?flag=StudentDemo&table=className,name,studentNo
获得的表格内容为:
在这里插入图片描述

相关文章:

【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)

文章目录 前言正文一、POM依赖二、核心Java文件2.1 自定义表头注解 ExcelColumnTitle2.2 自定义标题头的映射接口2.3 自定义有序map存储表内数据2.4 表头工厂2.5 表flag和表头映射枚举2.6 测试用的实体2.6.1 NameAndFactoryDemo2.6.2 StudentDemo 2.7 启动类2.8 测试控制器 三、…...

代码随想录算法训练营第四十二天 _ 动态规划_01背包问题、416.分割等和子集。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 二维数组处理01背包问题 听起来…...

市场上好用的aspera替代方案,你知道哪些

Aspera作为一个高速文件传输方案曾经非常受欢迎&#xff0c;但是其昂贵的价格却限制了许多用户的选择&#xff0c;因此市场上出现了众多Aspera替代方案&#xff0c;本文将会介绍市场上最好的Aspera替代方案。 最近几年&#xff0c;网络传输已成为现代商业运作中必不可少的一部…...

Stm32_串口的帧(不定长)数据接收

目录标题 前言1、串口中断接收固定帧头帧尾数据1.1、任务需求1.2、实现思路1.3、程序源码&#xff1a; 2、串口中断接收用定时器来判断帧结束3、串口中断接收数据空闲中断3.1、串口的空闲中断3.2、实现思路3.3、程序源码 4、串口的空闲中断DMA转运4.1、DMA简介4.2、DMA模式4.3、…...

L0、Linux常用命令

一、防火墙&#xff1a; 在 Linux 中&#xff0c;关闭防火墙可以使用不同的命令&#xff0c;这取决于你所使用的防火墙软件。在一些常见的 Linux 发行版中&#xff0c;防火墙可能是 iptables 或 firewalld两种&#xff1a; centos6使用iptables作为默认防火墙&#xff1b;cento…...

Golang实践录:读取toml配置

本文对 toml 文件进行解析。 下载 对于toml格式文件&#xff0c;golang 有很多库可以解释 yaml 文件&#xff0c;如toml、viper。由于 viper 可解析格式较多&#xff0c;本文采用该库。 toml语法规则 toml语法规则在官方中文文档上有说明&#xff0c;这里直接使用。 TOML 是…...

超大规模集成电路设计----基于阵列的可编程逻辑(七)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。本篇文章绝大部分资料来自中国科学院段成华教授PPT 超大规模集成电路设计----基于阵列的可编程逻辑&#xff08;七&#xff09; 7.1 引言7.1.1.回顾7.1.2. 数字逻辑系列Digital Logic Families7.1.3.从定制到半…...

深入探索FastAPI单元测试:使用TestClient轻松测试你的API

原文&#xff1a;深入探索FastAPI单元测试&#xff1a;使用TestClient轻松测试你的API-51CTO.COM 当使用FastAPI进行单元测试时&#xff0c;一个重要的工具是TestClient类。TestClient类允许我们模拟对FastAPI应用程序的HTTP请求&#xff0c;并测试应用程序的响应。这使我们能…...

基于ssm小型企业办公自动化系统论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对小型企业办公信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…...

CasADi - 最优控制开源 Python/MATLAB 库

系列文章目录 文章目录 系列文章目录前言一、介绍1.1 CasADi 是什么&#xff1f;1.2 帮助与支持1.3 引用 CasADi1.4 阅读本文档 二、获取与安装三、符号框架3.1 符号 SX3.1.1 关于命名空间的说明3.1.2 C 用户注意事项 3.2 DM3.3 符号 MX3.4 SX 和 MX 混合使用3.5 稀疏类3.5.1 获…...

Java中使用String字符串的注意事项

引言 介绍字符串在Java中的重要性和普遍性&#xff0c;以及本文将讨论的注意事项。 1. 字符串是不可变的 解释Java中字符串是不可变的概念&#xff0c;即一旦创建&#xff0c;字符串对象的值就不能被修改。强调在对字符串进行操作时应当创建新的字符串对象而不是修改原有的对…...

离线数仓构建案例一

数据采集 日志数据&#xff08;文件&#xff09;到Kafka 自己写个程序模拟一些用户的行为数据&#xff0c;这些数据存在一个文件夹中。 接着使用flume监控采集这些文件&#xff0c;然后发送给kafka中待消费。 1、flume采集配置文件 监控文件将数据发给kafka的flume配置文件…...

nginx优雅如何优雅的接管【跨域配置】

跨域问题太常见了&#xff0c;这里不做详细赘述。文章主要想说一下&#xff0c;如何统一管理和更好的来管理 跨域配置 跨域的常见配置有两种 后台代码设置和网关设置 1、后台代码设置 以springboot为例代码如下&#xff08;水一下文章长度...&#xff09; Configuration pu…...

远离危险的购买手机的渠道

今年上半年从淘宝特价版上面的官方旗舰店买了一个oppo手机&#xff0c;第一次买我打算不要了&#xff0c;所以就退了回去&#xff0c;过了几天我又觉得还是买一个比较好&#xff0c;所以就又买了一个&#xff0c;型号我绝不说了700-1000z这个价位的手机带个高通骁龙芯片的&…...

外包干了2个多月,技术明显有退步了。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...

【Java项目管理工具】Maven

Maven 文章目录 Maven一、简介二、安装和配置三、GAVP四、IDEA Maven Java Web工程五、插件、命令、生命周期六、依赖配置七、构建配置八、依赖传递与依赖冲突九、Maven工程继承和聚合关系9.1 工程继承关系9.2 工程聚合关系 十、Maven私服10.1 Nexus下载安装10.2 Nexus上的各种…...

solidity案例详解(六)服务评价合约

有服务提供商和用户两类实体&#xff0c;其中服务提供商部署合约&#xff0c;默认诚信为true&#xff0c;用户负责使用智能合约接受服务及评价&#xff0c;服务提供商的评价信息存储在一个映射中&#xff0c;可以根据服务提 供商的地址来查找评价信息。用户评价信息&#xff0c…...

使用kubeadm搭建高可用的K8s集群

文章目录 1. 安装要求2. 准备环境3. 所有master节点部署keepalived3.1 安装相关包和keepalived3.2配置master节点3.3 启动和检查 4. 部署haproxy4.1 安装4.2 配置4.3 启动和检查 5. 所有节点安装Docker/kubeadm/kubelet5.1 安装Docker5.2 添加阿里云YUM软件源5.3 安装kubeadm&a…...

C#图像处理OpenCV开发指南(CVStar,07)——通用滤波(Filter2D)的实例代码

1 函数定义 void Filter2D (Mat src, Mat dst, int ddepth, InputArray kernel, Point anchor Point(-1,-1), double delta 0, int borderType BORDER_DEFAULT ) 1.1 原型 #include <opencv2/imgproc.hpp> Convolves an image wit…...

c++函数模板STL详解

函数模板 函数模板语法 所谓函数模板&#xff0c;实际上是建立一个通用函数&#xff0c;其函数类型和形参类型不具体指定&#xff0c;用一个虚拟的类型来代表。这个通用函数就称为函数模板。 凡是函数体相同的函数都可以用这个模板来代替&#xff0c;不必定义多个函数&#xf…...

Java利用UDP实现简单群聊

一、创建新项目 首先新建一个新的项目&#xff0c;并按如下操作 二、实现代码 界面ChatFrame类 package 群聊; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.InetAddress; public abstract class ChatFrame extends JFrame { p…...

fastapi.templating与HTMLResponse

要声明一个模板对象&#xff0c;应将存储html模板的文件夹作为参数提供。在当前工作目录中&#xff0c;我们将创建一个 “templates “目录。 templates Jinja2Templates(directory“templates”) 我们现在要把这个页面的HTML代码渲染成HTMLResponse。让我们修改一下hello()函…...

当初为什么选择计算机这类的行业?

CSDN给了这么一个话题&#xff1a; 还记得当初自己为什么选择计算机&#xff1f; 当初你问我为什么选择计算机&#xff0c;我笑着回答&#xff1a;“因为我梦想成为神奇的码农&#xff01;我想像编织魔法一样编写程序&#xff0c;创造出炫酷的虚拟世界&#xff01;”谁知道&…...

tif文件转png、Excel

l利用gdal读取tif中的地理信息和波段数组&#xff0c;然后保存想要的格式即可。 from osgeo import gdal from PIL import Image import numpy as np import cv2 as cv from matplotlib import pyplot as plt# 读取.tif文件 def read_tif(file_path):dataset gdal.Open(file_…...

【PyTorch】训练过程可视化

文章目录 1. 训练过程中的可视化1.1. alive_progress1.2. rich.progress 2. 训练结束后的可视化2.1. tensorboardX2.1.1. 安装2.1.2. 使用 1. 训练过程中的可视化 主要是监控训练的进度。 1.1. alive_progress 安装 pip install alive_progress使用 from alive_progress i…...

深入理解Go语言GC机制

1、Go 1.3之前的标记-清除&#xff08;mark and sweep&#xff09;算法 Go 1.3之前的时候主要用的是普通的标记-清除算法&#xff0c;此算法主要由两个主要的步骤&#xff1a; 标记&#xff08;Mark phase&#xff09;清除&#xff08;Sweep phase&#xff09; 1&#xff09…...

qt-C++笔记之组件-分组框QGroupBox

qt-C笔记之组件-分组框QGroupBox code review! 文章目录 qt-C笔记之组件-分组框QGroupBox1.《Qt 6 C开发指南》p752.《Qt 官方文档》3.《Qt 5.12实战》——5.9 分组框控件 1.《Qt 6 C开发指南》p75 2.《Qt 官方文档》 中间段落翻译&#xff1a; 我把示例补充完整&#xff1a; …...

qt 定时器用法

在qt开发中&#xff0c;定时器是我们经常用到的。我们接下来说一下定时器的三种用法&#xff0c;需要注意的是定时器事件是在主线程中触发的&#xff0c;因此在处理耗时操作时应特别小心&#xff0c;以避免阻塞应用程序的事件循环。 1. 三种定时器使用 1.1 QObject的定时器 …...

用23种设计模式打造一个cocos creator的游戏框架----(九)访问者模式

1、模式标准 模式名称&#xff1a;访问者模式 模式分类&#xff1a;行为型 模式意图&#xff1a;将数据操作与数据结构分离&#xff0c;使得在不修改数据结构的前提下&#xff0c;可以添加或改变对数据的操作。 结构图&#xff1a; 适用于&#xff1a; 当你需要对一个复杂对…...

根文件系统初步测试

一. 简介 上一篇文章学习了向所编译生成的根文件系统中加入 lib库文件。文章地址如下&#xff1a; 根文件系统lib库添加与初步测试-CSDN博客 本文继上一篇文章的学习&#xff0c;本文对之前制作的根文件系统进行一次初步测试。 二. 根文件系统初步测试 为了方便测试&#…...

【精选】设计模式——策略设计模式-两种举例说明,具体代码实现

Java策略设计模式 简介 策略设计模式是一种行为型设计模式&#xff0c;它允许在运行时选择算法的行为。 在软件开发中&#xff0c;我们常常需要根据不同情况采取不同的行为。通常的做法是使用大量的条件语句来实现这种灵活性&#xff0c;但这会导致代码变得复杂、难以维护和扩…...

外包干了3个月,技术倒退2年。。。

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…...

微信小程序:chooseimage从本地相册选择图片或使用相机拍照

文档 https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html 代码示例 const res await uni.chooseImage({count: 1, //默认9sizeType: [original, compressed], //可以…...

「Swift」取消UITableView起始位置在状态栏下方开始

前言&#xff1a;在写页面UI时发现&#xff0c;当隐藏了NavigationBar时&#xff0c;即使UITableView是从(0,0)进行布局&#xff0c;也会一直在手机状态栏下方进行展示布局&#xff0c;而我的想法是希望UITableView可以从状态栏处就进行展示布局 当前页面展示&#xff1a; 问题…...

android高版本适配使用Tools.java

随着android版本的提升&#xff0c;原生Tools不公开并且不能被正常使用&#xff0c;为了延续项目的功能&#xff0c;修改如下&#xff1a; /** Copyright (C) 2006 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License&quo…...

面试官:说说webpack中常见的Loader?解决了什么问题?

面试官&#xff1a;说说webpack中常见的Loader&#xff1f;解决了什么问题&#xff1f; 一、是什么 loader 用于对模块的"源代码"进行转换&#xff0c;在 import 或"加载"模块时预处理文件 webpack做的事情&#xff0c;仅仅是分析出各种模块的依赖关系&a…...

【蓝桥杯省赛真题50】Scratch智能计价器 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解

目录 scratch智能计价器 一、题目要求 编程实现 二、案例分析 1、角色分析...

折半查找(数据结构实训)

题目&#xff1a; 标准输入输出 题目描述&#xff1a; 实现折半查找。要求查找给定的值在数据表中相应的存储位置。本题目假定输入元素均按非降序输入。 输入&#xff1a; 输入包含若干个测试用例&#xff0c;第一行为测试用例个数k。每个测试用例占3行&#xff0c;其中第一行为…...

AR助推制造业智能转型:实时远程协作与可视化引领生产创新

制造商面临着多方面的变革&#xff0c;技术的兴起催生了工业物联网&#xff08;IIoT&#xff09;&#xff0c;改变了现代工厂的外貌、系统和流程。同时&#xff0c;全球竞争压力和不断变化的员工队伍要求采用新的员工培训方法&#xff0c;并重新审视工人在工厂中的角色。尽管如…...

【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)

文章目录 本节最终效果前言素材人物移动音效枪口火焰和开火音效枪口灯光弹孔和火花添加武器随镜头手臂摇摆效果源码完结 本节最终效果 前言 本节主要实现添加音效&#xff0c;和一些特效、武器摆动调整。 素材 素材&#xff0c;为了方便我直接用了unity免费的音效输出&#…...

sed 流式编辑器

使用方式&#xff1a; 1&#xff0c;前置指令 | sed 选项 定址符指令 2&#xff0c;sed 选项 定址符指令 被处理文档 选项&#xff1a; -n 屏蔽默认输出 -i写入文件 -r支持扩展正则 指令&#xff1a; p输出 d删除 s替换 sed -n 1p user //输出第1行 sed -n…...

Linux shell编程学习笔记33:type 命令

目录 0 引言1 type 命令的功能和格式 1.1 type命令的功能1.2 type 命令的格式2 type命令用法实例 2.1用type命令查看shell内置命令&#xff08;以echo命令为例&#xff09;2.2 用type命令查看别名&#xff08;以ls命令为例&#xff09;2.3 用type命令同时查看shell内置命令和别…...

【数据结构】—红黑树(C++实现)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 &#x1f49c;本文前置知识&#xff1a; AVL树 ♈️今日夜电波&#xff1a;Letter Song—ヲタみん 1:36━━━━━━️&#x1f49f;──────── 5:35 …...

内衣洗衣机和手洗哪个干净?高性价比内衣洗衣机推荐

通常来说&#xff0c;我们的内衣裤对卫生要求比较高&#xff0c;毕竟是贴身穿的&#xff0c;所以如果和一般的衣物一起洗&#xff0c;就怕会有细菌互相感染。所以很多用户为了内衣裤的卫生都会选择自己手动洗&#xff0c;但手洗一方面很费时间和人力&#xff0c;另一方面又很伤…...

TikTok与互动广告:品牌如何打破传统界限

随着数字时代的蓬勃发展&#xff0c;广告行业也经历了翻天覆地的变革。在这个变革的浪潮中&#xff0c;TikTok作为一款崭新的社交媒体平台&#xff0c;通过其独特的短视频形式为品牌提供了全新的互动广告机会。 本文将深入探讨TikTok与互动广告的结合&#xff0c;以及品牌如何…...

跟着Nature Communications学习Hisat-Trinity-PASA等分析流程

一边学习,一边总结,一边分享! 详细教程请访问: 组学分析流程 本期分析流程 Hisat2-SamtoolsTrinity_GG_denovoPASA… 本期教程文章 题目:Genomic insights into local adaptation and future climate-induced vulnerability of a keystone forest tree in East Asia H…...

Unity中Batching优化的动态合批

文章目录 前言一、动态合批的规则1、材质相同是合批的前提&#xff0c;但是如果是材质实例的话&#xff0c;则一样无法合批。2、支持不同网格的合批3、动态合批需要网格支持的顶点条件二、我们导入一个模型并且制作一个Shader&#xff0c;来测试动态合批1、我们选择模型的 Mesh…...

2022年第十一届数学建模国际赛小美赛B题序列的遗传过程解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 B题 序列的遗传过程 原题再现&#xff1a; 序列同源性是指DNA、RNA或蛋白质序列之间的生物同源性&#xff0c;根据生命进化史中的共同祖先定义[1]。DNA、RNA或蛋白质之间的同源性通常根据它们的核苷酸或氨基酸序列相似性来推断。显著的相…...

【Linux】静态库与动态库制作及运行原理

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0. 静态库与动态库1. 制作与使用静态库2. 制作与使用动态库3. 动态库是如何被加载到内存&#xff1f;3.1程序地址空间 0. 静态库…...

工具站推荐

自己搭了一个文本工具站 TextTool&#xff0c;包含了常用的文本功能。 我自己比较常用 行转列、列转行、下划线替换的功能。 欢迎各位大佬提意见和建议...