目的是通过解析Excel动态生成类,所生成的类希望序列化而且继承ScriptObject
源代码:
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using NUnit.Framework;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
public class ExcelManager : MonoBehaviour
{
public List<string> _valType;
public List<string> _valName;
public string _className;
public Assembly _assembly;
public static StringBuilder _classSource;
public void ReadExcel(string path)
{
IWorkbook workbook = null;
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
if (path.IndexOf(".xlsx") > 0)
{
//2007版
workbook = new XSSFWorkbook(fileStream);
}
else if (path.IndexOf(".xls") > 0)
{
//2003版
workbook = new HSSFWorkbook(fileStream);
}
else
{
Debug.LogError("Invalid path.");
}
ISheet sheet = workbook.GetSheetAt(0);
_className = sheet.SheetName.Substring(1, sheet.SheetName.Length - 1);
IRow row;
for (int i = 0; i <= sheet.LastRowNum; ++i)
{
row = sheet.GetRow(i);
if (row != null)
{
//若该行首列内容以'#'开头,则为无效列
string tmp = row.GetCell(0).ToString();
if (tmp[0] == '#')
{
continue;
}
for (int j = 0; j < row.LastCellNum; ++j)
{
string cellValue = row.GetCell(j).ToString();
if (cellValue[0] == '&')
{
//内容以'&'开头则记录变量名和类型
int index = cellValue.IndexOf('|');
string tmpVarName = cellValue.Substring(1, index - 1);
tmpVarName.ToLower();
string tmpVarType = cellValue.Substring(index + 1, cellValue.Length - (index + 1));
tmpVarName.ToLower();
_valType.Add(tmpVarType);
_valName.Add(tmpVarName);
}
//---TODO---
//是否记录数据
}
}
}
fileStream.Close();
workbook.Close();
}
public void NewAssembly()
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false;
paras.GenerateInMemory = true;
paras.OutputAssembly = "Assets/Plugins" + _className + ".dll";
_classSource = GetClassSource();
CompilerResults result = provider.CompileAssemblyFromSource(paras, _classSource.ToString());
//验证编译错误
if (result.Errors.HasErrors)
{
foreach (var error in result.Errors)
{
_classSource.AppendLine(error.ToString());
}
//验证文本
FileStream fst = new FileStream("/Users/lijiesheng/Desktop/Error.txt", FileMode.Create);
byte[] data = System.Text.Encoding.Default.GetBytes(_classSource.ToString());
fst.Write(data, 0, data.Length);
fst.Flush();
fst.Close();
}
_assembly = result.CompiledAssembly;
}
public StringBuilder GetClassSource()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("using System;\n");
stringBuilder.Append("using UnityEngine;\n");
stringBuilder.Append("using System.Collections;\n");
stringBuilder.Append("using System.Collections.Generic;\n\n");
stringBuilder.Append("public class NewClass\n");
stringBuilder.Append("{\n");
stringBuilder.Append("\t[System.Serializable]\n");
stringBuilder.Append("\tpublic class " + _className + " : ScriptableObject\n");
stringBuilder.Append("\t{\n");
int len = _valType.Count;
for (int i = 0; i < len; ++i)
{
stringBuilder.Append("\t\tpublic " + _valType[i] + " " + _valName[i] + ";\n");
}
stringBuilder.Append("\t}\n");
stringBuilder.Append("\n\t[SerializeField]\n");
stringBuilder.Append("\tpublic List<" + _className + "> Fields;\n");
stringBuilder.Append("}\n");
return stringBuilder;
}
void Start()
{
ReadExcel("/Users/lijiesheng/Desktop/test.xlsx");
NewAssembly();
}
}
但是动态生成类的时候报错如下,打印到了文本里:
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class NewClass
{
[System.Serializable]
public class Field : ScriptableObject
{
public int VarName1;
public float VarName2;
public string VarName3;
public bool VarName4;
}
[SerializeField]
public List<Field> Fields;
}
/var/folders/19/xjrl577j315f2vjb0ddrl2h40000gn/T/26505f4c/65304a7e.0.cs(2,7) : error CS0246: The type or namespace name `UnityEngine' could not be found. Are you missing an assembly reference?
/var/folders/19/xjrl577j315f2vjb0ddrl2h40000gn/T/26505f4c/65304a7e.0.cs(9,23) : error CS0246: The type or namespace name `ScriptableObject' could not be found. Are you missing an assembly reference?
上面是我希望生成类的结构,下面是生成时候的报错信息,为什么解析不了UnityEngin,有没有上面解决办法
动态添加dll好像也不行:
parameters.ReferencedAssemblies.Add("UnityEngine.dll");
报错变成:error CS0006: Metadata file `UnityEngine.dll' could not be found