首先要感谢王王王渣渣这位大佬,把插件和制作步骤写的很清楚,原文链接请参考
在此,我主要写制作过程和我在制作中遇到的问题
一:效果展示
二:unity读取excel文件的过程
1.导入插件
链接: https://pan.baidu.com/s/1NhY_VxmO233cp3N09VErNw 提取码: qc5k
(将dll文件导入自建的Plugins文件夹下)
2.原始Excel表格
3.ItemMangager脚本
其中包含两个类:第一个类用来存放每行的表数据,第二个类用来存放前者的数组即所有的表数据(ItemManager)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Data
{
[System.Serializable]
public class Item
{
public string Name; //姓名
public string work; //职务
public string sex; //性别
public string age; //年龄
}
public class ItemManager : ScriptableObject
{
public Item[] dataArray;
}
}
其中Item中声明的每个变量都是在excel中的表头,有几个表头就定义几个变量(对于有出生年月这种含标点符号的数据,要声明为string),在ExcelTool中也要将对应的数据对应好,少了或多了数据都会报错
4.ExcelTool脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Data;
using System.IO;
using System.Text;
using Excel;
using UnityEditor;
using Data;
public class ExcelTool : MonoBehaviour
{
public class ExcelConfig
{
/// <summary>
/// 存放excel表文件夹的的路径,本例excel表放在了"StreamingAssets/Excels/"当中
/// </summary>
public static readonly string excelsFolderPath = Application.streamingAssetsPath +"/";
/// <summary>
/// 存放Excel转化CS文件的文件夹路径
/// </summary>
public static readonly string assetPath = "Assets/Resources/DataAssets/";
}
/// <summary>
/// 读取表数据,生成对应的数组
/// </summary>
/// <param name="filePath">excel文件全路径</param>
/// <returns>Item数组</returns>
public class Excel_Tool
{
static DataRowCollection ReadExcel(string filePath, ref int columnNum, ref int rowNum)
{
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
//Tables[0] 下标0表示excel文件中第一张表的数据
columnNum = result.Tables[0].Columns.Count;
rowNum = result.Tables[0].Rows.Count;
return result.Tables[0].Rows;
}
/// <summary>
/// 读取excel文件内容
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="columnNum">行数</param>
/// <param name="rowNum">列数</param>
/// <returns></returns>
public static Item[] CreateItemArrayWithExcel(string filePath)
{
//获得表数据
int columnNum = 0, rowNum = 0;
DataRowCollection collect = ReadExcel(filePath, ref columnNum, ref rowNum);
//根据excel的定义,第二行开始才是数据
Item[] array = new Item[rowNum - 1];
for (int i = 1; i < rowNum; i++)
{
Item item = new Item();
//解析每列的数据
item.Name = collect[i][1].ToString();
item.work = collect[i][2].ToString();
item.sex = collect[i][3].ToString();
item.age = collect[i][4].ToString();
array[i - 1] = item;
}
return array;
}
}
public class ExcelBuild : Editor
{
[MenuItem("CustomEditor/CreateItemAsset")]
public static void CreateItemAsset()
{
ItemManager manager = ScriptableObject.CreateInstance<ItemManager>();
//赋值
manager.dataArray = Excel_Tool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + "Item.xlsx");
//确保文件夹存在
if (!Directory.Exists(ExcelConfig.assetPath))
{
Directory.CreateDirectory(ExcelConfig.assetPath);
}
//asset文件的路径 要以"Assets/..."开始,否则CreateAsset会报错
string assetPath = string.Format("{0}{1}.asset", ExcelConfig.assetPath, "Item");
//生成一个Asset文件
AssetDatabase.CreateAsset(manager, assetPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}
注意:
1、ExcelConfig方法中,excel文件的存放地址为:直接放在新建的StreamingAssets下,并且名称必须ExcelBuild中的名称一致,注意excel文件的后缀名:为xlsx。
//赋值
manager.dataArray = Excel_Tool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + "Item.xlsx");
ExcelConfig方法中的assetPath路径,在unity中新建一下文件夹,这个文件夹下面生成的是excel生成unity数据的路径,必须名称一致,不然找不到
2、item方法中的数据必须与ItemManager中声明的数据一致
5.在unity中生成excel数据
在unity中点击CustomEdiotor——CreateItemAsset就可生成数据
注意:将Item.asset生成之后,在最终导出的时候,需要将ExcelTool脚本删除,不然会导出失败
三:在unity中绘制表格
1.预制体的制作
新建一个空物体,加上Grid Layout Group组件,对文字进行排列,然后取消Grid Layout Group的勾选,在添加一条线的图片(这个可加可不加),如果需要竖线的话,可以在添加
2.新建一个ScrollView
大小自己调整将预制体放进content里面,在content上添加以下组件
3.编写代码ExcelTest
using Data;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ExcelTest : MonoBehaviour
{
List<GameObject> contents;
[SerializeField] GameObject prefab; //预制体
[SerializeField] GameObject parent; //父物体(content)
void Start()
{
//获取item的数据
ItemManager man = Resources.Load<ItemManager>("DataAssets/Item");
//循环生成预制体
for (int i = 0; i < 9; i++)
{
GameObject item = Instantiate(prefab, parent.transform);
//将预制体加入列表
contents.Add(item);
//数据赋值
contents[i].transform.GetChild(0).GetComponent<Text>().text = man.dataArray[i].Name;
contents[i].transform.GetChild(1).GetComponent<Text>().text = man.dataArray[i].work;
contents[i].transform.GetChild(2).GetComponent<Text>().text = man.dataArray[i].sex;
contents[i].transform.GetChild(3).GetComponent<Text>().text = man.dataArray[i].age;
}
}
}
将代码挂载在一个空物体上,在循环中,i的总数是根据Item的数据数决定的
这样之后点击运行就可以将表格生成了