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