Unity Excel导表工具转Lua文件

news2025/2/22 7:42:17

思路介绍

借助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.xls
        sb.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 = "{}";
                else
                    result = "\"\"";
                break;
        }
        return result;
    }
}

小提示

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

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

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

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

相关文章

Helix——Figure 02发布通用人形机器人控制的VLA:一组神经网络权重下的快与慢双系统,让两个机器人协作干活

前言 过去一周&#xff0c;我花了很大的心思、力气&#xff0c;把deepseek的GRPO、MLA算法的代码解析通透&#xff0c;比如GRPO与PPO的详细对比&#xff0c;再比如MLA中&#xff0c;图片 公式 代码的一一对应 2.20日晚&#xff0c;无意中刷到figure 02发布Helix的一个演示视频…

进程的介绍--进程状态/切换

1.冯 • 诺依曼体系结构 1.1 体系结构 冯•诺依曼结构也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构。数学家冯•诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#x…

goby(蓝队红队版)扫描工具扫描使用时候报错解决方法

1.Goby 是一款开源的网络安全扫描工具&#xff0c;主要用于漏洞扫描、资产发现和信息收集。它旨在帮助安全研究人员、渗透测试人员和红队成员自动化和简化网络漏洞扫描过程。Goby 提供了多种功能&#xff0c;能够在大量的目标中高效地识别出潜在的安全漏洞。 2.今天在官网下载…

Word文档中插入的图片不能完整显示

在在Word文档中插入图片&#xff0c;只显示图片最下面的一小部分。 将“固定值”更改为“单倍行距”

模电知识点总结(6)

1.选取频率高于1000Hz的信号时&#xff0c;可选用高通滤波器&#xff1b;抑制50Hz的交流干扰时&#xff0c;可选用带阻滤波器如果希望抑制500Hz以下的信号&#xff0c;可选用高通滤波器。 2.有用信号频率高于1000Hz&#xff0c;可选用高通滤波器&#xff1b;希望抑制50Hz的交流…

Linux操作系统4-进程间通信4(共享内存原理,创建,查看,命令)

上篇文章&#xff1a;Linux操作系统4-进程间通信3&#xff08;基于管道的进程池设计&#xff09;-CSDN博客 本篇Gitee代码&#xff1a;myLerningCode/l24 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重点&#xff1a;使用共享内存来实现两个进程…

使用Ubuntu搭建Java部署环境

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:小舟从此逝&#xff0c;江海寄余生&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小…

MATLAB学习之旅:从入门到基础实践

在当今科技飞速发展的时代,MATLAB作为一款强大的数学软件,犹如一把神奇的钥匙,能够打开众多领域的大门。无论是工程计算、数据分析,还是算法开发、可视化呈现,MATLAB都展现出了无与伦比的魅力。今天,就让我们踏上这段奇妙的MATLAB学习之旅,从最基础的部分开始,逐步探索…

蓝桥杯核心内容

核心内容 数学 质数与筛质数&#xff0c;分解质因数 分解质因数 所有的数都可以写成有限个数相乘质数&#xff1a;可以写成1✖本身&#xff08;如131✖13&#xff09;合数&#xff1a;ab1✖...✖bn-》把乘数里面是合数的再分&#xff08;如b3是合数-》b3c1✖c2&#xff09;进…

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

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

金融时间序列【量化理论】

业界常用的技术分析指标都与价格本身有关&#xff0c;而时间序列分析由于对数据平稳性的要求常常是基于收益率这样更加偏稳定的数据&#xff08;收益率由于会涨停和跌停每天最多10%&#xff09; 平稳性&#xff1a; 强平稳性&#xff1a;随时间变化&#xff0c;各个统计特征都…

快速入门——第三方组件element-ui

学习自哔哩哔哩上的“刘老师教编程”&#xff0c;具体学习的网站为&#xff1a;10.第三方组件element-ui_哔哩哔哩_bilibili&#xff0c;以下是看课后做的笔记&#xff0c;仅供参考。 第一节 组件间的传值 组件可以有内部Data提供数据&#xff0c;也可由父组件通过prop方式传…

Qt5 C++ TcpSocket 如何判断是服务主动断开tcp socket连接?

文章目录 实现思路示例代码代码解释主要功能和用法注意事项 在 Qt 5.9.9 的 C 开发中&#xff0c;使用 QTcpSocket 时&#xff0c;要判断是服务端主动断开 TCP Socket 连接&#xff0c;可以通过处理 QTcpSocket 的 disconnected 信号&#xff0c;结合 QTcpSocket 的状态以及…

DeepSeek动画视频全攻略:从架构到本地部署

DeepSeek 本身并不直接生成动画视频,而是通过与一系列先进的 AI 工具和传统软件协作,完成动画视频的制作任务。这一独特的架构模式,使得 DeepSeek 在动画视频创作领域发挥着不可或缺的辅助作用。其核心流程主要包括脚本生成、画面设计、视频合成与后期处理这几个关键环节。 …

电力通信物联网应用,国密网关守护电力数据安全

电力国密网关是用于保护电力调度数据网路由器和电力系统的局域网之间通信安全的电力专用网关机&#xff0c;主要为上下级控制系统之间的广域网通信提供认证与加密服务&#xff0c;实现数据传输的机密性、完整性。 国密算法网关功能特点 身份认证&#xff1a;对接入的设备和用户…

Datawhale Ollama教程笔记5

Dify 接入 Ollama 部署的本地模型 Dify 支持接入 Ollama 部署的大型语言模型推理和 embedding 能力。 快速接入 下载 Ollama 访问 Ollama 安装与配置&#xff0c;查看 Ollama 本地部署教程。 运行 Ollama 并与 Llama 聊天 ollama run llama3.1Copy to clipboardErrorCopied …

保姆级! 本地部署DeepSeek-R1大模型 安装Ollama Api 后,Postman本地调用 deepseek

要在Postman中访问Ollama API并调用DeepSeek模型&#xff0c;你需要遵循以下步骤。首先&#xff0c;确保你有一个有效的Ollama服务器实例运行中&#xff0c;并且DeepSeek模型已经被加载。 可以参考我的这篇博客 保姆级&#xff01;使用Ollama本地部署DeepSeek-R1大模型 并java…

ASP.NET Core 下载文件

本文使用 ASP .NET Core&#xff0c;适用于 .NET Core 3.1、.NET 5、.NET 6和.NET 8。 另请参阅&#xff1a; 如何在将文件发送到浏览器后自动删除该文件。 如何将文件从浏览器上传到服务器。 如何在 ASP.NET Core 应用程序中从 URL/URI 下载文件。 如果使用.NET Framework&am…

【信息系统项目管理师-案例真题】2022下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一(24分)【问题1】(6分)【问题2】(10分)【问题3】(8分)试题二(26分)【问题1】(8分)【问题2】(8分)【问题3】(4分)【问题4】(6分)试题三(25分)【问题1】(12分)【问题2】(7分)【问题…

原来DeepSeek还能运用在系统集成-领星对接

在当今数字化转型的浪潮中&#xff0c;企业的信息化建设已成为提升运营效率、优化管理流程的关键。领星ERP与金蝶云星空作为两款在电商和财务管理领域广受欢迎的软件&#xff0c;其数据对接对于跨境电商企业来说尤为重要。本文将结合实际应用场景&#xff0c;深度解析如何通过轻…