让策划也能轻松修改数据,将xml表格转为Object导入脚本

让策划也能轻松修改数据,将xml表格转为Object导入脚本

目录

插件源码

依赖以下四个dll

在这里插入图片描述

文件目录

脚本代码

JasonToObject
using System.Collections;
using System.Collections.Generic;
using System.IO;
using LitJson;
using UnityEngine;

public static class JsonToObject
{
    /// <summary>
    /// 把一个Json文本文件,转成一个对象(Object)
    /// </summary>
    /// <typeparam name="T">对象的类型</typeparam>
    /// <param name="filePath">Json文本文件的地址(需要加上文件名和后缀名)</param>
    /// <returns></returns>
    public static List<T> JsonToObject_ByJsonFile<T>(string filePath)
    {
        /*直接解析成对象*/
        //读取Json文本中的内容
        string json = File.ReadAllText(filePath);
        //解析Json文本中的内容 -(解析成数组或者List列表都可以)
        List<T> datas = JsonToObject_ByJsonContent<T>(json);
        return datas;
    }

    /// <summary>
    /// 把一个Json格式的文本,转成一个对象(Object)
    /// </summary>
    /// <typeparam name="T">对象的类型</typeparam>
    /// <param name="filePath">Json文本中的内容</param>
    /// <returns></returns>
    public static List<T> JsonToObject_ByJsonContent<T>(string conntent)
    {
        /*直接解析成对象*/
        //解析Json文本中的内容 -(解析成数组或者List列表都可以)
        T[] datas = JsonMapper.ToObject<T[]>(conntent);

        //把数组封装成List列表
        List<T> dataList = new List<T>();
        for (int i = 0; i < datas.Length; i++)
        {
            dataList.Add(datas[i]);
        }
        return dataList;
    }
}
这里解释一下这两个API

这里解释一下这两个API

JsonToObject.JsonToObject_ByJsonFile()*

用于把一个Json文件转换为(Object)

参数:Json 文本文件的地址(需要加上文件名的后缀名)

/// 把一个Json文本文件,转成一个对象(Object)
/// <typeparam name="T">对象的类型</typeparam>
/// <param name="filePath">Json文本文件的地址(需要加上文件名和后缀名)</param>
public static List<T> JsonToObject_ByJsonFile<T>(string filePath)
{
    /*直接解析成对象*/
	//读取Json文本中的内容
    string json = File.ReadAllText(filePath);
    //解析Json文本中的内容 -(解析成数组或者List列表都可以)
    List<T> datas = JsonToObject_ByJsonContent<T>(json);

    return datas;
}

返回值:泛型类型的列表

JsonToObject.JsonToObject_ByJsonContent()

用于把一个Json格式的文本转换为(Object)

参数:Json 文本文件中的内容

/// 把一个Json格式的文本,转成一个对象(Object)
/// <typeparam name="T">对象的类型</typeparam>
/// <param name="filePath">Json文本中的内容</param>
public static List<T> JsonToObject_ByJsonContent<T>(string conntent)
{
    /*直接解析成对象*/
    //解析Json文本中的内容 -(解析成数组或者List列表都可以)
    T[] datas = JsonMapper.ToObject<T[]>(conntent);

    //把数组封装成List列表
    List<T> dataList = new List<T>();
    for (int i = 0; i < datas.Length; i++)
    {
        dataList.Add(datas[i]);
    }

    return dataList;
}

返回值:泛型类型的列表

