ExcelDataReader读取Excel
Contents
读取Excel文件
using (FileStream fs = File.Open(Application.dataPath + "/ArtRes/Excel/PlayerInfo.xlsx", FileMode.Open, FileAccess.Read ))
{
//通过文件流获取Excel数据
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
//将excel表中的数据转换为DataSet数据类型 方便我们 获取其中的内容
DataSet result = excelReader.AsDataSet();
//得到Excel文件中的所有表信息
for (int i = 0; i < result.Tables.Count; i++)
{
Debug.Log("表名:" + result.Tables[i].TableName);
Debug.Log("行数:" + result.Tables[i].Rows.Count);
Debug.Log("列数:" + result.Tables[i].Columns.Count);
}
fs.Close();
}获取Excel表中单元格的信息
DataSet result = excelReader.AsDataSet();
for (int i = 0; i < result.Tables.Count; i++)
{
//得到其中一张表的具体数据
DataTable table = result.Tables[i];
//得到其中一行的数据
DataRow row = table.Rows[0];
//得到行中某一列的信息
Debug.Log(row[1].ToString());
}Excel数据持久化类
using Excel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
public class ExcelTool
{
/// <summary>
/// excel文件存放的路径
/// </summary>
public static string EXCEL_PATH = Application.dataPath + "/ArtRes/Excel/";
/// <summary>
/// 数据结构类脚本存储位置路径
/// </summary>
public static string DATA_CLASS_PATH = Application.dataPath + "/Scripts/ExcelData/DataClass/";
/// <summary>
/// 容器类脚本存储位置路径
/// </summary>
public static string DATA_CONTAINER_PATH = Application.dataPath + "/Scripts/ExcelData/Container/";
/// <summary>
/// 2进制数据存储位置路径
/// </summary>
public static string DATA_BINARY_PATH = Application.streamingAssetsPath + "/Binary/";
/// <summary>
/// 真正内容开始的行号
/// </summary>
public static int BEGIN_INDEX = 4;
[MenuItem("GameTool/GenerateExcel")]
private static void GenerateExcelInfo()
{
//记在指定路径中的所有Excel文件 用于生成对应的3个文件
DirectoryInfo dInfo = Directory.CreateDirectory(EXCEL_PATH);
//得到指定路径中的所有文件信息 相当于就是得到所有的Excel表
FileInfo[] files = dInfo.GetFiles();
//数据表容器
DataTableCollection tableConllection;
for (int i = 0; i < files.Length; i++)
{
//如果不是excel文件就不要处理了
if (files[i].Extension != ".xlsx" &&
files[i].Extension != ".xls")
continue;
//打开一个Excel文件得到其中的所有表的数据
using (FileStream fs = files[i].Open(FileMode.Open, FileAccess.Read))
{
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
tableConllection = excelReader.AsDataSet().Tables;
fs.Close();
}
//遍历文件中的所有表的信息
foreach (DataTable table in tableConllection)
{
Debug.Log(table.TableName);
//生成数据结构类
GenerateExcelDataClass(table);
//生成容器类
GenerateExcelContainer(table);
//生成2进制数据
GenerateExcelBinary(table);
}
}
}
/// <summary>
/// 生成Excel表对应的数据结构类
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelDataClass(DataTable table)
{
//字段名行
DataRow rowName = GetVariableNameRow(table);
//字段类型行
DataRow rowType = GetVariableTypeRow(table);
//判断路径是否存在 没有的话 就创建文件夹
if (!Directory.Exists(DATA_CLASS_PATH))
Directory.CreateDirectory(DATA_CLASS_PATH);
//如果我们要生成对应的数据结构类脚本 其实就是通过代码进行字符串拼接 然后存进文件就行了
string str = "public class " + table.TableName + "\n{\n";
//变量进行字符串拼接
for (int i = 0; i < table.Columns.Count; i++)
{
str += " public " + rowType[i].ToString() + " " + rowName[i].ToString() + ";\n";
}
str += "}";
//把拼接好的字符串存到指定文件中去
File.WriteAllText(DATA_CLASS_PATH + table.TableName + ".cs", str);
//刷新Project窗口
AssetDatabase.Refresh();
}
/// <summary>
/// 生成Excel表对应的数据容器类
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelContainer(DataTable table)
{
//得到主键索引
int keyIndex = GetKeyIndex(table);
//得到字段类型行
DataRow rowType = GetVariableTypeRow(table);
//没有路径创建路径
if (!Directory.Exists(DATA_CONTAINER_PATH))
Directory.CreateDirectory(DATA_CONTAINER_PATH);
string str = "using System.Collections.Generic;\n";
str += "public class " + table.TableName + "Container" + "\n{\n";
str += " ";
str += "public Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">";
str += "dataDic = new " + "Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">();\n";
str += "}";
File.WriteAllText(DATA_CONTAINER_PATH + table.TableName + "Container.cs", str);
//刷新Project窗口
AssetDatabase.Refresh();
}
/// <summary>
/// 生成excel2进制数据
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelBinary(DataTable table)
{
//没有路径创建路径
if (!Directory.Exists(DATA_BINARY_PATH))
Directory.CreateDirectory(DATA_BINARY_PATH);
//创建一个2进制文件进行写入
using (FileStream fs = new FileStream(DATA_BINARY_PATH + table.TableName + ".tang", FileMode.OpenOrCreate, FileAccess.Write))
{
//存储具体的excel对应的2进制信息
//1.先要存储我们需要写多少行的数据 方便我们读取
//-4的原因是因为 前面4行是配置规则 并不是我们需要记录的数据内容
fs.Write(BitConverter.GetBytes(table.Rows.Count - 4), 0, 4);
//2.存储主键的变量名
string keyName = GetVariableNameRow(table)[GetKeyIndex(table)].ToString();
byte[] bytes = Encoding.UTF8.GetBytes(keyName);
//存储字符串字节数组的长度
fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
//存储字符串字节数组
fs.Write(bytes, 0, bytes.Length);
//遍历所有内容的行 进行2进制的写入
DataRow row;
//得到类型行 根据类型来决定应该如何写入数据
DataRow rowType = GetVariableTypeRow(table);
for (int i = BEGIN_INDEX; i < table.Rows.Count; i++)
{
//得到一行的数据
row = table.Rows[i];
for (int j = 0; j < table.Columns.Count; j++)
{
switch (rowType[j].ToString())
{
case "int":
fs.Write(BitConverter.GetBytes(int.Parse(row[j].ToString())), 0, 4);
break;
case "float":
fs.Write(BitConverter.GetBytes(float.Parse(row[j].ToString())), 0, 4);
break;
case "bool":
fs.Write(BitConverter.GetBytes(bool.Parse(row[j].ToString())), 0, 1);
break;
case "string":
bytes = Encoding.UTF8.GetBytes(row[j].ToString());
//写入字符串字节数组的长度
fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
//写入字符串字节数组
fs.Write(bytes, 0, bytes.Length);
break;
}
}
}
fs.Close();
}
AssetDatabase.Refresh();
}
/// <summary>
/// 获取变量名所在行
/// </summary>
/// <param name="table"></param>
/// <returns></returns>
private static DataRow GetVariableNameRow(DataTable table)
{
return table.Rows[0];
}
/// <summary>
/// 获取变量类型所在行
/// </summary>
/// <param name="table"></param>
/// <returns></returns>
private static DataRow GetVariableTypeRow(DataTable table)
{
return table.Rows[1];
}
/// <summary>
/// 获取主键索引
/// </summary>
/// <param name="table"></param>
/// <returns></returns>
private static int GetKeyIndex(DataTable table)
{
DataRow row = table.Rows[2];
for (int i = 0; i < table.Columns.Count; i++)
{
if (row[i].ToString() == "key")
return i;
}
return 0;
}
}