文章目录
- 前言
- 一、读取Excel表格并生成代码模板
- 1.引入库
- 二、使用步骤
- 1.引入库
- 2.读入数据并生成模板代码(!注意一下,一开始写的时候没发现,要记得给管理类的list初始化啊!要不然反射的时候是null,找到它真是痛苦的经历)
- 3.读入数据到类中,并压缩保存
- 4.最后呢,再写一个解压和反序列化的方法就结束了
前言
提示:这里可以添加本文要记录的大概内容:
解析Excel表格,生成商品代码模板,压缩保存
项目中引用了ExcelDataReader,ProtoBuf,SharpZipLib,NPOI,zlib,以下为中文内容
一、读取Excel表格并生成代码模板
1.引入库
using NPOI.HSSF.UserModel;
using System;
using zlib;
using System.Data;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;二、使用步骤
1.引入库
代码如下(示例):
using ExcelDataReader;//读取Excel表
using ICSharpCode.SharpZipLib.Zip;//压缩
using ProtoBuf;//序列化2.读入数据并生成模板代码(!注意一下,一开始写的时候没发现,要记得给管理类的list初始化啊!要不然反射的时候是null,找到它真是痛苦的经历)
代码如下(代码会生成两类模板,一类会生成商品类Protect,一类会生成商品管理类StaticData):
private void CreateCode()
{
//Excel表所在的目录的路径
string path = Application.dataPath + "/EasyUI/ExcelFiles";
string[] filePaths = Directory.GetFiles(path,"*.xlsx",SearchOption.TopDirectoryOnly);
DataSet dataSet;
StringBuilder builder = new StringBuilder();
StringBuilder m_builder = new StringBuilder();
StringBuilder static_builder = new StringBuilder();
int protectIndex = 0;
int fileIndex = 0;
string mName = "StaticData";
try {
foreach(string filePath in filePaths)
{
FileInfo info = new FileInfo(filePath);
using (FileStream stream = info.OpenRead())
{
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream))
{
dataSet = excelReader.AsDataSet();
int col = dataSet.Tables[1].Columns.Count;
string className = dataSet.Tables[1].Rows[2][0].ToString();
builder.Append("using System.Collections;\n");
builder.Append("using System.Collections.Generic;\n");
builder.Append("using ProtoBuf;\n");
builder.Append("[ProtoContract]\n");
builder.Append("public class " + className + "\n");
builder.Append("{\n");
static_builder.Append("[ProtoMember(" + ++fileIndex + ")]\n");
static_builder.Append("public List<" + className + "> " + className + "List;\n");
for (int i = 0;i < col; i++)
{
protectIndex++;
builder.Append("[ProtoMember(" + protectIndex + ")]\n");
builder.Append("public " + dataSet.Tables[1].Rows[1][i].ToString() + " " + dataSet.Tables[1].Rows[0][i] + ";\n");
}
builder.Append("public " + className + "()\n");
builder.Append("{}\n");
builder.Append("}");
WriteFile(Application.dataPath + "/Script/" + className + ".cs", builder.ToString());
builder.Clear();
}
}
}
m_builder.Append("using System.Collections.Generic;\n");
m_builder.Append("using ProtoBuf;\n");
m_builder.Append("[ProtoContract]\n");
m_builder.Append("public class " + mName + "\n");
m_builder.Append("{\n");
m_builder.Append(static_builder.ToString());
m_builder.Append("public " + mName + "()\n");
m_builder.Append("{}\n");
m_builder.Append("}");
WriteFile(Application.dataPath + "/Script/" + mName + ".cs", m_builder.ToString());
m_builder.Clear();
}
catch(Exception e)
{
Debug.LogError(e.ToString());
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();下面是生成代码模板的效果图,有些粗糙就自己之后美化一下吧


3.读入数据到类中,并压缩保存
前面我们以及创建好了管理类和商品类,接下来就只需要读取Excel表创建商品类,存入管理类,在压缩保存就好了
public static void GenerateBinFile()
{
FileInfo info;
FileStream stream;
IExcelDataReader excelReader;
DataSet result;
string[] files = Directory.GetFiles(Application.dataPath + "/EasyUI/ExcelFiles", "*.xlsx", SearchOption.TopDirectoryOnly);
int row = 0, col = 0;
string name = "", value = "", type = "";
StaticData staticData = new StaticData();
foreach (string path in files)
{
info = new FileInfo(path);
stream = info.Open(FileMode.Open, FileAccess.Read);
excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
result = excelReader.AsDataSet();
int rowCount = result.Tables[0].Rows.Count;
int colCount = result.Tables[0].Columns.Count;
string className = result.Tables[1].Rows[2][0].ToString();
FieldInfo field = staticData.GetType().GetField(className + "List");//获取类中的一个Field
object fieldValue = field.GetValue(staticData);//给这个实例中的Field的代表的属性赋值
IList list = fieldValue as IList;
for (row = 1; row < rowCount; row++)
{
Type tt = DataManager.Instance.GetType(className);
object obj = System.Activator.CreateInstance(tt);
for (col = 0; col < colCount; col++)
{
name = result.Tables[1].Rows[0][col].ToString();
value = result.Tables[0].Rows[row][col].ToString();
type = result.Tables[1].Rows[1][col].ToString();
FieldInfo ifo = tt.GetField(name);
object cvalue = System.ComponentModel.TypeDescriptor.GetConverter(ifo.FieldType).ConvertFrom(value);
ifo.SetValue(obj, cvalue);
}
if (list != null)
list.Add(obj);
}
excelReader.Close();
stream.Close();
}
ZIPData(staticData);
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
}private static void ZIPTemp(StaticData staticData)
{
//直接使用protobuf来序列化输出到内存流中
MemoryStream ms = new MemoryStream();
Serializer.Serialize<StaticData>(ms, staticData);
byte[] bytes = ms.ToArray();
//压缩处理
using (ZipOutputStream zos = new ZipOutputStream(File.Create(Application.dataPath + "/Resources/StaticDatas1.zip")))
{
//压缩的力度
zos.SetLevel(6);
//将数组转换为流来读取写入文件
using (Stream stream = new MemoryStream(bytes))
{
byte[] buffer = new byte[4 * 1024];
//entry用于存储一些文件的信息,并不是存储数据
ZipEntry entry = new ZipEntry(Path.GetFileName("StaticDatas.byte"));
entry.DateTime = DateTime.Now;
zos.PutNextEntry(entry);
int sourceBytes;
do
{
sourceBytes = stream.Read(buffer, 0, buffer.Length);
zos.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
zos.CloseEntry();
}
}4.最后呢,再写一个解压和反序列化的方法就结束了
public bool Decompress(string sourceFile, string targetPath)
{
if (!File.Exists(sourceFile))
{
Debug.LogError("未找到源文件");
}
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourceFile)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directorName = Path.Combine(targetPath, Path.GetDirectoryName());
string fileName = Path.Combine(directorName, Path.GetFileName());
// 创建目录
if (directorName.Length > 0)
{
Directory.CreateDirectory(directorName);
}
if (fileName != string.Empty)
{
using (FileStream streamWriter = File.Create(fileName))
{
int size = 4096;
byte[] data = new byte[4 * 1024];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else break;
}
}
}
}
}
return true;
}//反序列化
public StaticData UnSerialize<T>(string path)
{
if (!File.Exists(path)) return null;
FileStream fs = new FileInfo(path).OpenRead();
object data = Serializer.Deserialize<T>(fs);
return data as StaticData;
}
















