Unity Excel导表工具转Lua文件

思路介绍

借助EPPlus读取Excel文件中的配置数据,根据指定的不同类型的数据配置规则来解析成对应的代码文本,将解析出的字符串内容写入到XXX.lua.txt文件中即可

EPPlus常用API

//命名空间
using OfficeOpenXml;//Excel文件路径
var fileExcel = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//加载Excel数据资源
var excelPackage = new ExcelPackage(fileExcel);//工作表列表
var sheetList = excelPackage.Workbook.Worksheets;foreach (var sheet in sheetList)
{var sheetName = sheet.Name;//工作表名称var rowCount = sheet.Dimension.Rows;//总行数var columnCount = sheet.Dimension.Columns;//总列数for (var i = 4; i <= rowCount; i++){for (var j = 1; j <= columnCount; j++){//获取第几行第几列的数据var value = sheet.GetValue(i, j);}}
}

制定Excel数据类型配置规则

编写导表工具之前,需要和策划、后端沟通制定数据配置规则

例如:

类型

标记

数值型

number

布尔型

bool

字符串

string

列表

list<type>

type支持:number,bool,string

示例:2,3,4

字典

dic<key|value>

type支持: number,bool,string

示例:语文|88;数学|91;英语|67

 

导入EPPlus.dll


在Unity的Assets下创建Plugins文件夹,并将EPPlus.dll文件放到该文件夹中

核心代码

using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using OfficeOpenXml;
using UnityEditor;public class ExcelToLua
{//Excel导表文件路径public static readonly string ExcelFolderPath = "D:\\Study\\Excel";//lua文件路径private static readonly string LuaFolderPath = Path.Combine(Application.dataPath, "LuaScripts");//Table文件后缀拼接private const string LuaNameEnd = "Table.lua.txt";[MenuItem("新项目工具/导表工具/导入Excel表数据", false, 1)]static void ImportSingleExcelFile(){if (Directory.Exists(ExcelFolderPath)){var path = EditorUtility.OpenFilePanel("打开文件", ExcelFolderPath, "xlsx");if (path.Length != 0){CreateLuaFile(path);AssetDatabase.Refresh();}}}/// <summary>/// 获取Excel数据并创建Lua文件/// </summary>/// <param name="filePath"></param>public static void CreateLuaFile(string filePath){//Excel文件路径var fileExcel = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//加载Excel数据资源var excelPackage = new ExcelPackage(fileExcel);//工作表列表var sheetList = excelPackage.Workbook.Worksheets;StringBuilder sb = new StringBuilder();//变量字典var variableDic = new Dictionary<int, string>();//变量类型字典var typeDic = new Dictionary<int, string>();var fileName = Path.GetFileName(filePath); //文件名称带后缀  例:A-活动_activity.xlssb.Append($"--{fileName}\nreturn {{\n");foreach (var sheet in sheetList){variableDic.Clear();typeDic.Clear();var sheetName = sheet.Name;//工作表名称var rowCount = sheet.Dimension.Rows;//总行数var columnCount = sheet.Dimension.Columns;//总列数//变量类型列表InitSheetDic(sheet, typeDic, 1);//变量列表InitSheetDic(sheet, variableDic, 2);sb.Append($"[\"{sheetName}\"] = {{\n");for (var i = 4; i <= rowCount; i++){for (var j = 1; j <= columnCount; j++){if (!typeDic.ContainsKey(j) || !variableDic.ContainsKey(j)){break;}var type = typeDic[j];var variable = variableDic[j];if (type == null || variable == null){continue;}//获取第几行第几列的数据var value = sheet.GetValue(i, j);var valueStr = GetTypeValue(type, value);if (j == 1){sb.Append($"    [{valueStr}] = {{");}sb.Append($"{variable} = {valueStr};");}sb.Append("};\n");}sb.Append("},\n");}sb.Append("}");var txtName = Path.GetFileNameWithoutExtension(filePath);var nameIndex = txtName.LastIndexOf('_');if (nameIndex != -1){txtName = txtName.Substring(nameIndex + 1);txtName = txtName.Substring(0, 1).ToUpper() + txtName.Substring(1);}//创建XXXTable文件File.WriteAllText($"{LuaFolderPath}\\{txtName}{LuaNameEnd}", sb.ToString());Debug.Log($"<color=#00EE00>{fileName}</color>表导入成功");sb.Clear();}//将Excel列表某一行的数据初始化到指定字典中private static void InitSheetDic(ExcelWorksheet sheet, Dictionary<int, string> dic, int rowNum){var columnSum = sheet.Dimension.End.Column;for (var i = 1; i <= columnSum; i++){var value = sheet.GetValue(rowNum, i);if (value == null)break;dic[i] = value.ToString();}}//根据不同类型的数据拼接对应格式的数据内容private static string GetTypeValue(string typeStr, object val){if (val == null)return GetDefaultValue(typeStr);var value = val.ToString();var result = value;switch (typeStr){case "number":case "bool":break;case "string":result = "\"" + value + "\"";break;case "list<number>":case "list<bool>":result = "{" + value + "}";break;case "list<string>":var strArray = value.Split(',');if (strArray.Length > 0){var sb = new StringBuilder();sb.Append("{");foreach (var item in strArray){sb.Append($"\"{item}\",");}sb.Append("}");result = sb.ToString();}break;default:if (typeStr.Contains("dic<")){if (typeStr.Contains("string")){var frontIndex = typeStr.IndexOf("string");var backIndex = typeStr.LastIndexOf("string");var isFront = frontIndex == 5;var isBack = backIndex == (typeStr.Length - 7);var strDic = value.Split(';');if (strDic.Length > 0){var sb = new StringBuilder();sb.Append("{");foreach (var item in strDic){var cell = item.Split("|");var frontStr = isFront ? "\"" + cell[0] + "\"" : cell[0];var backStr = isBack ? "\"" + cell[1] + "\"" : cell[1];sb.Append($"[{frontStr}] = {backStr},");}sb.Append("}");result = sb.ToString();}}else{var sb = new StringBuilder();var strDic = value.Split(';');if (strDic.Length > 0){sb.Append("{");foreach (var item in strDic){var cell = item.Split("|");sb.Append($"[{cell[0]}] = {cell[1]},");}sb.Append("}");result = sb.ToString();}}}else{result = "\"" + value + "\"";}break;}return result;}//如果某个数据未填,返回默认值private static string GetDefaultValue(string typeStr){string result;switch (typeStr){case "number":result = "0";break;case "bool":result = "false";break;case "string":result = "\"\"";break;default:if (typeStr.Contains("dic") || typeStr.Contains("list"))result = "{}";elseresult = "\"\"";break;}return result;}
}

