NLDClient-yudde/ProjectNLD/Assets/Editor/Tools/AutoConfig/MixKeyTool/ExcelRead.cs

517 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}
}