类与Excel转换原理

类和Excel想要映射,需要一个reg.xml来做中转。

一个中转reg.xml文件示例(注意图中的Foreign拼错了):

中转后的xml

  1. rootNode命名为“data”,它有三个Attribute
    1. name:rootNode对应的类。
    2. from:此reg映射的Excel
    3. to:此reg映射的xml
  2. 普通的Node命名为“variable”,它根据需要有多种Attribute
    1. name:必须要有,对应变量名
    2. col:在Excel中的列名
    3. type:此变量的类型,除了常见的几种类型,还有一些针对list的特殊的类型,见下面的Reg注意事项
    4. defaultValue:此变量的默认值,在Excel转xml的时候使用
    5. foreign:如果此“variable”的type是list,那么就有此Attribute,代表的是此变量对应的列表sheet上一层是什么主键,一般就是Excel里面的“ID”
    6. split:如果此“variable”的type是list,那么就有此Attribute,代表的是在同一个sheet显示时的分割方式,避免使用多个sheet
  3. 集合性质的Node命名为“list”,它也有多种Attribute
    1. list这种Node一般跟在type是list的“variable”后面,一个list可以设置sheetname,用来指示此list应用的新sheet名,如果不想创建新的sheet,可以通过后面的split指示的分割符让list的内容可以在同一个sheet显示。
    2. name:list容纳的类名
    3. mainKey:通过这个Attribute指定列表的主键,注意指定的是变量名,用来指示子sheet的填充在“Foreign”行内容。具体应用见“Xml转Excel”拓展。
    4. sheetname:此list对应得sheet名
    5. split:此list元素分割符号,用于在同一个sheet里显示,避免使用多个sheet

此中转xml对应的Excel示例:

BuffExcel

基本原理图示

基本原理

不论是从类转Excel还是Excel转类,都有一个读取reg.xml文件的过程。

Reg表注意事项

注意事项

编写reg文件

我们将之前的MonsterData的reg映射写出来。

我们在Unity工程文件目录下(Assets的父目录)新建Data文件夹,并在其中新建Reg文件夹和Excel文件夹。

在Reg文件夹中新建MonsterDataReg.xml(reg文件的命名无所谓,但是推荐统一的命名)。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<data name="MonsterData" from="Monster.xlsx" to="MonsterData.xml">
<variable name="AllMonster" type="list">
<list name="MonsterBase" sheetname="怪物配置" mainKey="Id">
<variable name="Id" col="ID" type="int"></variable>
<variable name="Name" col="名字" type="string"></variable>
<variable name="OutLook" col="Prefab路径" type="string"></variable>
<variable name="Level" col="等级" type="int"></variable>
<variable name="Rarity" col="稀有度" type="int"></variable>
<variable name="Height" col="高度" type="float"></variable>
</list>
</variable>
</data>

测试xml读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
[MenuItem("Tools/测试Xml读取")]
public static void TestReadXml()
{
string xmlPath = Application.dataPath + "/../" + "Data/Reg/MonsterDataReg.xml";
XmlReader xmlReader = null;
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlReader = XmlReader.Create(xmlPath);
xmlDocument.Load(xmlReader);

XmlNode rootNode = xmlDocument.SelectSingleNode("data");
XmlElement rootElement = rootNode as XmlElement;
string className = rootElement.GetAttribute("name");
string excelName = rootElement.GetAttribute("form");
string xmlName = rootElement.GetAttribute("to");
xmlReader.Close();
Debug.Log(className + " " + excelName + " " +xmlName);

foreach (XmlElement mainVarElement in rootNode.ChildNodes)
{
string varName = mainVarElement.GetAttribute("name");
string varType = mainVarElement.GetAttribute("type");
Debug.Log(varName + " " + varType);

//if(varType == "list"){}
XmlNode listNode = mainVarElement.FirstChild;
XmlElement listElement = listNode as XmlElement;
string listType = listElement.GetAttribute("name");
string listSheetName = listElement.GetAttribute("sheetname");
string listMainKey = listElement.GetAttribute("mainKey");
Debug.Log("list: " + listType + " " + listSheetName + " " +listMainKey);

foreach (XmlElement listChildEle in listNode.ChildNodes)
{
Debug.Log(listChildEle.GetAttribute("name") + " "
+ listChildEle.GetAttribute("col") + " "
+ listChildEle.GetAttribute("type"));
}


}
}
catch (Exception e)
{

if (xmlReader != null)
{
xmlReader.Close();
}
}
}

Epplus使用示例

将Epplus.dll插件放在Assets——Plugins——Editor文件夹里,并将它的Platform限定在Editor里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[MenuItem("Tools/测试Excecl写入")]
public static void TestWriteExcel()
{
string excelPath = Application.dataPath + "/../" + "Data/Excel/Monster.xlsx";
FileInfo xlsxFile = new FileInfo(excelPath);
if(File.Exists(excelPath) )
{
File.Delete(excelPath );
xlsxFile = new FileInfo (excelPath);
using (ExcelPackage package = new ExcelPackage(xlsxFile))
{
ExcelWorksheet excelWorksheet = package.Workbook.Worksheets.Add("怪物配置");

excelWorksheet.DefaultColWidth = 10;//设置工作簿默认宽度
excelWorksheet.DefaultRowHeight = 10;//设置工作簿默认高度
excelWorksheet.Cells.AutoFitColumns();//设置所有单元格自动换行
excelWorksheet.InsertColumn(4, 1, 1);//插入列,第一个参数表示从第几列开始插入,第二个参数表示插入几个,第三个参数表示复制第几列的Style。
excelWorksheet.InsertRow(4, 1, 1);//插入行,参数同上
excelWorksheet.DeleteColumn(4, 1);//删除列,第一个参数表示从第几列开始删除,第二个参数表示删除几个
excelWorksheet.DeleteRow(4, 1);//删除行,参数同上
excelWorksheet.Column(2).Width = 10;//单独设置某一列的宽度
excelWorksheet.Row(2).Height = 10;//单独设置某一行的高度
excelWorksheet.Column(2).Hidden = true;//设置某一列是否隐藏
excelWorksheet.Row(2).Hidden = true;//设置某一行是否隐藏
excelWorksheet.Column(3).Style.Locked = true;//设置某一列是否锁定
excelWorksheet.Row(3).Style.Locked = true;//设置某一行是否锁定
excelWorksheet.TabColor = System.Drawing.Color.White;//设置工作簿选项卡的颜色
excelWorksheet.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;//设置所有单元格对齐方式
excelWorksheet.Cells.AutoFitColumns();//设置所有单元格的自适应宽度,注意单元格的内容需要换行的话需要单独设置


ExcelRange range = excelWorksheet.Cells[1, 1];//单元格从1开始,不是从0开始
range.Value = "happpppppy\n huhuhuhuhuh";

range.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.DarkGrid;//单元格的背景样式
range.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.White);//单元格背景颜色
range.Style.Font.Color.SetColor(System.Drawing.Color.Black);//单元格文字颜色
range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;//设置单元格对齐方式
range.AutoFitColumns();//列的长度自动适应Value
range.Style.WrapText = true;//如果Value里面需要换行,先调用range.AutoFitColumns();再调用这个,否则range.AutoFitColumns();会失效
package.Save();
}
}
}