171 lines
4.9 KiB
C#
171 lines
4.9 KiB
C#
using UnityEngine;
|
||
using System.IO;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using NPOI.HSSF.UserModel;
|
||
using TMPro;
|
||
using System.Collections.Generic;
|
||
|
||
public class ExcelToHierarchy : MonoBehaviour
|
||
{
|
||
[Header("Excel 设置")]
|
||
public string folderPath = "ExcelData";
|
||
public string fileName = "data.xlsx";
|
||
|
||
private void Awake()
|
||
{
|
||
FillFromExcel();
|
||
|
||
}
|
||
|
||
private void FillFromExcel()
|
||
{
|
||
string filePath = Path.Combine(Application.streamingAssetsPath+"/"+ folderPath, fileName);
|
||
if (!File.Exists(filePath))
|
||
{
|
||
Debug.LogWarning($"Excel 文件不存在: {filePath}");
|
||
return;
|
||
}
|
||
|
||
IWorkbook workbook;
|
||
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||
{
|
||
if (Path.GetExtension(fileName).ToLower() == ".xls")
|
||
workbook = new HSSFWorkbook(fs);
|
||
else
|
||
workbook = new XSSFWorkbook(fs);
|
||
}
|
||
|
||
string sheetName = gameObject.name; // Sheet 名与挂载物体名一致
|
||
ISheet sheet = workbook.GetSheet(sheetName);
|
||
if (sheet == null)
|
||
{
|
||
Debug.LogWarning($"Sheet 不存在: {sheetName}");
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i <= sheet.LastRowNum; i++)
|
||
{
|
||
IRow row = sheet.GetRow(i);
|
||
if (row == null) continue;
|
||
|
||
ICell keyCell = row.GetCell(0);
|
||
ICell valueCell = row.GetCell(1);
|
||
if (keyCell == null || valueCell == null) continue;
|
||
|
||
string key = GetCellStringValue(keyCell);
|
||
string value = GetCellStringValue(valueCell);
|
||
|
||
Transform target = FindTargetByKey(transform, key);
|
||
if (target != null)
|
||
{
|
||
ApplyValueToChild(target.gameObject, value);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"子物体未找到: {key}");
|
||
}
|
||
}
|
||
|
||
Debug.Log("Excel 数据填充完成");
|
||
}
|
||
|
||
private string GetCellStringValue(ICell cell)
|
||
{
|
||
if (cell == null) return "";
|
||
switch (cell.CellType)
|
||
{
|
||
case CellType.String: return cell.StringCellValue;
|
||
case CellType.Numeric: return cell.NumericCellValue.ToString();
|
||
case CellType.Boolean: return cell.BooleanCellValue.ToString();
|
||
case CellType.Formula:
|
||
if (cell.CachedFormulaResultType == CellType.String)
|
||
return cell.StringCellValue;
|
||
if (cell.CachedFormulaResultType == CellType.Numeric)
|
||
return cell.NumericCellValue.ToString();
|
||
return cell.ToString();
|
||
default: return "";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 严格匹配 Key,第一段必须是挂载物体名,后续段只查找直接子物体
|
||
/// </summary>
|
||
private Transform FindTargetByKey(Transform root, string key)
|
||
{
|
||
string[] parts = key.Split('-');
|
||
if (parts.Length < 2)
|
||
{
|
||
Debug.LogWarning($"Key 格式不正确(至少挂载物体-子物体): {key}");
|
||
return null;
|
||
}
|
||
|
||
// 第一段必须是挂载物体名
|
||
if (parts[0] != root.name)
|
||
return null;
|
||
|
||
Transform current = root;
|
||
// 从第二段开始,每级只在当前物体的直接子物体中查找
|
||
for (int i = 1; i < parts.Length; i++)
|
||
{
|
||
string childName = parts[i];
|
||
Transform found = null;
|
||
foreach (Transform child in current)
|
||
{
|
||
if (child.name == childName)
|
||
{
|
||
if (child.GetComponent<ReadExlAndSetValue>() != null)
|
||
{
|
||
found = null;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
found = child;
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
if (found == null) return null; // 没找到
|
||
current = found;
|
||
}
|
||
|
||
return current; // 找到目标物体
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将 Excel value 填充到对应组件
|
||
/// </summary>
|
||
private void ApplyValueToChild(GameObject go, string value)
|
||
{
|
||
// TMP_InputField 优先
|
||
TMP_InputField tmpInput = go.GetComponent<TMP_InputField>();
|
||
if (tmpInput != null)
|
||
{
|
||
tmpInput.text = value;
|
||
return; // 不再操作子物体
|
||
}
|
||
|
||
TMP_Dropdown tmpDropdown = go.GetComponent<TMP_Dropdown>();
|
||
if (tmpDropdown != null)
|
||
{
|
||
string[] options = value.Split('-');
|
||
tmpDropdown.ClearOptions();
|
||
tmpDropdown.AddOptions(new List<string>(options));
|
||
if (options.Length > 0)
|
||
{
|
||
tmpDropdown.value = 0; // 默认选第一个
|
||
tmpDropdown.RefreshShownValue();
|
||
}
|
||
return;
|
||
}
|
||
|
||
TMP_Text tmpText = go.GetComponent<TMP_Text>();
|
||
if (tmpText != null)
|
||
{
|
||
tmpText.text = value;
|
||
}
|
||
}
|
||
}
|