Editor工具类:实现Excel表格转换成Lua配置文件

实际项目开发中,游戏中会存在很多的数值,而这些数值是由策划填表,程序员通过读表获取的。我们公司的表格是Excel表格(xlsx文件),实际程序中,我们会把Excel表转成Lua文件再读取,在这里,给大家分享一下转表功能的实现。

首先需要读取Excel,我们需要三个外部插件:Excel.dll、ICSharpCode.SharpZipLib.dll、System.Data.dll

Excel.dll和ICSharpCode.SharpZipLib.dll的下载地址:http://exceldatareader.codeplex.com/

system.data.dll的路径在unity安装路径下的Editor\Data\Mono\lib\mono\unity 这个路径下

把这三个类库引入Plugins以后,我们就可以开始写代码了


话不多说,上代码:

using UnityEngine;
using UnityEditor;
using System.IO;
using Excel;
using System.Data;
using System.Text.RegularExpressions;
using System.Text;
using System.Collections.Generic;

public class ExcleToLua : EditorWindow
{
    [MenuItem("Tools/配置表/将全部Excel转为配置表")]
    public static void ExcleAll()
    {
        string excleRoot = "Assets/table";
        DirectoryInfo root = new DirectoryInfo(excleRoot);
        FileInfo[] xlsxs = root.GetFiles("*.xlsx");//读取指定目录下所有Excel表数据,存储在数组中
        foreach (FileInfo xlsx in xlsxs)
        {
            string path = xlsx.FullName;
            path = path.Substring(path.IndexOf("Assets"));
            SelectedExcelToLua(path);
        }
        AssetDatabase.Refresh();
        Debug.Log("全部转表完成");
    }

    //Excel文件转换成Lua文件方法
    static void SelectedExcelToLua(string path)
    {
        string tableName = Path.GetFileNameWithoutExtension(path);
        bool encoderShouldEmitUTF8Identifier = true;
        bool throwOnInvalidBytes = false;
        bool append = false;
        UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes);
        StreamReader streamReader = new StreamReader("Assets/CustomEditor/Editor/Excel/ExcelToLuaConfig.txt", encoding);//转表配置文件
        string text = streamReader.ReadToEnd();
        streamReader.Close();
        string[] lines = text.Split('\n');
        string[] configs = null;
        bool isInConfig = false;
        for (int i = 0; i < lines.Length; i++)
        {
            string line = lines[i];
            if (line.IndexOf(tableName) != -1)
            {
                configs = line.Split('|');
                tableName = configs[1];
                isInConfig = true;
                break;
            }
        }
        if (!isInConfig)
        {
            Debug.Log("没有找到" + tableName + "配置,不生成");
            return;//没配置就不生成。
        }

        Debug.Log("_开始转表:" + tableName);
        FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read);
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);//调用Excel中IExcelDataReader接口读取数据
        DataSet result = excelReader.AsDataSet();
        string script =
                       @"local #TABLENAME#=
                       {
                       --[[
                       转表工具 beta 0.9
                       ]]
                       #CONTENT#
                       }
                       return #TABLENAME#";

        Dictionary<string, int> sheetConfigs = new Dictionary<string, int>();

        if (configs != null && configs.Length > 2)
        {
            for (int i = 2; i < configs.Length; i++)
            {
                string[] config = configs[i].Split(':');
                string sheetName = config[0];
                int keyIndex = int.Parse(config[1]) - 1;
                sheetConfigs.Add(sheetName, keyIndex);
            }
        }

        StringBuilder content = new StringBuilder();
        for (int i = 0; i < result.Tables.Count; i++)
        {
            int keyIndex;
            if (!sheetConfigs.TryGetValue(result.Tables[i].TableName, out keyIndex))
                keyIndex = -1;
            content.Append(GetSheetString(result.Tables[i], keyIndex));
        }
        script = Regex.Replace(script, "#CONTENT#", content.ToString());
        script = Regex.Replace(script, "#TABLENAME#", tableName);
        tableName = Regex.Replace(tableName, "\n", "");
        tableName = Regex.Replace(tableName, " ", "");
        tableName = Regex.Replace(tableName, "\r", "");
        string fileName = "Assets/LuaFramework/Lua/Config/" + tableName + ".lua";
        StreamWriter streamWriter = new StreamWriter(fileName, append, encoding);
        streamWriter.Write(script);
        streamWriter.Close();

        Debug.Log("转表:" + fileName);
    }
static string GetSheetString(DataTable data, int keyIndex)
    {
        string script =
GetIndentString(2) + "#TABLENAME# = \n" + GetIndentString(2) + "{\n" +
@"--[[
#INDEX#
#NOTE#
  ]]
#CONTENT#"
  + GetIndentString(2) + "}," + "\n";

        bool defaultKey = true;
        if (keyIndex != -1)
            defaultKey = false;

        string tableName = data.TableName;
        script = Regex.Replace(script, "#TABLENAME#", tableName);
        int columns = data.Columns.Count;
        int rows = data.Rows.Count;

        StringBuilder content = new StringBuilder();
        StringBuilder noteStr = new StringBuilder();
        string[] keys = new string[columns];
        string[] note = new string[columns];
        for (int i = 0; i < columns; i++)
        {
            keys[i] = data.Rows[0][i].ToString();
            note[i] = data.Rows[1][i].ToString();
            noteStr.Append(GetIndentString(2) + keys[i] + ":" + note[i] + "\n");
        }
        script = Regex.Replace(script, "#INDEX#", GetIndentString(2) + "配置索引为:" + (defaultKey ? "默认数字索引" : keys[keyIndex]));
        script = Regex.Replace(script, "#NOTE#", noteStr.ToString());
        int itemIndex = 1;
        bool keyIsString = false;
        if (!defaultKey)
        {
            for (int i = 2; i < rows; i++)
            {
                float result;
                string nvalue = data.Rows[i][keyIndex].ToString();
                if (nvalue.Equals(string.Empty)) continue;
                if (!float.TryParse(nvalue, out result))
                {
                    keyIsString = true;
                    break;
                }
            }

        }

        for (int i = 2; i < rows; i++)
        {
            string key = null;
            if (defaultKey)
                key = itemIndex + "";
            else
            {
                float result;
                string nvalue = data.Rows[i][keyIndex].ToString();
                if (!keyIsString && float.TryParse(nvalue, out result))
                    key = "" + nvalue + "";
                else
                    key = "\"" + nvalue + "\"";
            }
            StringBuilder obj = new StringBuilder();
            obj.Append(GetIndentString(4) + "[" + key + "]={");
            itemIndex++;
            bool valid = false;
            for (int j = 0; j < columns; j++)
            {
                string nvalue = data.Rows[i][j].ToString();
                if (nvalue.Equals(string.Empty)) continue;
                float result;
                if (float.TryParse(nvalue, out result) && nvalue.IndexOf(",") == -1)//"1,2,3":不能转为数字。
                    obj.Append(keys[j].Trim() + " = " + nvalue + " ,");
                else
                    obj.Append(keys[j].Trim() + " = [[" + nvalue + "]] ,");
                valid = true;
            }
            obj.Append("},\n");
            if (valid == true)
                content.Append(obj.ToString());
        }
        script = Regex.Replace(script, "#CONTENT#", content.ToString());
        return script;
    }

 }
可以看出来,基本逻辑是,先去指定路径取出所有的配置表存在数组里,然后根据转表配置文件确定转表类型,使用Excel内部的接口读取数据,然后用循环把所有数据重新写入到Lua文件。


猜你喜欢

转载自blog.csdn.net/oneword233/article/details/80622877