517 lines
18 KiB
C#
517 lines
18 KiB
C#
using System;
|
||
using UnityEditor;
|
||
using System.Collections.Generic;
|
||
using System.Globalization;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using TGS;
|
||
using UnityEngine;
|
||
|
||
namespace AutoConfig
|
||
{
|
||
public static class ExcelRead
|
||
{
|
||
private static List<string> _stringCfgMixKeyList; //stringCfg里面所有的MixKey
|
||
public static List<string> StringCfgMixValueList = new();
|
||
|
||
public static List<string> StringCfgMixKeyList => _stringCfgMixKeyList;
|
||
|
||
private static Dictionary<string, IWorkbook> _cacheWorkbooks = new();
|
||
private static List<FileStream> _listFileStreams = new();
|
||
|
||
public enum RowInfo
|
||
{
|
||
Variable,
|
||
Type,
|
||
Config
|
||
}
|
||
|
||
#region 生成StringConfig对应的Key/Value
|
||
|
||
/// <summary>
|
||
/// 加载StringConfig表中的MixKey,放入列表
|
||
/// </summary>
|
||
public static void LoadStrCfgMixKeyList()
|
||
{
|
||
if (_stringCfgMixKeyList == null)
|
||
{
|
||
_stringCfgMixKeyList = new List<string>();
|
||
}
|
||
else
|
||
{
|
||
_stringCfgMixKeyList.Clear();
|
||
}
|
||
|
||
//ExcelWrite.CfgMixKeyDataList.Clear();
|
||
var stringCfgPath = GenMixKeyTool.CfgPath + GenMixKeyTool.StringConfigPath;
|
||
var workBook = GetWorkBook(stringCfgPath);
|
||
if (workBook == null)
|
||
{
|
||
DebugUtil.LogError($"找不到配置表文件,路径: {stringCfgPath}");
|
||
return;
|
||
}
|
||
|
||
var sheetNum = workBook.NumberOfSheets;
|
||
for (int i = 0; i < sheetNum; i++)
|
||
{
|
||
int sheetIdx = i;
|
||
int rowIdx = -1;
|
||
int lineIdx = -1;
|
||
var sheet = workBook.GetSheetAt(i);
|
||
var row = sheet.GetRow(0);
|
||
var curRowIdx = 0;
|
||
var mixKeyLineIdx = new List<int>();
|
||
while (row != null)
|
||
{
|
||
var cell = row.GetCell(0);
|
||
var cellContent = TryReadCell(cell);
|
||
var lineNum = row.PhysicalNumberOfCells;
|
||
|
||
rowIdx = curRowIdx;
|
||
|
||
if (cellContent == "##var")
|
||
{
|
||
int cIdx = 1;
|
||
for (; cIdx < lineNum; cIdx++)
|
||
{
|
||
var curCell = row.GetCell(cIdx);
|
||
var curContent = TryReadCell(curCell);
|
||
if (curContent.Contains("Param"))
|
||
{
|
||
mixKeyLineIdx.Add(cIdx);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (cellContent != "##type" && cellContent != "##group" && cellContent != "##")
|
||
{
|
||
for (int idx = 0; idx < mixKeyLineIdx.Count; idx++)
|
||
{
|
||
lineIdx = mixKeyLineIdx[idx];
|
||
var curCell = row.GetCell(mixKeyLineIdx[idx]);
|
||
var curContent = TryReadCell(curCell);
|
||
if (curContent.Length > 0)
|
||
{
|
||
if (!_stringCfgMixKeyList.Contains(curContent))
|
||
{
|
||
_stringCfgMixKeyList.Add(curContent);
|
||
// ExcelWrite.CfgMixKeyDataList.Add(curContent, new CfgMixKeyData()
|
||
// {
|
||
// key = curContent,
|
||
// rowIndex = rowIdx,
|
||
// lineIndex = lineIdx,
|
||
// sheetIndex = sheetIdx
|
||
// });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
row = sheet.GetRow(++curRowIdx);
|
||
}
|
||
}
|
||
}
|
||
|
||
public static List<int> GetValueIndexList(string configName, List<string> keys)
|
||
{
|
||
var cfgPath = GenMixKeyTool.CfgPath + configName + ".xlsx";
|
||
var workBook = GetWorkBook(cfgPath);
|
||
if (workBook == null)
|
||
{
|
||
DebugUtil.LogError($"找不到配置表文件,路径: {cfgPath}");
|
||
return null;
|
||
}
|
||
|
||
var keyCount = keys.Count;
|
||
var needKeyList = GetMultipleKey(configName);
|
||
if (needKeyList == null)
|
||
{
|
||
DebugUtil.LogError($"配置的Key值不对劲, 数量错误, 配置的表: {configName}, Key:{keys[0]}");
|
||
return default;
|
||
}
|
||
|
||
if(needKeyList.Count != keyCount)
|
||
{
|
||
DebugUtil.LogError($"配置的Key值不对劲, 数量错误, 配置的表: {configName}, Key:{keys[0]}");
|
||
return default;
|
||
}
|
||
|
||
var sheetCount = workBook.NumberOfSheets;
|
||
var keyIdxList = new List<int>(needKeyList.Count);
|
||
for (int i = 0; i < keyCount; i++)
|
||
{
|
||
keyIdxList.Add(-1);
|
||
}
|
||
for (int i = 0; i < sheetCount; i++)
|
||
{
|
||
var sheet = workBook.GetSheetAt(i);
|
||
var row = sheet.GetRow(0);
|
||
var rowIndex = 0;
|
||
while (row != null)
|
||
{
|
||
var cell = row.GetCell(0);
|
||
var content = TryReadCell(cell);
|
||
if (content == "##var")
|
||
{
|
||
int keyIdx = 1;
|
||
for (; keyIdx < row.PhysicalNumberOfCells; keyIdx++)
|
||
{
|
||
cell = row.GetCell(keyIdx);
|
||
content = TryReadCell(cell);
|
||
for (int n = 0; n < needKeyList.Count; n++)
|
||
{
|
||
if (needKeyList[n] == content)
|
||
{
|
||
keyIdxList[n] = keyIdx;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (keyIdxList.Contains(-1))
|
||
{
|
||
DebugUtil.LogError("获取索引值列表时有误,有数据为-1!!! ");
|
||
}
|
||
return keyIdxList;
|
||
}
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
}
|
||
|
||
return keyIdxList;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据索引获取到具体的配置值
|
||
/// </summary>
|
||
/// <param name="configName"></param>
|
||
/// <param name="param"></param>
|
||
/// <param name="keyIdxList"></param>
|
||
/// <param name="indexList"></param>
|
||
/// <returns></returns>
|
||
public static string GetStringValByIndex(string configName, string param, List<int> keyIdxList,
|
||
List<string> indexList, int listIdx = 0)
|
||
{
|
||
var cfgPath = GenMixKeyTool.CfgPath + configName + ".xlsx";
|
||
var workBook = GetWorkBook(cfgPath);
|
||
if (workBook == null)
|
||
{
|
||
DebugUtil.LogError($"找不到配置表文件,路径: {cfgPath}");
|
||
return null;
|
||
}
|
||
|
||
var idxCount = indexList.Count;
|
||
if (idxCount != keyIdxList.Count)
|
||
{
|
||
DebugUtil.LogError($"获取配置表对应ID内容时失败,原因: keyList和indexList数量无法对应。");
|
||
return null;
|
||
}
|
||
|
||
char departChar = '|';
|
||
bool isList = false;
|
||
var sheetCount = workBook.NumberOfSheets;
|
||
int valueParamIdx = 0;
|
||
//寻找对应参数那一列
|
||
for (int i = 0; i < sheetCount; i++)
|
||
{
|
||
var sheet = workBook.GetSheetAt(i);
|
||
var row = sheet.GetRow(0);
|
||
var rowIndex = 0;
|
||
while (row != null)
|
||
{
|
||
var cell0 = row.GetCell(0);
|
||
var content0 = TryReadCell(cell0);
|
||
if (content0 == "##var")
|
||
{
|
||
for (int idx = 1; idx < row.PhysicalNumberOfCells; idx++)
|
||
{
|
||
var cell = row.GetCell(idx);
|
||
var content = TryReadCell(cell);
|
||
if (content == param)
|
||
{
|
||
valueParamIdx = idx;
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
|
||
//识别是否为List
|
||
rowIndex = 0;
|
||
row = sheet.GetRow(0);
|
||
while (row != null)
|
||
{
|
||
var cell0 = row.GetCell(0);
|
||
var content0 = TryReadCell(cell0);
|
||
if (content0 == "##type")
|
||
{
|
||
var idx = valueParamIdx;
|
||
var cell = row.GetCell(idx);
|
||
var content = TryReadCell(cell);
|
||
if (content.Contains("list"))
|
||
{
|
||
isList = true;
|
||
var length = "(list#sep=".Length;
|
||
departChar = content[length];
|
||
}
|
||
break;
|
||
}
|
||
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
|
||
//获取格子内容
|
||
rowIndex = 0;
|
||
row = sheet.GetRow(0);
|
||
while (row != null)
|
||
{
|
||
var cell0 = row.GetCell(keyIdxList[0]);
|
||
var content0 = TryReadCell(cell0);
|
||
if (content0 == indexList[0])
|
||
{
|
||
int idx = 1;
|
||
bool isCurRow = true;
|
||
for (; idx < indexList.Count; idx++)
|
||
{
|
||
var cell = row.GetCell(keyIdxList[idx]);
|
||
if (cell == null)
|
||
{
|
||
DebugUtil.LogError($"获取配置表对应ID内容时失败,原因: 传入的Key索引元素在配置表中不存在!!!");
|
||
return null;
|
||
}
|
||
|
||
var content = TryReadCell(cell);
|
||
if (content != indexList[idx])
|
||
{
|
||
isCurRow = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (isCurRow)
|
||
{
|
||
var val = TryReadCell(row.GetCell(valueParamIdx));
|
||
if (isList)
|
||
{
|
||
string[] strList = val.Split(departChar);
|
||
if (listIdx >= strList.Length)
|
||
{
|
||
DebugUtil.LogError($"配置的list索引超出了list长度! configName: {configName}",
|
||
$"rowIdx:{rowIndex}, valueIdx:{valueParamIdx}");
|
||
return "";
|
||
}
|
||
|
||
return strList[listIdx];
|
||
}
|
||
return val;
|
||
}
|
||
}
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// 获取工作簿
|
||
/// </summary>
|
||
/// <param name="excelPath"></param>
|
||
/// <returns></returns>
|
||
public static IWorkbook GetWorkBook(string excelPath)
|
||
{
|
||
FileStream fs = null;
|
||
if (_cacheWorkbooks.TryGetValue(excelPath, out var workbook))
|
||
{
|
||
return workbook;
|
||
}
|
||
try
|
||
{
|
||
fs = new FileStream(excelPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
_listFileStreams.Add(fs);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogException(e);
|
||
}
|
||
|
||
if (fs == null)
|
||
{
|
||
Debug.LogError("无法打开文件{0},跳过处理:" + excelPath);
|
||
return null;
|
||
}
|
||
|
||
var isXlsx = excelPath.EndsWith(".xlsx", System.StringComparison.CurrentCultureIgnoreCase);
|
||
if (isXlsx)
|
||
{
|
||
IWorkbook workBook = new XSSFWorkbook(fs);
|
||
_cacheWorkbooks.TryAdd(excelPath, workBook);
|
||
return workBook;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public static void InitAll()
|
||
{
|
||
_cacheWorkbooks.Clear();
|
||
_listFileStreams.Clear();
|
||
}
|
||
|
||
public static void ReleaseAll()
|
||
{
|
||
for (int i = _listFileStreams.Count - 1; i >= 0; i--)
|
||
{
|
||
_listFileStreams[i].Close();
|
||
}
|
||
|
||
_cacheWorkbooks.Clear();
|
||
_listFileStreams.Clear();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读格子,转换成string
|
||
/// </summary>
|
||
/// <param name="cell"></param>
|
||
/// <returns></returns>
|
||
public static string TryReadCell(ICell cell)
|
||
{
|
||
if (cell == null)
|
||
{
|
||
return "";
|
||
}
|
||
if (cell.CellType == CellType.String)
|
||
{
|
||
return cell.StringCellValue;
|
||
}
|
||
if (cell.CellType == CellType.Numeric)
|
||
{
|
||
return cell.NumericCellValue.ToString(CultureInfo.InvariantCulture);
|
||
}
|
||
if (cell.CellType == CellType.Boolean)
|
||
{
|
||
return cell.BooleanCellValue.ToString();
|
||
}
|
||
if (cell.CellType == CellType.Blank)
|
||
{
|
||
return "";
|
||
}
|
||
Debug.LogError("暂不支持的单元格类型:" + cell.CellType + "");
|
||
return "";
|
||
}
|
||
|
||
private static List<string> GetMultipleKey(string cfgName)
|
||
{
|
||
var cfgFullName = cfgName + ".xlsx";
|
||
var tableCfg = GenMixKeyTool.CfgPath + "__tables__" + ".xlsx";
|
||
var workBook = GetWorkBook(tableCfg);
|
||
if (workBook == null)
|
||
{
|
||
DebugUtil.LogError("__tables__ 不存在,请检查传入路径");
|
||
return null;
|
||
}
|
||
|
||
var sheetNum = workBook.NumberOfSheets;
|
||
int cfgIdx = -1; //配置表列索引
|
||
int keyNumIdx = -1; //key数量列索引
|
||
|
||
//先取对应的表名和key值列索引
|
||
for (int i = 0; i < sheetNum; i++)
|
||
{
|
||
var sheet = workBook.GetSheetAt(i);
|
||
var rowIndex = 0;
|
||
var row = sheet.GetRow(rowIndex);
|
||
if (i == 0)
|
||
{
|
||
while (row != null)
|
||
{
|
||
var cell = row.GetCell(0);
|
||
var content = TryReadCell(cell);
|
||
if (content == "##var")
|
||
{
|
||
for (int idx = 1; idx < row.PhysicalNumberOfCells; idx++)
|
||
{
|
||
var curCell = row.GetCell(idx);
|
||
var curContent = TryReadCell(curCell);
|
||
if (curContent == "input")
|
||
{
|
||
cfgIdx = idx;
|
||
}
|
||
|
||
if (curContent == "index")
|
||
{
|
||
keyNumIdx = idx;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
}
|
||
|
||
//取到后找到对应的配置表那一行,取key值判断
|
||
rowIndex = 0;
|
||
row = sheet.GetRow(rowIndex);
|
||
while (row != null)
|
||
{
|
||
var inputContent = TryReadCell(row.GetCell(cfgIdx));
|
||
if (inputContent.Contains(cfgFullName))
|
||
{
|
||
var keyContent = TryReadCell(row.GetCell(keyNumIdx));
|
||
if (keyContent.Contains("+"))
|
||
{
|
||
string[] list = keyContent.Split('+');
|
||
return list.ToList();
|
||
}
|
||
if(keyContent.Contains(","))
|
||
{
|
||
string[] list = keyContent.Split(',');
|
||
return new List<string> { list[0] };
|
||
}
|
||
|
||
var firstKey = GetFirstKey(cfgName);
|
||
return new List<string> {firstKey};
|
||
}
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
private static string GetFirstKey(string configName)
|
||
{
|
||
var cfgPath = GenMixKeyTool.CfgPath + configName + ".xlsx";
|
||
var workBook = GetWorkBook(cfgPath);
|
||
if (workBook == null)
|
||
{
|
||
DebugUtil.LogError($"找不到配置表文件,路径: {cfgPath}");
|
||
return null;
|
||
}
|
||
|
||
var sheet = workBook.GetSheetAt(0);
|
||
var rowIndex = 0;
|
||
var row = sheet.GetRow(rowIndex);
|
||
while (row != null)
|
||
{
|
||
var cell0 = row.GetCell(0);
|
||
var str0 = TryReadCell(cell0);
|
||
if (str0 == "##var")
|
||
{
|
||
return TryReadCell(row.GetCell(1));
|
||
}
|
||
row = sheet.GetRow(++rowIndex);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
}
|
||
} |