164 lines
6.0 KiB
C#
164 lines
6.0 KiB
C#
#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代表第一个Sheet,1代表第二个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 |