Unity Editor扩展 实现一个Excel读表窗口

news2024/10/7 16:27:36

设计

在这里插入图片描述

Unity Editor窗口类

public class ExcelEditorWindow : EditorWindow
{
    [MenuItem( "Frameworks/读表配置界面", false, 10 )]
    private static void Open()
    {
        Rect wr = new Rect( 0, 0, 500, 500 );
        ExcelEditorWindow window = ( ExcelEditorWindow ) EditorWindow.GetWindowWithRect( typeof( ExcelEditorWindow ), wr, true, "Export Excel Window" );
        window.Show();
    }

}

[MenuItem( “Frameworks/读表配置界面”, false, 10 )]

第一个参数是路径
在这里插入图片描述
第二个参数默认false

第三个参数是优先级 越低越靠上

自定义窗口绘制内容

private void OnGUI()
{




}

好 跟着我们的草图 我们一步步的完成就可以了

标题

在这里插入图片描述

选择导入的excel根目录

		GUILayout.Label( "选择一个批量导出的Excel目录: " );
        GUILayout.BeginHorizontal();
        excelRootFolder = GUILayout.TextField( excelRootFolder, 128, GUILayout.MaxWidth( 400f ) );
        if ( GUILayout.Button( "选择目录" ) )
        {
            string newFolder = EditorUtility.OpenFolderPanel( "选择Excel目录", excelRootFolder, string.Empty );
            if ( !string.IsNullOrEmpty( newFolder ) && !string.IsNullOrWhiteSpace( newFolder ) )
            {
                excelRootFolder = newFolder;
                if ( Directory.Exists( excelRootFolder ) )
                {
                    data.excelRootFolder = excelRootFolder;
                }
            }
        }
        GUILayout.EndHorizontal();

然后我们下一个功能和这个功能之间 留一点空隙

GUILayout.Space( 4 );

然后就是 批量遍历按钮 和 导出按钮

 		GUILayout.BeginHorizontal();
        if ( GUILayout.Button( "开始遍历" ) )
        {
            excels.Clear();
            if ( Directory.Exists( excelRootFolder ) )
            {
                ConsoleUtils.Clear();
                string[] xlsxs = Directory.GetFiles( excelRootFolder, "*.xlsx", SearchOption.TopDirectoryOnly );
                excels.AddRange( xlsxs );
            }
            else
            {
                EditorUtility.DisplayDialog( "路径错误", $"不存在 {excelRootFolder}", "确认" );
                Debug.LogError( $"Excel路径错误: {excelRootFolder}" );
            }
        }
        else if ( GUILayout.Button( "批量导出" ) )
        {
            BatchExport( excelRootFolder );
        }
        else if ( GUILayout.Button( "打开目录 - Excel源" ) )
        {
            EditorUtility.RevealInFinder( excelRootFolder );
        }
        else if ( GUILayout.Button( "打开目录 - 数据源" ) )
        {
            var dataFolder = Path.Combine( Application.dataPath, "BundleRes/ExcelData/" );
            EditorUtility.RevealInFinder( dataFolder );
        }
        else if ( GUILayout.Button( "打开目录 - 数据类" ) )
        {
            var csFolder = Path.Combine( Application.dataPath, "Scripts/ExcelCSharp/" );
            EditorUtility.RevealInFinder( csFolder );
        }
        GUILayout.EndHorizontal();

最后就是我们筛选出的excel展示区域 需要一个滑动展示页面

滑动页面核心

