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

Excel转Json编辑器工具

功能说明:根据 .xlsx 文件生成对应的 JSON 文件,并自动创建脚本

注意事项

  1. Excel 读取依赖
    本功能依赖 EPPlus 库,只能读取 .xlsx 文件。请确保将该脚本放置在 Assets 目录下的 Editor 文件夹中。同时,在 Editor 下再创建一个 Excel 目录,并将你的 .xlsx 文件放到 Excel 目录下。注意:该目录下只能有一个 .xlsx 文件,且该文件是唯一的数据源。

    • Excel 文件格式要求
      • 第一行:字段名(与自动生成脚本中的字段对应)。
      • 第二行:中文注释。
      • 第三行:字段的数据类型(目前支持 intfloatdoublestringbool 和数组类型,如 int[]string[])。
      • 第四行开始:实际数据。
    • Epplus依赖获取查看我的另一篇文章Nuget For Unity插件介绍_nugetforunity-CSDN博客

  1. 生成脚本与 JSON 文件
    使用编辑器中的 ExcelTool 进行生成,点击 读取 Excel 按钮后,将自动执行以下操作:

    • 删除之前生成的脚本目录和 JSON 目录(如果存在),然后重新生成它们。
    • 注意:在这两个目录下请不要放置其他文件,因为此工具会在每次生成时覆盖这些目录。
  2. 关于数组格式
    数组数据需要按如下格式写入:
    例如1|2|3。数组成员使用 | 分隔。

  3. 支持多 sheet
    一个 .xlsx 文件中可以包含多个 sheet。在读取时,工具会读取所有 sheet 数据。请注意:

    • 将每个 sheet 的名字改为与要生成的脚本名一致。
    • Sheet 名称必须符合 C# 的命名规范,建议使用 TB_ 开头。

提示

  • 脚本命名:请确保每个 sheet 的名字与生成的 C# 脚本的名称一致。
  • 字段类型:当前支持的字段类型包括基本数据类型(intfloatdoublestringbool)以及数组类型(如 int[]string[])。
  • 感谢原作者:特别感谢原作者“小人”的贡献,我仅添加了一些功能,以下是他在 B站的教程视频地址:Unity中简单根据excel文件自动生成对应的C#脚本及json文件_哔哩哔哩_bilibili

格式

保证这个目录格式

Excel格式

源码

