Tz2/Assets/Scripts/ExcelTableGenerator.cs

164 lines
6.0 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.

#if UNITY_EDITOR
using UnityEngine;
using UnityEngine.UI;
using System.Data;
using System.IO;
using Excel;
using TMPro;
using UnityEditor;
using UnityEditor.SceneManagement;
using System;
public class ExcelTableGenerator : EditorWindow
{
private string excelPath = "";
private GameObject scrollViewPrefab;
private GameObject rowPrefab;
private GameObject cellPrefab;
private int selectedSheetIndex = 1; // 默认选择第二个Sheet页索引从0开始
private int customRowCount = 10; // 自定义行数
private int customColumnCount = 5; // 自定义列数
[MenuItem("Tools/Excel表格生成器")]
public static void ShowWindow()
{
GetWindow<ExcelTableGenerator>("Excel表格生成器");
}
private void OnGUI()
{
GUILayout.Label("Excel表格生成器", EditorStyles.boldLabel);
if (GUILayout.Button("选择Excel文件"))
{
excelPath = EditorUtility.OpenFilePanel("选择Excel文件", "", "xlsx");
}
scrollViewPrefab = EditorGUILayout.ObjectField("Scroll View预制体", scrollViewPrefab, typeof(GameObject), false) as GameObject;
rowPrefab = EditorGUILayout.ObjectField("行预制体", rowPrefab, typeof(GameObject), false) as GameObject;
cellPrefab = EditorGUILayout.ObjectField("单元格预制体", cellPrefab, typeof(GameObject), false) as GameObject;
// 添加Sheet页选择
selectedSheetIndex = EditorGUILayout.IntField("Sheet页索引", selectedSheetIndex);
EditorGUILayout.HelpBox("Sheet页索引从0开始0代表第一个Sheet1代表第二个Sheet以此类推", MessageType.Info);
// 添加自定义行数和列数输入
customRowCount = EditorGUILayout.IntField("生成行数", customRowCount);
customColumnCount = EditorGUILayout.IntField("生成列数", customColumnCount);
EditorGUILayout.HelpBox("设置要生成的表格行数和列数", MessageType.Info);
if (GUILayout.Button("生成表格") && !string.IsNullOrEmpty(excelPath))
{
GenerateTable();
}
}
private void GenerateTable()
{
// 读取Excel文件
FileStream stream = File.Open(excelPath, FileMode.Open, FileAccess.Read, FileShare.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
// 检查Sheet页索引是否有效
if (selectedSheetIndex >= result.Tables.Count)
{
EditorUtility.DisplayDialog("错误", $"所选Sheet页索引 {selectedSheetIndex} 无效Excel文件只有 {result.Tables.Count} 个Sheet页", "确定");
excelReader.Close();
stream.Close();
return;
}
DataTable table = result.Tables[selectedSheetIndex];
// 使用自定义行数但不超过Excel文件的实际行数
int maxRows = Math.Min(customRowCount, table.Rows.Count);
// 创建Scroll View
GameObject scrollView = Instantiate(scrollViewPrefab);
scrollView.name = "ExcelScrollView";
// 获取Content对象
ScrollRect scrollRect = scrollView.GetComponent<ScrollRect>();
Transform content = scrollRect.content;
RectTransform contentRect = content as RectTransform;
// 生成数据行
for (int row = 0; row < maxRows; row++)
{
// 检查这一行是否全为空
bool isEmptyRow = true;
int maxCols = Math.Min(customColumnCount, table.Columns.Count);
for (int col = 0; col < maxCols; col++)
{
if (!string.IsNullOrEmpty(table.Rows[row][col]?.ToString()))
{
isEmptyRow = false;
break;
}
}
// 如果是空行,跳过
if (isEmptyRow) continue;
GameObject dataRow = Instantiate(rowPrefab, content);
dataRow.name = $"DataRow_{row}";
// 使用自定义列数但不超过Excel文件的实际列数
for (int col = 0; col < maxCols; col++)
{
GameObject cell = Instantiate(cellPrefab, dataRow.transform);
cell.name = $"Cell_{row}_{col}";
TMP_InputField text = cell.GetComponent<TMP_InputField>();
if (text != null)
{
var cellValue = table.Rows[row][col]?.ToString() ?? "";
text.text = cellValue;
}
}
}
// 确保所有UI元素都被正确初始化
Canvas.ForceUpdateCanvases();
// 延迟一帧后更新布局
EditorApplication.delayCall += () =>
{
// 重新计算所有布局
LayoutRebuilder.ForceRebuildLayoutImmediate(contentRect);
// 确保滚动视图回到顶部
scrollRect.normalizedPosition = new Vector2(0, 1);
// 标记场景为脏以保存更改
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
};
// 关闭Excel读取器和文件流
excelReader.Close();
stream.Close();
// 计算实际的行数(不包括空行)
int actualRowCount = 0;
for (int row = 0; row < maxRows; row++)
{
bool isEmptyRow = true;
int maxCols = Math.Min(customColumnCount, table.Columns.Count);
for (int col = 0; col < maxCols; col++)
{
if (!string.IsNullOrEmpty(table.Rows[row][col]?.ToString()))
{
isEmptyRow = false;
break;
}
}
if (!isEmptyRow) actualRowCount++;
}
// 调整Content大小以适应所有内容
float totalHeight = actualRowCount * 30f;
float totalWidth = customColumnCount * 100f;
(content as RectTransform).sizeDelta = new Vector2(totalWidth, totalHeight);
}
}
#endif