excelScrollerPos = EditorGUILayout.BeginScrollView( excelScrollerPos );
//其它需要渲染的目标内容写着中间
EditorGUILayout.EndScrollView();

  if ( excels.Count > 0 )
        {
            GUILayout.Space( 4 );
            excelScrollerPos = EditorGUILayout.BeginScrollView( excelScrollerPos );
            EditorGUILayout.BeginVertical();
            for ( int i = 0; i < excels.Count; i++ )
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.TextArea( excels[ i ], GUILayout.MaxWidth( 400 ) );
                if ( GUILayout.Button( "Export" ) )
                {
                    Export( excels[ i ] );
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }

最终效果

在这里插入图片描述

源码

//==========================
// - FileName:      Assets/Frameworks/Editor/Excel/ExcelEditorWindow.cs
// - Created:       ChenJC	
// - CreateTime:    2023-06-19 10:03:20
// - UnityVersion:  2019.4.35f1
// - Version:       1.0
// - Description:   
//==========================
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class ExcelEditorWindow : EditorWindow
{
    [MenuItem( "Frameworks/读表配置界面", false, 10 )]
    private static void Open()
    {
        Rect wr = new Rect( 0, 0, 500, 500 );
        ExcelEditorWindow window = ( ExcelEditorWindow ) EditorWindow.GetWindowWithRect( typeof( ExcelEditorWindow ), wr, true, "Export Excel Window" );
        window.Show();
    }

    class ExcelEditorConfig 
    {
        public string excelRootFolder = "Excels";
        public string lastUpdateTime = string.Empty;
    }
    ExcelEditorConfig data;
    private string GetConfigFilePath()
    {
        return Path.Combine( Application.persistentDataPath, nameof( ExcelEditorConfig ) );
    }
    private void OnEnable()
    {

        if ( !File.Exists( GetConfigFilePath() ) )
        {
            data = new ExcelEditorConfig();
            try
            {
                var clips = Application.dataPath.Split( '/' );
                var projname = clips[ clips.Length - 2 ];
                var plant = projname.Split( '-' )[ 0 ] + "-plan";
                var plantPath = Application.dataPath.Replace( $"{projname}/Assets", $"{plant}/Excel/" );
                data.excelRootFolder = plantPath;
            }
            catch ( Exception e ) { }
            data.excelRootFolder = Path.Combine( Application.dataPath, data.excelRootFolder );
        }
        else
        {
            try
            {
                data = JsonConvert.DeserializeObject<ExcelEditorConfig>( File.ReadAllText( GetConfigFilePath() ) );
            }
            catch ( Exception e )
            {
                Debug.LogError( e );
                data = new ExcelEditorConfig();
            }
        }

        data.lastUpdateTime = DateTime.Now.ToString();
        excelRootFolder = data.excelRootFolder;
    }
    private void OnDisable()
    {
        try
        {
            string jsonstr = JsonConvert.SerializeObject( data );
            File.WriteAllText( GetConfigFilePath(), jsonstr );
        }
        catch ( Exception e )
        {
            Debug.LogError( e );
        }
    }

    string excelRootFolder = string.Empty;
    List<string> excels = new List<string>();
    Vector2 excelScrollerPos = Vector2.zero;
    //绘制窗口时调用
    private void OnGUI()
    {
        GUILayout.Label( "选择一个批量导出的Excel目录: " );
        GUILayout.BeginHorizontal();
        excelRootFolder = GUILayout.TextField( excelRootFolder, 128, GUILayout.MaxWidth( 400f ) );
        if ( GUILayout.Button( "选择目录" ) )
        {
            string newFolder = EditorUtility.OpenFolderPanel( "选择Excel目录", excelRootFolder, string.Empty );
            if ( !string.IsNullOrEmpty( newFolder ) && !string.IsNullOrWhiteSpace( newFolder ) )
            {
                excelRootFolder = newFolder;
                if ( Directory.Exists( excelRootFolder ) )
                {
                    data.excelRootFolder = excelRootFolder;
                }
            }
        }
        GUILayout.EndHorizontal();
        GUILayout.Space( 4 );
        GUILayout.BeginHorizontal();
        if ( GUILayout.Button( "开始遍历" ) )
        {
            excels.Clear();
            if ( Directory.Exists( excelRootFolder ) )
            {
                ConsoleUtils.Clear();
                string[] xlsxs = Directory.GetFiles( excelRootFolder, "*.xlsx", SearchOption.TopDirectoryOnly );
                excels.AddRange( xlsxs );
            }
            else
            {
                EditorUtility.DisplayDialog( "路径错误", $"不存在 {excelRootFolder}", "确认" );
                Debug.LogError( $"Excel路径错误: {excelRootFolder}" );
            }
        }
        else if ( GUILayout.Button( "批量导出" ) )
        {
            BatchExport( excelRootFolder );
        }
        else if ( GUILayout.Button( "打开目录 - Excel源" ) )
        {
            EditorUtility.RevealInFinder( excelRootFolder );
        }
        else if ( GUILayout.Button( "打开目录 - 数据源" ) )
        {
            var dataFolder = Path.Combine( Application.dataPath, "BundleRes/ExcelData/" );
            EditorUtility.RevealInFinder( dataFolder );
        }
        else if ( GUILayout.Button( "打开目录 - 数据类" ) )
        {
            var csFolder = Path.Combine( Application.dataPath, "Scripts/ExcelCSharp/" );
            EditorUtility.RevealInFinder( csFolder );
        }
        GUILayout.EndHorizontal();
        if ( excels.Count > 0 )
        {
            GUILayout.Space( 4 );
            excelScrollerPos = EditorGUILayout.BeginScrollView( excelScrollerPos );
            EditorGUILayout.BeginVertical();
            for ( int i = 0; i < excels.Count; i++ )
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.TextArea( excels[ i ], GUILayout.MaxWidth( 400 ) );
                if ( GUILayout.Button( "Export" ) )
                {
                    Export( excels[ i ] );
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }

    }

    private void Export( string xlsx )
    {
        ExcelExport.ConvertFromFile( xlsx );
    }

    private void BatchExport( string folder )
    {
        ExcelExport.ConvertFromFolder( folder );
    }

    private void OnInspectorUpdate()
    {
        this.Repaint();
    }
}

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

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

相关文章

津津乐道设计模式 - 组合模式详解(以餐厅菜单系统举例让你快速掌握)

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

基于Python所写的玛丽冒险设计

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87953199 《玛丽冒险》程序使用说明 在PyCharm中运行《玛丽冒险》即可进入如图1所示的游戏主界面。 图1 游戏主界面 具体的操作步骤如下&#xff1a; &#xff08;1&#xff09;游戏…

数据库监控与调优【十四】—— COUNT语句优化

COUNT语句优化 有关COUNT的几个实验与结论 准备工作 create table user_test_count (id int primary key not null auto_increment,name varchar(45),age int,email varchar(60),birthday date ) engine innodb;insert into user_test_count (id, name, a…

算法设计与分析之回溯法

文章目录 1. 回溯法简介1.1 DFS的基本思想1.2 回溯法的基本思想1.3 回溯法和DFS的区别1.4 剪枝 2. 01背包问题&#xff1a;子集树2.1 问题介绍2.2 解决思路2.3 算法实现2.4 如何优化 3. 旅行商问题TSP&#xff1a;排序树3.1 问题介绍3.2 解决思路3.3 算法框架3.4 算法实现 4. 总…

项目一点点记录

kafka发布通知 kafka是消息队列&#xff0c;kafka采用发布订阅模式进行消息的生产与消费。在项目中&#xff0c;我们采用spring来整合kafka&#xff0c; 通过定义事件event来封装 点赞、关注、评论三类事件&#xff0c;event实体中有 事件主题topic&#xff0c;当前用户id&…

怎么给PDF添加图片水印?其实很简单,看这篇就会了!

许多人都意识到版权问题的重要性&#xff0c;尽管在日常生活中我们可能很少遇到&#xff0c;但在办公和学习中却经常涉及到此类问题。例如&#xff0c;我们辛辛苦苦制作的PDF文件&#xff0c;如何确保不被他人盗用呢?这就涉及到如何为PDF添加图片水印的问题&#xff0c;相当于…

无向图G的广度优先搜索和深度优先搜索以及完整程序

图的遍历算法有两种&#xff1a;广度优先搜索和深度优先搜索 一.广度优先搜索类似于层次遍历&#xff0c;需要借助辅助队列 空间复杂度为O(|V|);空间复杂度由辅助队列大小决定 时间复杂度为O(|V||E|) 为避免同一顶点被多次访问&#xff0c;设计visited[]来标记顶点 二.深度…

MyBatis 从初识到掌握

目录 今日良言&#xff1a;与其抱怨于黑暗&#xff0c;不如提灯向前行 一、初识MyBatis 1.MyBatis定义 2.为什么要学习MyBatis 3.MyBatis的创建 二、MyBatis的相关操作 1.增删改查操作 2.动态SQL使用 今日良言&#xff1a;与其抱怨于黑暗&#xff0c;不如提灯向前行 一…

UE4/5 通过Control rig的FullBody【蜘蛛模型,不用basic ik】

目录 根设置 FullBody IK 额外骨设置 ​编辑 晃动效果 根设置 第一步你需要准备一个蜘蛛模型&#xff0c;不论是官方示例或者是epic上购买的模型 然后我用的是epic上面购买的一个眼球蜘蛛&#xff1a; 第一步&#xff0c;我们从根创建一个空项【这个记得脱离父子级到root之…

SQLServer 2016 R2数据库新建、附加、分离、备份、还原、复制等基本操作

一、打开Microsoft SQL Server Management Studio 在桌面上找到图标&#xff0c;双击运行 打开Microsoft SQL Server Management Studio 17 输入服务器名称&#xff0c;选择SQL Server 身份验证&#xff0c;sa和sa密码&#xff0c;可以勾选记住密码&#xff0c;以便以后的登录…

分享基于安卓项目的单元测试总结

前言&#xff1a; 负责公司的单元测试体系的搭建&#xff0c;大约有一两个月的时间了&#xff0c;从最初的框架的调研&#xff0c;到中期全员的培训&#xff0c;以及后期对几十个项目单元测试的引入和推进&#xff0c;也算是对安卓的单元测试有了一些初步的收获以及一些新的认…

【雕爷学编程】Arduino动手做(131)---跑马灯矩阵键盘模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

线性代数基础--矩阵

矩阵 矩阵是由排列在矩形阵列中的数字或其他数学对象组成的表格结构。它由行和列组成&#xff0c;并且在数学和应用领域中广泛使用。 基本概念 元素&#xff1a;矩阵中的每个数字称为元素。元素可以是实数、复数或其他数学对象。 维度&#xff1a;矩阵的维度表示矩阵的行数和…

vtk创建点

使用vtk库创建三维空间中的点 引言开发环境示例一项目结构实现代码 运行效果示例二项目结构实现代码 运行效果总结 引言 本文仅适合初学者。 本文不提供vtk动态库的生成&#xff0c;以及在QtCreator中的引进vtk时的配置。 本文先由示例一开始&#xff0c;然后再在示例一的基础…

aws使用外部 ID对其他账号授权

点击前往授权,进入控制台 https://signin.aws.amazon.com/signin?redirect_urihttps%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_eu-north-1_f2d9c316b93c0026&client_idarn%3Aaws%3Asignin%3A%…

Glassdoor美国公司员工及面试者评价数据

一、数据简介 除了股东、债权人、政府等外部利益相关者外&#xff0c;员工的利益更应该得到公司的恰当保护&#xff0c;因为员工才是公司创造价值的真正主体。提高企业在产品市场的竞争力&#xff0c;首先就是要提高员工对企业的满意度&#xff0c;只有员工的满意度更高、幸福感…

7个技巧,助你同时轻松管理和跟踪多个项目

仅仅想到要兼顾这么多重要的职责&#xff0c;就会让许多专业的项目经理感到焦虑。当涉及多个项目的多种项目管理工具的处理&#xff0c;即使对于了解项目管理的项目经理来说&#xff0c;也是一项艰巨的任务&#xff0c;而对于在这个领域没有经过适当培训的人来说&#xff0c;这…

强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

计算机网络—数据链路层

文章目录 数据链路层服务差错编码多路访问协议信道划分随机访问MAC协议 数据链路层服务 该层中的帧数据结构&#xff1a; 帧头部会因为不同的局域网协议而不同&#xff0c;因此会在另一篇博文中继续介绍不同的帧数据报&#xff0c;不在本博文介绍。&#xff08;不过除了PPP协…

Docker学习笔记11

Docker容器镜像&#xff1a; 1&#xff09;docker client 向docker daemon发起创建容器的请求&#xff1b; 2&#xff09;docker daemon查找本地有客户端需要的镜像&#xff1b; 3&#xff09;如无&#xff0c;docker daemon则到容器的镜像仓库中下载客户端需要的镜像&#…