137 lines
4.3 KiB
C#
137 lines
4.3 KiB
C#
using UnityEngine;
|
||
using UnityEditor;
|
||
using System.IO;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using NPOI.HSSF.UserModel;
|
||
using TMPro;
|
||
using System.Collections.Generic;
|
||
|
||
public class ExcelFromHierarchy : EditorWindow
|
||
{
|
||
private string folderPath = "Assets/ExcelData";
|
||
private string fileName = "data.xlsx";
|
||
|
||
[MenuItem("Tools/Hierarchy -> Excel 写入(组件限定,InputField停止子物体)")]
|
||
public static void ShowWindow()
|
||
{
|
||
GetWindow<ExcelFromHierarchy>("Excel 写入组件限定");
|
||
}
|
||
|
||
private void OnGUI()
|
||
{
|
||
GUILayout.Label("Hierarchy -> Excel 写入工具", EditorStyles.boldLabel);
|
||
folderPath = EditorGUILayout.TextField("目标文件夹", folderPath);
|
||
fileName = EditorGUILayout.TextField("表名(文件名)", fileName);
|
||
|
||
if (GUILayout.Button("写入选中物体数据到 Excel"))
|
||
{
|
||
var selected = Selection.activeGameObject;
|
||
if (selected == null)
|
||
{
|
||
Debug.LogWarning("请先在 Hierarchy 中选中一个物体");
|
||
return;
|
||
}
|
||
|
||
string sheetName = selected.name;
|
||
WriteHierarchyToExcel(folderPath, fileName, selected, sheetName);
|
||
}
|
||
}
|
||
|
||
private void WriteHierarchyToExcel(string folderPath, string fileName, GameObject root, string sheetName)
|
||
{
|
||
if (!Directory.Exists(folderPath))
|
||
Directory.CreateDirectory(folderPath);
|
||
|
||
string filePath = Path.Combine(folderPath, fileName);
|
||
IWorkbook workbook = null;
|
||
ISheet sheet = null;
|
||
|
||
if (File.Exists(filePath))
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (Path.GetExtension(fileName).ToLower() == ".xls")
|
||
workbook = new HSSFWorkbook();
|
||
else
|
||
workbook = new XSSFWorkbook();
|
||
}
|
||
|
||
sheet = workbook.GetSheet(sheetName) ?? workbook.CreateSheet(sheetName);
|
||
|
||
// 清空 Sheet
|
||
int lastRow = sheet.LastRowNum;
|
||
for (int i = lastRow; i >= 0; i--)
|
||
{
|
||
var row = sheet.GetRow(i);
|
||
if (row != null) sheet.RemoveRow(row);
|
||
}
|
||
|
||
int currentRow = 0;
|
||
TraverseHierarchy(root.transform, "", (key, value) =>
|
||
{
|
||
var row = sheet.CreateRow(currentRow++);
|
||
row.CreateCell(0).SetCellValue(key);
|
||
row.CreateCell(1).SetCellValue(value);
|
||
});
|
||
|
||
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
||
{
|
||
workbook.Write(fs);
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
Debug.Log($"Hierarchy -> Excel 写入完成: {fileName} Sheet: {sheetName}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 遍历子物体
|
||
/// - 一旦找到 TMP_InputField,只获取 text 并停止对子物体搜索
|
||
/// - TMP_Dropdown / TMP_Text 同理
|
||
/// - 否则继续递归遍历子物体
|
||
/// </summary>
|
||
private void TraverseHierarchy(Transform current, string pathPrefix, System.Action<string, string> writeAction)
|
||
{
|
||
string currentPath = string.IsNullOrEmpty(pathPrefix) ? current.name : pathPrefix + "-" + current.name;
|
||
|
||
// TMP_InputField 优先判断
|
||
TMP_InputField tmpInput = current.GetComponent<TMP_InputField>();
|
||
if (tmpInput != null)
|
||
{
|
||
writeAction?.Invoke(currentPath, tmpInput.text);
|
||
return; // 找到 InputField,停止搜索子物体
|
||
}
|
||
|
||
TMP_Dropdown tmpDropdown = current.GetComponent<TMP_Dropdown>();
|
||
if (tmpDropdown != null)
|
||
{
|
||
List<string> opts = new List<string>();
|
||
foreach (var o in tmpDropdown.options)
|
||
opts.Add(o.text);
|
||
writeAction?.Invoke(currentPath, string.Join("-", opts));
|
||
return; // 找到 Dropdown,停止搜索子物体
|
||
}
|
||
|
||
TMP_Text tmpText = current.GetComponent<TMP_Text>();
|
||
if (tmpText != null)
|
||
{
|
||
writeAction?.Invoke(currentPath, tmpText.text);
|
||
return; // 找到 Text,停止搜索子物体
|
||
}
|
||
|
||
// 当前物体没有组件,递归遍历子物体
|
||
foreach (Transform child in current)
|
||
{
|
||
TraverseHierarchy(child, currentPath, writeAction);
|
||
}
|
||
}
|
||
}
|