小提示

1、在实际开发工作中,一般会用到导入单个或者所有的表两种逻辑。对于导出所有的表的逻辑,可以借助多线程来提高效率。

2、对于一些配置错误的情况也需要考虑到,增加一些报错逻辑判断并提示。

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

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

相关文章

【vue项目中如何实现一段文字跑马灯效果】

在Vue项目中实现一段文字跑马灯效果&#xff0c;可以通过多种方式实现&#xff0c;以下是几种常见的方法&#xff1a; 方法一&#xff1a;使用CSS动画和Vue数据绑定 这种方法通过CSS动画实现文字的滚动效果&#xff0c;并结合Vue的数据绑定动态更新文本内容。 步骤&#xff…

AcWing走迷宫-最短路问题-BFS求解

题目描述 给定一个 n * m 的二维整数数组&#xff0c;用来表示一个迷宫&#xff0c;数组中只包含 0 或 1&#xff0c;其中 0 表示可以走的路&#xff0c;1 表示不可通过的墙壁。 最初&#xff0c;有一个人位于左上角 (1, 1) 处&#xff0c;已知该人每次可以向上、下、左、右任…

go 错误处理 error

普通错误处理 // 包路径 package mainimport ("errors""fmt" )func sqrt(f1, f2 float64) (float64, error) {if f2 < 0 {return 0, errors.New("error: f2 < 0")}return f1 / f2, nil }func sqrt1(f1, f2 float64) {if re, err : sqrt(f…

MCU Bootloader具备什么条件才能跳转到APP程序

在MCU系统中&#xff0c;BootLoader&#xff08;Boot&#xff09;跳转到应用程序&#xff08;APP&#xff09;的条件通常由硬件和软件协同控制&#xff0c;核心逻辑是确保APP的完整性和合法性。以下是关键条件及流程&#xff1a; 1. 硬件启动模式选择 BOOT引脚电平&#xff1a…

LeeCode题库第二十八题

28.找出字符串第一个匹配项的下标 项目场景&#xff1a; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 …

深入解析BFS算法:C++实现无权图最短路径的高效解决方案

在无权图中&#xff0c;广度优先搜索&#xff08;BFS&#xff09;是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节&#xff0c;并给出C代码示例&#xff1a; 目录 一、核心原理 二、算法步骤 三、C实现关键点 1. 数据结构 2. 边界检查 3. 路径回溯…

Plant Simulation培训教程-双深堆垛机立库仿真模块

原创 知行 天理智能科技 2025年01月03日 17:02 浙江 又到年终盘点的时候了&#xff0c;在这里我把之前录制的Plant Simulation培训教程-双深堆垛机立库仿真模块分享出来&#xff0c;有需要的可以直接联系我。 双深堆垛机立库仿真模块基于单深模块开发&#xff0c;适用于双深堆…

文本和语音互转

