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 "";
}
}
///
/// 严格匹配 Key,第一段必须是挂载物体名,后续段只查找直接子物体
///
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() != null)
{
found = null;
break;
}
else
{
found = child;
break;
}
}
}
if (found == null) return null; // 没找到
current = found;
}
return current; // 找到目标物体
}
///
/// 将 Excel value 填充到对应组件
///
private void ApplyValueToChild(GameObject go, string value)
{
// TMP_InputField 优先
TMP_InputField tmpInput = go.GetComponent();
if (tmpInput != null)
{
tmpInput.text = value;
return; // 不再操作子物体
}
TMP_Dropdown tmpDropdown = go.GetComponent();
if (tmpDropdown != null)
{
string[] options = value.Split('-');
tmpDropdown.ClearOptions();
tmpDropdown.AddOptions(new List(options));
if (options.Length > 0)
{
tmpDropdown.value = 0; // 默认选第一个
tmpDropdown.RefreshShownValue();
}
return;
}
TMP_Text tmpText = go.GetComponent();
if (tmpText != null)
{
tmpText.text = value;
}
}
}