ExcelTools
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public class ExcelTools : EditorWindow
{
	/// <summary>
	/// 当前编辑器窗口实例
	/// </summary>
	private static ExcelTools instance;

	/// <summary>
	/// Excel文件列表
	/// </summary>
	private static List<string> excelList;

	/// <summary>
	/// 项目根路径	
	/// </summary>
	private static string pathRoot;

	/// <summary>
	/// 滚动窗口初始位置
	/// </summary>
	private static Vector2 scrollPos;

	/// <summary>
	/// 输出格式索引
	/// </summary>
	private static int indexOfFormat=0;

	/// <summary>
	/// 输出格式
	/// </summary>
	private static string[] formatOption=new string[]{"JSON","CSV","XML"};

	/// <summary>
	/// 编码索引
	/// </summary>
	private static int indexOfEncoding=0;

	/// <summary>
	/// 编码选项
	/// </summary>
	private static string[] encodingOption=new string[]{"UTF-8","GB2312"};

	/// <summary>
	/// 是否保留原始文件
	/// </summary>
	private static bool keepSource=true;

	/// <summary>
	/// 显示当前窗口	
	/// </summary>
	[MenuItem("Plugins/ExcelTools")]
	static void ShowExcelTools()
	{
		Init();
		//加载Excel文件
		LoadExcel();
		instance.Show();
	}

	void OnGUI()
	{
		DrawOptions();
		DrawExport();
	}

	/// <summary>
	/// 绘制插件界面配置项
	/// </summary>
	private void DrawOptions()
	{
		GUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("请选择格式类型:",GUILayout.Width(85));
		indexOfFormat=EditorGUILayout.Popup(indexOfFormat,formatOption,GUILayout.Width(125));
		GUILayout.EndHorizontal();

		GUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("请选择编码类型:",GUILayout.Width(85));
		indexOfEncoding=EditorGUILayout.Popup(indexOfEncoding,encodingOption,GUILayout.Width(125));
		GUILayout.EndHorizontal();

		keepSource=GUILayout.Toggle(keepSource,"保留Excel源文件");
	}

	/// <summary>
	/// 绘制插件界面输出项
	/// </summary>
	private void DrawExport()
	{
		if(excelList==null) return;
		if(excelList.Count<1)
		{
			EditorGUILayout.LabelField("目前没有Excel文件被选中哦!");
		}
		else
		{
			EditorGUILayout.LabelField("下列项目将被转换为" + formatOption[indexOfFormat] + ":");
			GUILayout.BeginVertical();
			scrollPos=GUILayout.BeginScrollView(scrollPos,false,true,GUILayout.Height(150));
			foreach(string s in excelList)
			{
				GUILayout.BeginHorizontal();
				GUILayout.Toggle(true,s);
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();

			//输出
			if(GUILayout.Button("转换"))
			{
				Convert();
			}
		}
	}

	/// <summary>
	/// 转换Excel文件
	/// </summary>
	private static void Convert()
	{
		foreach(string assetsPath in excelList)
		{
			//获取Excel文件的绝对路径
			string excelPath=pathRoot + "/" + assetsPath;
			//构造Excel工具类
			ExcelUtility excel=new ExcelUtility(excelPath);

			//判断编码类型
			Encoding encoding=null;
			if(indexOfEncoding==0){
				encoding=Encoding.GetEncoding("utf-8");
			}else if(indexOfEncoding==1){
				encoding=Encoding.GetEncoding("gb2312");
			}

			//判断输出类型
			string output="";
			if(indexOfFormat==0){
				output=excelPath.Replace(".xlsx",".json");
				excel.ConvertToJson(output,encoding);
			}else if(indexOfFormat==1){
				output=excelPath.Replace(".xlsx",".csv");
				excel.ConvertToCSV(output,encoding);
			}else if(indexOfFormat==2){
				output=excelPath.Replace(".xlsx",".xml");
				excel.ConvertToXml(output);
			}

			//判断是否保留源文件
			if(!keepSource)
			{
				FileUtil.DeleteFileOrDirectory(excelPath);
			}

			//刷新本地资源
			AssetDatabase.Refresh();
		}

		//转换完后关闭插件
		//这样做是为了解决窗口
		//再次点击时路径错误的Bug
		instance.Close();

	}

	/// <summary>
	/// 加载Excel
	/// </summary>
	private static void LoadExcel()
	{
		if(excelList==null) excelList=new List<string>();
		excelList.Clear();
		//获取选中的对象
		object[] selection=(object[])Selection.objects;
		//判断是否有对象被选中
		if(selection.Length==0)
			return;
		//遍历每一个对象判断不是Excel文件
		foreach(Object obj in selection)
		{
			string objPath=AssetDatabase.GetAssetPath(obj);
			if(objPath.EndsWith(".xlsx"))
			{
				excelList.Add(objPath);
			}
		}
	}

	private static void Init()
	{
		//获取当前实例
		instance=EditorWindow.GetWindow<ExcelTools>();
		//初始化
		pathRoot=Application.dataPath;
		//注意这里需要对路径进行处理
		//目的是去除Assets这部分字符以获取项目目录
		//我表示Windows的/符号一直没有搞懂
		pathRoot=pathRoot.Substring(0,pathRoot.LastIndexOf("/"));
		excelList=new List<string>();
		scrollPos=new Vector2(instance.position.x,instance.position.y+75);
	}

	void OnSelectionChange() 
	{
		//当选择发生变化时重绘窗体
		Show();
		LoadExcel();
		Repaint();
	}
}
ExcelUtility
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Excel;
using System.Data;
using System.IO;
using Newtonsoft.Json;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System;

public class ExcelUtility
{

	/// <summary>
	/// 表格数据集合
	/// </summary>
	private DataSet mResultSet;

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="excelFile">Excel file.</param>
	public ExcelUtility (string excelFile)
	{
		FileStream mStream = File.Open (excelFile, FileMode.Open, FileAccess.Read);
		IExcelDataReader mExcelReader = ExcelReaderFactory.CreateOpenXmlReader (mStream);
		mResultSet = mExcelReader.AsDataSet ();
	}
			
	/// <summary>
	/// 转换为实体类列表
	/// </summary>
	public List<T> ConvertToList<T> ()
	{
		//判断Excel文件中是否存在数据表
		if (mResultSet.Tables.Count < 1)
			return null;
		//默认读取第一个数据表
		DataTable mSheet = mResultSet.Tables [0];
			
		//判断数据表内是否存在数据
		if (mSheet.Rows.Count < 1)
			return null;

		//读取数据表行数和列数
		int rowCount = mSheet.Rows.Count;
		int colCount = mSheet.Columns.Count;
				
		//准备一个列表以保存全部数据
		List<T> list = new List<T> ();
				
		//读取数据
		for (int i=1; i<rowCount; i++) 
		{
			//创建实例
			Type t = typeof(T);
			ConstructorInfo ct = t.GetConstructor (System.Type.EmptyTypes);
			T target = (T)ct.Invoke (null);
			for (int j=0; j<colCount; j++) 
			{
				//读取第1行数据作为表头字段
				string field = mSheet.Rows [0] [j].ToString ();
				object value = mSheet.Rows [i] [j];
				//设置属性值
				SetTargetProperty (target, field, value);
			}
					
			//添加至列表
			list.Add (target);
		}
				
		return list;
	}

	/// <summary>
	/// 转换为Json
	/// </summary>
	/// <param name="JsonPath">Json文件路径</param>
	/// <param name="Header">表头行数</param>
	public void ConvertToJson (string JsonPath, Encoding encoding)
	{
		//判断Excel文件中是否存在数据表
		if (mResultSet.Tables.Count < 1)
			return;

		//默认读取第一个数据表
		DataTable mSheet = mResultSet.Tables [0];

		//判断数据表内是否存在数据
		if (mSheet.Rows.Count < 1)
			return;

		//读取数据表行数和列数
		int rowCount = mSheet.Rows.Count;
		int colCount = mSheet.Columns.Count;

		//准备一个列表存储整个表的数据
		List<Dictionary<string, object>> table = new List<Dictionary<string, object>> ();

		//读取数据
		for (int i = 1; i < rowCount; i++) {
			//准备一个字典存储每一行的数据
			Dictionary<string, object> row = new Dictionary<string, object> ();
			for (int j = 0; j < colCount; j++) {
				//读取第1行数据作为表头字段
				string field = mSheet.Rows [0] [j].ToString ();
				//Key-Value对应
				row [field] = mSheet.Rows [i] [j];
			}

			//添加到表数据中
			table.Add (row);
		}

		//生成Json字符串
		string json = JsonConvert.SerializeObject (table, Newtonsoft.Json.Formatting.Indented);


	    /*絮大王添加代码:去掉所有的反斜杠+支持数组*/
	    json = JsonSupportArray(json);


		//写入文件
		using (FileStream fileStream=new FileStream(JsonPath,FileMode.Create,FileAccess.Write)) {
			using (TextWriter textWriter = new StreamWriter(fileStream, encoding)) {
				textWriter.Write (json);
			}
		}
	}

	/// <summary>
	/// 转换为CSV
	/// </summary>
	public void ConvertToCSV (string CSVPath, Encoding encoding)
	{
		//判断Excel文件中是否存在数据表
		if (mResultSet.Tables.Count < 1)
			return;

		//默认读取第一个数据表
		DataTable mSheet = mResultSet.Tables [0];

		//判断数据表内是否存在数据
		if (mSheet.Rows.Count < 1)
			return;

		//读取数据表行数和列数
		int rowCount = mSheet.Rows.Count;
		int colCount = mSheet.Columns.Count;

		//创建一个StringBuilder存储数据
		StringBuilder stringBuilder = new StringBuilder ();

		//读取数据
		for (int i = 0; i < rowCount; i++) {
			for (int j = 0; j < colCount; j++) {
				//使用","分割每一个数值
				stringBuilder.Append (mSheet.Rows [i] [j] + ",");
			}
			//使用换行符分割每一行
			stringBuilder.Append ("\r\n");
		}

		//写入文件
		using (FileStream fileStream = new FileStream(CSVPath, FileMode.Create, FileAccess.Write)) {
			using (TextWriter textWriter = new StreamWriter(fileStream, encoding)) {
				textWriter.Write (stringBuilder.ToString ());
			}
		}

	}

	/// <summary>
	/// 导出为Xml
	/// </summary>
	public void ConvertToXml (string XmlFile)
	{
		//判断Excel文件中是否存在数据表
		if (mResultSet.Tables.Count < 1)
			return;

		//默认读取第一个数据表
		DataTable mSheet = mResultSet.Tables [0];

		//判断数据表内是否存在数据
		if (mSheet.Rows.Count < 1)
			return;

		//读取数据表行数和列数
		int rowCount = mSheet.Rows.Count;
		int colCount = mSheet.Columns.Count;

		//创建一个StringBuilder存储数据
		StringBuilder stringBuilder = new StringBuilder ();
		//创建Xml文件头
		stringBuilder.Append ("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
		stringBuilder.Append ("\r\n");
		//创建根节点
		stringBuilder.Append ("<Table>");
		stringBuilder.Append ("\r\n");
		//读取数据
		for (int i = 1; i < rowCount; i++) {
			//创建子节点
			stringBuilder.Append ("  <Row>");
			stringBuilder.Append ("\r\n");
			for (int j = 0; j < colCount; j++) {
				stringBuilder.Append ("   <" + mSheet.Rows [0] [j].ToString () + ">");
				stringBuilder.Append (mSheet.Rows [i] [j].ToString ());
				stringBuilder.Append ("</" + mSheet.Rows [0] [j].ToString () + ">");
				stringBuilder.Append ("\r\n");
			}
			//使用换行符分割每一行
			stringBuilder.Append ("  </Row>");
			stringBuilder.Append ("\r\n");
		}
		//闭合标签
		stringBuilder.Append ("</Table>");
		//写入文件
		using (FileStream fileStream = new FileStream(XmlFile, FileMode.Create, FileAccess.Write)) {
			using (TextWriter textWriter = new StreamWriter(fileStream,Encoding.GetEncoding("utf-8"))) {
				textWriter.Write (stringBuilder.ToString ());
			}
		}
	}

	/// <summary>
	/// 设置目标实例的属性
	/// </summary>
	private void SetTargetProperty (object target, string propertyName, object propertyValue)
	{
		//获取类型
		Type mType = target.GetType ();
		//获取属性集合
		PropertyInfo[] mPropertys = mType.GetProperties ();
		foreach (PropertyInfo property in mPropertys) {
			if (property.Name == propertyName) {
				property.SetValue (target, Convert.ChangeType (propertyValue, property.PropertyType), null);
			}
		}
	}

    /// <summary>
    /// 让Json支持数组
    /// 此方法是为了让Excel在转化成Json的时候,支持数组  (格式为["元素1","元素2"])
    /// * 为什么要这样做?
    ///   在源代码中,转化后的Json字符串是不支持数组的  (转化后,会变成这样:   "[\"元素1\",\"元素2\"]")
    /// * 此方法的做了什么?
    ///   把Json字符串传递过来,就会返回一个支持数组的Json字符串  (格式为["元素1","元素2"])
    /// </summary>
    /// <param name="jsonContent">json的文本内容</param>
    /// <returns></returns>
    private string JsonSupportArray(string jsonContent)
    {
        //去掉所有的反斜杠  (把"\"替换成"")
        jsonContent = jsonContent.Replace("\\", string.Empty);

        //为了能够支持数组,所以:
        //把所有的"[替换成[   
        //并且把所有的]"替换成]
        jsonContent = jsonContent.Replace("\"[", "[");
        jsonContent = jsonContent.Replace("]\"", "]");

        //把所有的".0" 替换成 ""
        //不然的话,"1"会显示为"1.0"
        jsonContent = jsonContent.Replace(".0,", ",");

        return jsonContent;
    }
}

使用流程

1.导入插件

导入Excel2Object.unitypackage

2.创建存储数据的Excel表格

IDNameHpDesc
1a10da
2b20db
3c30dc
4d40dd

后缀名必须是“.xlsx”

表格第一行为变量名

其后每一行都是一组数据

把表格导入Unity

这里创建的表格文件名为 HeroDataxml.xml

3.Unity中确定数据类

public class HeroData
{
    public int ID;
    public string Name;
    public int hp;
    public string Des;
}//变量名必须和表格第一行一致

4.在Unity中把Excel表格转换为Jason文件

在这里插入图片描述
在这里插入图片描述

转换生成同名Jason文件

5.Jason文件转换为Object

例如我们创建一个控制对象Hero1的脚本HeroDatactl

将HeroDatactl挂载到游戏物体Hero1上

然后在HeroDatactl中声明一个变量

public TextAsset json;//声明一个存放.txt的变量

在unity中指定他为转换好的json文件(把我们转换出的 Json 文件,直接拖到这个变量中)
在这里插入图片描述

public class HeroData : MonoBehaviour
{
    public TextAsset json;//声明一个存放.txt文件的变量

    // Start is called before the first frame update
    void Start()
    {
        //将一个jason文件转换为一个类型对象  
        //(一个HeroData类的对象,就是一条数据)
        List<HeroData> datas
            = JsonToObject.JsonToObject_ByJsonContent<HeroData>(json.text);
        
        //返回值为表格中的数据  
        
        //输出测试
        Debug.Log(datas[0].ID);
        Debug.Log(datas[2].Name);
    }
}
//将一个jason文件转换为一个类型对象  
JsonToObject.JsonToObject_ByJsonContent<HeroData>(json.text);
//<>要把表格中的数据,转换的什么类型的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值