using OfficeOpenXml;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System;
using UnityEditor;
using UnityEngine;/*功能:根据.xlsx文件生成对应的json文件,并自动创建脚本注意:一 Excel读取依赖EPPlus,只能读.xlsx文件,Asset下创建一个Editor,同时将该脚本放到Editor下然后在Editor下再创建一个Excel目录,然后将你的Excel文件放到Excel目录下,注意Excel目录下只能有一个Excel文件,同时Excel格式要符合下列要求,最后Excel是唯一的数据源,所以除了保护好你的Excel文件外,其他的可以重新生成.使用编辑器上的ExcelTool/读取Excel按钮生成Json和脚本使用该按钮会删除脚本目录和json目录然后重新生成(如果已经生成过),所以不要在这两个目录下放置其他文件.二 xlsx第一行为英文字段与自动生成脚本中的字段对应第二行为中文注释第三行为字段的数据类型,目前支持int float double string bool 数组数组的写法统一为基本数据类型+[] 如int[] 、string[]第四行开始为实际数据三 xlsx文件中可以有很多sheet.读取时会读取xlsx的全部sheet要将对应的sheet的名字改为与要生成的脚本名一致,所以sheet名要符合C#的命名规范,建议使用TB_开头四 数组的书写格式形如:1|2|3,数组成员使用|分隔五 感谢原作者小人,我仅做了一些功能补充,下面的地址是小人的b站视频地址*/
[HelpURL("https://www.bilibili.com/video/BV16f421Q7zA/?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=f9b5906b25cd5ca40ec79f317993905b")]
public class ExcelTool
{//命名空间列表private static List<string> nameSpaceList = new List<string>(){ "using System;", "[Serializable]"};//Root目录,包含Excel本身,Excel生成的json和脚本private static readonly string excel = Application.dataPath + "/Editor/Excel";//Excel文件private static string excelFilePath = excel;//脚本目录private static readonly string scriptsFolder = excel + "/ExcelScripts";//json目录private static string jsonFolder = excel + "/Json";[MenuItem("ExcelTool/读取Excel")]public static void TestTool(){// 获取目录下所有以 .xlsx 结尾的文件(不包括子目录中的文件)string[] files = Directory.GetFiles(excel, "*.xlsx");if (files.Length > 0){// 获取第一个文件的完整路径string firstFilePath = files[0];// 获取文件名(不包括路径)string fileName = Path.GetFileName(firstFilePath);excelFilePath = excelFilePath + "/" + fileName;}if (!File.Exists(excelFilePath)){Debug.LogError("excel文件不存在");return;}CreateDirectory(scriptsFolder);CreateDirectory(jsonFolder);var res = ReadExcel(excelFilePath);for (int i = 0; i < res.Count; i++){string path = scriptsFolder + "/" + res[i].scriptName + ".cs";CreateAScript(path, res[i].scriptName, nameSpaceList, res[i].fieldType, res[i].fieldName);CreateAJson(res[i].scriptName, res[i].fieldType, res[i].fieldName, res[i].dataDic);}AssetDatabase.Refresh();}private static void CreateDirectory(string path){if (!Directory.Exists(path)){Directory.CreateDirectory(path);}else{path = ConvertToRelativePath(path);var b = AssetDatabase.DeleteAsset(path);Directory.CreateDirectory(path);}}// 将绝对路径转为相对路径private static string ConvertToRelativePath(string absolutePath){// 获取项目的 'Assets' 文件夹路径string assetsPath = Application.dataPath;// 确保返回的路径是相对于 'Assets' 文件夹的if (absolutePath.StartsWith(assetsPath)){// 去掉 Application.dataPath 前缀,返回相对路径return "Assets" + absolutePath.Substring(assetsPath.Length);}Debug.LogError("路径不在 Assets 目录内: " + absolutePath);return absolutePath;}/// <summary>/// 读取 .xlsx文件,获取第一张sheet的内容/// </summary>/// <param name="path"></param>/// <returns></returns>private static List<(string scriptName, List<string> fieldType, List<string> fieldName, Dictionary<int, List<string>> dataDic)>ReadExcel(string path){int sheetsCount;var list = new List<(string scriptName, List<string> fieldType, List<string> fieldName, Dictionary<int, List<string>> dataDic)>();FileInfo fileInfo = new FileInfo(path);using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)){sheetsCount = excelPackage.Workbook.Worksheets.Count;}for (int z = 0; z < sheetsCount; z++){//生成的脚本名string scriptName;//字段类型列表List<string> fieldType = new List<string>();//字段名列表List<string> fieldName = new List<string>();//.xlsx除注释行之外的相关数据Dictionary<int, List<string>> dataDic = new Dictionary<int, List<string>>();using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)){//取得.xlsx中的第一张sheet(EPPlus中下标从1或者0开始,取决于版本)ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[z];if (worksheet == null){sheetsCount++;continue;}//取sheet的名字,即生成的脚本名scriptName = worksheet.Name;//取英文字段名//遍历表格第一行取字段名 注意索引下标for (int i = 1; i <= worksheet.Dimension.End.Column; i++){if (worksheet.Cells[1, i].Value is null){Debug.LogError($"当前{worksheet}中第1行第{i}个单元格数据为空");return null;}string field = worksheet.Cells[1, i].Value.ToString();fieldName.Add(field);}//取字段类型//遍历第三行 同上for (int i = 1; i <= worksheet.Dimension.End.Column; i++){if (worksheet.Cells[3, i].Value is null){Debug.LogError($"当前{worksheet}中第3行第{i}个单元格数据为空");return null;}string field = worksheet.Cells[3, i].Value.ToString();fieldType.Add(field);}//取实际数据for (int k = 4; k <= worksheet.Dimension.End.Row; k++){List<string> realData = new List<string>();for (int j = 1; j <= worksheet.Dimension.End.Column; j++){if (worksheet.Cells[k, j].Value is null){Debug.LogError($"当前{worksheet}中第{k}行第{j}个单元格数据为空");return null;}string data = worksheet.Cells[k, j].Value.ToString();realData.Add(data);}dataDic[k] = realData;}}list.Add((scriptName, fieldType, fieldName, dataDic));}return list;}/// <summary>/// 判断字符串列表中是否包含重复成员,有,返回true/// </summary>/// <param name="list"></param>/// <returns></returns>private static bool HasRepeatedMember(List<string> list){//往HaseSet中添加字符串,若不成功添加,说明有重复字符串 HashSet<string> hashSet = new HashSet<string>();for (int i = 0; i < list.Count; i++){if (!hashSet.Add(list[i])){return true;}}return false;}/// <summary>/// 创建一个C#脚本/// </summary>/// <param name="path">脚本保存路径</param>/// <param name="scriptName">脚本名</param>/// <param name="nameSpaceList">命名空间列表</param>/// <param name="fieldType">字段类型列表</param>/// <param name="fieldName">字段名列表</param>private static void CreateAScript(string path, string scriptName, List<string> nameSpaceList,List<string> fieldType, List<string> fieldName){#region 安全校验if (fieldType is null || fieldType.Count == 0){Debug.LogError($"{scriptName}字段类型列表错误");return;}if (fieldName is null || fieldName.Count == 0){Debug.LogError($"{scriptName}字段名列表错误");return;}if (nameSpaceList is null || nameSpaceList.Count == 0){Debug.LogError($"{scriptName}命名空间列表错误");return;}if (fieldType.Count != fieldName.Count){Debug.LogError($"{scriptName}字段类型列表与字段名列表长度不一致");return;}//生成的字段以字母开头for (int i = 0; i < fieldName.Count; i++){if (!Regex.IsMatch(fieldName[i], @"^[a-zA-Z_]")){Debug.LogError($"{scriptName}中字段名应以字母开头");return;}}//避免生成字段重复if (HasRepeatedMember(fieldName)){Debug.LogError($"{scriptName}中出现重复字段");return;}#endregionusing (StreamWriter writer = new StreamWriter(path)){//写入命名空间for (int i = 0; i < nameSpaceList.Count; i++){writer.WriteLine(nameSpaceList[i]);}//写入脚本名writer.WriteLine($"public class {scriptName}");writer.WriteLine("{");//写入类型及字段for (int i = 0; i < fieldName.Count; i++){writer.WriteLine($"public {fieldType[i]} {fieldName[i]} ;");}writer.WriteLine("}");}}/// <summary>/// 创建json文件/// </summary>/// <param name="jsonName">json文件名</param>;/// <param name="fieldType">字段类型列表</param>/// <param name="fieldName">字段名列表</param>/// <param name="dataDic">实际数据字典</param>private static void CreateAJson(string jsonName, List<string> fieldType, List<string> fieldName, Dictionary<int, List<string>> dataDic){//写一行数据StringBuilder sb = new StringBuilder();sb.Append("[\n");for (int i = 4; i < dataDic.Count + 4; i++){//写一行 追加string s = GetALine(fieldType, fieldName, dataDic[i]);sb.Append(s);//不是最后一项数据,加逗号if (i != dataDic.Count + 3){sb.Append(",");}//换行sb.Append("\n");}//写最后一个括号sb.Append("]\n");string path = jsonFolder + "/" + jsonName + ".json";using (StreamWriter writer = new StreamWriter(path)){writer.WriteLine(sb.ToString());}}/// <summary>/// 将一行excel转为一行json/// </summary>/// <param name="fieldType">字段类型列表</param>/// <param name="fieldName">字段名列表</param>/// <param name="dataList">实际一行数据</param>/// <returns></returns>/// <exception cref="Exception"></exception>private static string GetALine(List<string> fieldType, List<string> fieldName, List<string> dataList){StringBuilder sb = new StringBuilder();//写括号sb.Append("{");//遍历列表 for (int i = 0; i < fieldType.Count; i++){//写入主键string key = fieldName[i];sb.Append($"\"{key}\":");//写入值 string type = fieldType[i];string value = dataList[i];if (value is null){throw new Exception("表格实际数据存在未配置项");}sb.Append($"{Convert(type, value)}");//写入逗号//不是最后一个就是逗号if (i != fieldType.Count - 1){sb.Append(",");}}sb.Append("}");return sb.ToString();}//根据类型获取键所对应的值//如果不是数组 返回类型为 "Key":"Value" 中的value//如果是数组 返回类似于 ["1","2"] 的结构private static string Convert(string type, string value){switch (type){case "int":case "float":case "double":case "bool":case "string":case "long"://注此处返回的时候加了引号,避免格式错误return $"\"{value}\"";case "int[]":case "float[]":case "double[]":case "bool[]":case "string[]":case "long[]":return ArrayParse(value);default:throw new Exception("{type}类型暂未支持");}}/// <summary>/// 将数组转换成对应的字符串/// </summary>/// <param name="value"></param>/// <returns></returns>private static string ArrayParse(string value){//切分字符串得到数组var res = value.Split("|");StringBuilder sb = new StringBuilder();sb.Append("[");for (int i = 0; i < res.Length; i++){sb.Append('"');sb.Append(res[i]);sb.Append('"');//不是数组最后一个加,if (i != res.Length - 1){sb.Append(",");}}sb.Append("]");return sb.ToString();}}

直接获取该项目

ExcelToJson: ExcelToJson

总结

该工具可以帮助你轻松地将 .xlsx 文件中的数据转换为 JSON 文件,并自动生成对应的 C# 脚本,简化了数据处理和代码生成的流程。在使用时,务必遵循 Excel 文件格式要求,确保生成的脚本和 JSON 文件符合预期。

相关文章:

Excel转Json编辑器工具

功能说明&#xff1a;根据 .xlsx 文件生成对应的 JSON 文件&#xff0c;并自动创建脚本 注意事项 Excel 读取依赖 本功能依赖 EPPlus 库&#xff0c;只能读取 .xlsx 文件。请确保将该脚本放置在 Assets 目录下的 Editor 文件夹中。同时&#xff0c;在 Editor 下再创建一个 Exc…...

创建型设计模式、结构型设计模式与行为型设计模式 上下文任务通用方案 设计模式 大全

设计模式&#xff08;Design Pattern&#xff09;是一种面向对象编程的思想&#xff0c;分为创建型模式、结构型模式与行为型模式三大类&#xff0c;它们提供了在特定上下文中解决常见任务的通用方案&#xff0c;旨在让程序&#xff08;软件&#xff09;具有更好的特点&#xf…...

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…...

如何在 Ubuntu 22.04 上部署 Nginx 并优化以应对高流量网站教程

简介 本教程将教你如何优化 Nginx&#xff0c;使其能够高效地处理高流量网站。 Nginx 是一个强大且高性能的 Web 服务器&#xff0c;以其高效处理大量并发连接的能力而闻名&#xff0c;这使得它成为高流量网站的流行选择。 正确优化 Nginx 可以显著提高服务器的性能&#xff0…...

springcloud各个组件介绍

Spring Cloud 是一系列框架的集合&#xff0c;它基于 Spring Boot 提供了在分布式系统&#xff08;如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话和集群状态&#xff09;中快速构建一些常见模式的工具。下面是对 Sprin…...

HTML5实现好看的喜庆圣诞节网站源码

HTML5实现好看的喜庆圣诞节网站源码 前言一、设计来源1.1 主界面1.2 圣诞介绍界面1.3 圣诞象征界面1.4 圣诞活动界面1.5 圣诞热度界面1.6 圣诞纪念界面1.7 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的喜庆圣诞节网站源码&#xff0c;圣…...

《学习之道》

《学习之道》主要讲述了以下内容&#xff1a; 学习的原理 大脑的两种认知模式&#xff1a;介绍了专注模式和发散模式。专注模式适合集中精力解决具体问题、进行深度理解和记忆推理&#xff0c;但长时间使用易疲惫和陷入思维定式&#xff1b;发散模式则让大脑在更广泛的认知网…...

【Unity3D】ECS入门学习(十一)ComponentSystem、JobComponentSystem

ComponentSystem&#xff1a;仅支持主线程执行&#xff0c;不支持多线程&#xff0c;并且无法使用SystemBase介绍的扩展方法。 using Unity.Entities; using Unity.Transforms; using Unity.Mathematics;/// <summary> /// 仅主线程执行&#xff0c;不支持多线程 /// &l…...

力扣刷题:栈和队列OJ篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 1.用队列实现栈&#xff08;1&#xff09;题目…...

XGPT用户帮助手册

文章目录 2024 更新日志2024.12.272024.12.29 摘要 本文详细介绍了XGPT软件的功能及发展历程。XGPT是一款融合了当前最先进人工智能技术的多模态智能软件&#xff0c;专为国内用户优化设计。除了强大的智能问答功能外&#xff0c;XGPT还结合日常办公和科学研究的需求&#xff0…...

Oracle 数据库 dmp文件从高版本导入低版本的问题处理

当前有个需求是将oracle 19c上的数据备份恢复到oracle 11g上使用。我们通过exp命令远程进行备份&#xff0c;然后通过imp进行恢复时出现IMP-00010: not a valid export file, header failed verification报错。 这是数据库版本问题&#xff0c;在使用exp命令导出的时候使用的客…...

ShardingSphere-Proxy分表场景测试案例

快速入门文章参考&#xff1a;《ShardingSphereProxy:快速入门》 基于K8S部署文章参考&#xff1a;《基于K8s部署ShardingSphere-Proxy》 基于golang的测试用例参考&#xff1a;《ShardingSphere-Proxy 连接实战&#xff1a;从 Golang 原生 SQL 到 GORM 的应用》 背景 我们…...

学技术学英文:Tomcat的线程模型调优

导读&#xff1a; tomcat 线程调优关键需要理解下面这几个参数&#xff1a; 1. maxConnections 描述&#xff1a;指定服务器能够同时接受和处理的最大连接数。也就是说&#xff0c;服务器在任何时候都能处理的最大并发连接数。作用&#xff1a;限制服务器在任何给定时间点能…...

创建flutter项目遇到无法连接源的问题

Flutter 环境信息 Flutter版本: 3.19.4 (channel stable) Framework: revision 68bfaea224 (2024-03-20) Engine: revision a5c24f538d Dart: 3.3.2 DevTools: 2.31.1 项目基本信息 项目路径: D:\F\luichun 域名: www.luichun.com.cn 支持平台: android, web, windows 项目创…...

MAC系统QT图标踩坑记录

MAC系统QT图标踩坑记录 1. 准备图标1.1 方法一&#xff1a;下载准备好的图标1.2 方法二&#xff1a;自己生成图标1.2.1 准备一个png文件1.2.2 用sips生成不同大小的图片1.2.3 用iconutil生成图标文件 2. 配置图标2.1. 把图标改命成自己想要的名字&#xff0c;如icon.icns&#…...

TF-IDF(Term Frequency-Inverse Document Frequency)详解:原理和python实现(中英双语)

中文版 TF-IDF算法详解&#xff1a;理解与应用 TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;是信息检索与文本挖掘中常用的算法&#xff0c;广泛应用于搜索引擎、推荐系统以及各种文本分析领域。TF-IDF的核心思想是通过计算一个词在文档中的重要…...

【竞技宝】CS2:HLTV2024职业选手排名TOP15-xantares

北京时间2024年12月30日&#xff0c;HLTV年度选手排名正在持续公布中&#xff0c;今日凌晨正式公布了今年的TOP15选手为EternalFire战队的xantares选手。 选手简介 xantares是一名来自于土耳其的CS职业选手&#xff0c;出生于1995年&#xff0c;今年已经29岁。早在2012年&…...

Spring-kafka快速Demo示例

使用Spring-Kafka快速发送/接受Kafka消息示例代码&#xff0c;项目结构是最基础的SpringBoot结构&#xff0c;提前安装好Kafka&#xff0c;确保Kafka已经正确启动 pom.xml&#xff0c;根据个人情况更换springboot、java版本等 <?xml version"1.0" encoding&qu…...

客户案例:基于慧集通集成平台,打通屠宰管理系统与用友U8C 系统的全攻略

一、引言 本原型客户成立于2014年&#xff0c;是一家集饲草种植、肉牛养殖、精深加工、冷链物流、餐饮服务于一体的大型农牧综合体。公司下设三个子公司分别涵盖农业、畜牧业、肉制品加工业与餐饮物流服务业。公司严格按照一二三产业融合发展要求&#xff0c;以肉牛产业化为支…...

模型 九屏幕分析法

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。九屏幕法&#xff1a;全方位分析问题的系统工具。 1 九屏幕分析法的应用 1.1 新产品研发的市场分析 一家科技公司计划开发一款新型智能手机&#xff0c;为了全面评估市场潜力和风险&#xff0c;他们…...

Qanything 2.0源码解析系列6 PDF解析逻辑

Qanything 2.0源码解析系列6: PDF解析逻辑 type: Post status: Published date: 2024/12/04 summary: 深入剖析Qanything是如何拆解PDF的,核心是pdf转markdown category: 技术分享 原文:www.feifeixu.top 😀 前言: 在前面的文章中探究了图片是怎么进行解析的,这篇文章对…...

MAC系统QT Creator的快捷键

安装好QT Creator后使用了一段时间&#xff0c;真是越用越难受&#xff0c;只想说&#x1f5d1;️。。。 找一圈qt creator的快捷键 0. 快捷键界面 这里的搜索真的是…无语&#xff0c;不考虑是人查找吗&#xff1f;&#xff1f; 1. 代码前后浏览 2. 移动代码 3. 半自动导入…...

【深度学习】多目标融合算法—样本Loss提权

目录 一、引言 二、样本Loss提权 2.1 技术原理 2.2 技术优缺点 三、总结 一、引言 在朴素的深度学习ctr预估模型中&#xff08;如DNN&#xff09;&#xff0c;通常以一个行为为预估目标&#xff0c;比如通过ctr预估点击率。但实际推荐系统业务场景中&#xff0c;更多是多…...

C 实现植物大战僵尸(四)

C 实现植物大战僵尸&#xff08;四&#xff09; C 实现植物大战僵尸&#xff0c;完结撒花&#xff08;还有个音频稍卡顿的性能问题&#xff0c;待有空优化解决&#xff09;。目前基本的功能模块已经搭建好了&#xff0c;感兴趣的友友可自行尝试编写后续游戏内容 因为 C 站不能…...

Tailwind CSS:现代 CSS 框架的优雅之选

Tailwind CSS&#xff1a;现代 CSS 框架的优雅之选 在现代前端开发中&#xff0c;CSS 的灵活性和复杂性让开发者在设计与实现之间寻找平衡。而 Tailwind CSS 的出现&#xff0c;重新定义了 CSS 框架的使用方式。它是一种原子化的 CSS 工具库&#xff0c;提供了丰富的类名以快速…...

MyBatis 使用的设计模式详解

MyBatis 是一个优秀的持久层框架&#xff0c;它简化了 Java 应用程序与数据库之间的交互。为了实现高效、灵活且易于维护的代码&#xff0c;MyBatis 内部使用了多种设计模式。本文将详细介绍 MyBatis 中应用到的设计模式及其作用。 工厂模式&#xff08;Factory Pattern&#x…...

LabVIEW 中 NI Vision 模块的IMAQ Create VI

IMAQ Create VI 是 LabVIEW 中 NI Vision 模块&#xff08;NI Vision Development Module&#xff09;的一个常用 VI&#xff0c;用于创建一个图像变量。该图像变量可以存储和操作图像数据&#xff0c;是图像处理任务的基础。 ​ 通过以上操作&#xff0c;IMAQ Create VI 是构建…...

2024 年度总结

时光荏苒&#xff0c;2024 年即将画上句号&#xff0c;回顾这一年的写博历程&#xff0c;有付出、有收获、有成长&#xff0c;也有诸多值得回味与反思的瞬间。 一、内容创作 主题涉猎&#xff1a;这一年&#xff0c;我致力于探索多样化的主题&#xff0c;以满足不同读者群体的…...

STM32 高级 物联网通讯之LoRa通讯

目录 LoRa通讯基础知识 常见的3种通讯协议 远距离高速率的传输协议 近距离高速率传输技术 近距离低功耗传输技术 低功耗广域网 采用授权频段技术 非授权频段 LoRa简介 LoRa的特点 远距离 低功耗 安全 标准化 地理定位 移动性 高性能 低成本 LoRa应用 LoRa组…...

【笔记】在虚拟机中通过apache2给一个主机上配置多个web服务器

&#xff08;配置出来的web服务器又叫虚拟主机……&#xff09; 下载apache2 sudo apt update sudo apt install apache2 &#xff08;一&#xff09;ip相同 web端口不同的web服务器 进入 /var/www/html 创建站点一和站点二的目录文件&#xff08;目录文件名自定义哈&#x…...