HKMBFZ/Assets/Editor/ExcelFromHierarchy.cs

137 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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