目录 1. 下载依赖ddl 2. 引入Pom依赖 3. java代码 二. 语音转文本 1. 下载中文语音转文本的模型 2. 引入pom依赖 3. java代码 4. 运行效果 1. 下载依赖ddl 文字转语音文件需要使用jacob的dll文件放在jdk安装目录下的bin文件夹下 点击官网下载录或者通过csdn下载 2. …

DeepSeek破局启示录:一场算法优化对算力霸权的降维打击

导言 2024年,中国AI大模型赛道杀出一匹黑马——深度求索(DeepSeek)。从数学推理能力超越GPT-4,到API价格仅为Claude 3.5的1/53,再到开源生态的快速扩张,DeepSeek的崛起不仅打破了“算力霸权”的固有认知,更揭示了AI行业底层逻辑的深刻变革。这场技术革命背后,隐藏着技术…

Python大数据可视化:基于python大数据的电脑硬件推荐系统_flask+Hadoop+spider

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 价格区间界面 用户信息界面 品牌管理 笔记本管理 电脑主机…

阿里云虚机的远程桌面登录提示帐户被锁定了

提示由于安全原因&#xff0c;帐户被锁定。 阿里云虚机ECS的远程桌面登录提示帐户被锁定了&#xff0c;只能登录阿里云处理 阿里云-计算&#xff0c;为了无法计算的价值 需选择通过VNC连接 然后计算机管理&#xff0c;解除帐户锁定即可。

Grok 使用指南

文章来源&#xff1a;Grok 漫游指南 | xAI Docs 欢迎&#xff01;在本指南中&#xff0c;我们将引导您了解使用 xAI API 的基础知识。 #第 1 步&#xff1a;创建 xAI 帐户 您需要一个 xAI 帐户才能访问 xAI API。在此处注册帐户。 创建账户后&#xff0c;您需要为其加载积分…

Node.js高频面试题精选及参考答案

目录 什么是 Node.js?它的主要特点有哪些? Node.js 的事件驱动和非阻塞 I/O 模型是如何工作的? 为什么 Node.js 适合处理高并发场景? Node.js 与传统后端语言(如 Java、Python)相比,有哪些优势和劣势? 简述 Node.js 的运行原理,包括 V8 引擎的作用。 什么是 Nod…

Servlet概述(Ⅰ)

目录 一、Servlet概述 演示 创建JavaWeb项目&#xff08;2017版本为例&#xff09; 1. 打开 IntelliJ IDEA 2. 选择项目类型 3. 配置框架 二、Servlet初识(熟练) 1.servlet说明 2.Servlet 接口方法 3.创建Servlet 4.JavaWeb请求响应流程 ​编辑 ​编辑 5.servlet…

Windows 小记 18 —— 子窗口继承父窗口的样式

子窗口会继承父窗口或者所有者窗口的一些样式。 当我们使用 CreateWindowExW 创建窗口后&#xff0c;指定其 HwndParent 参数时&#xff0c;或者通过 SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent); 指定所有者窗口时&#xff0c;子窗口将从父…

19、《Springboot+MongoDB整合:玩转文档型数据库》

SpringbootMongoDB整合&#xff1a;玩转文档型数据库 摘要&#xff1a;本文全面讲解Spring Boot与MongoDB的整合实践&#xff0c;涵盖环境搭建、CRUD操作、聚合查询、事务管理、性能优化等核心内容。通过15个典型代码示例&#xff0c;演示如何高效操作文档数据库&#xff0c;深…

跳跃游戏II(力扣45)

这道题在跳跃游戏(力扣55)-CSDN博客 的基础上需要找到最小的跳跃次数。那么我们需要用一个变量来统计跳跃次数&#xff0c;而难点就在于何时让该变量的值增加。这一点我写在注释中&#xff0c;大家结合我的代码会更好理解。其他部分跟跳跃游戏(力扣55)-CSDN博客 几乎相同&#…

Linux基础开发工具的使用(apt、vim、gcc、g++、gdb、make、makefile)

Linux软件包管理器–apt Linux安装软件的方式 在Linux下安装软件的方法有以下三种&#xff1a; 下载到程序的源代码&#xff0c;自己编译出可执行程序获取deb安装包、然后使用dpkg命令安装。&#xff08;不解决依赖关系&#xff09;通过apt进行安装软件。 小知识点&#xf…

C/C++ | 每日一练 (2)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…

【前端框架】vue2和vue3的区别详细介绍

Vue 3 作为 Vue 2 的迭代版本&#xff0c;在性能、语法、架构设计等多个维度均有显著的变革与优化。以下详细剖析二者的区别&#xff1a; 响应式系统 Vue 2 实现原理&#xff1a;基于 Object.defineProperty() 方法实现响应式。当一个 Vue 实例创建时&#xff0c;Vue 会遍历…