文章目录
- 一、Epplus 使用
- 二、ExcelWriter
- (一)文件结构
- (二)操作说明
- (三)操作示例
- (四)完整代码
一、Epplus 使用
(一)获取 Excel 文件
string filePath = Application.dataPath + "/目标名称.xlsx"; // 这里是文件路径
FileInfo fileInfo = new FileInfo(filePath); // 获取 Excel 文件的信息,文件中没有这个文件不会报错
(二)打开 Excel 文件
// 打开 Excel
using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)) {
...
}
(三)打开 / 创建 Excel 文件的某个表格
using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)) {
// 取得 Excel 文件中的第 1 张表
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
// 取得 Excel 文件中名为 Sheet1 的表格
ExcelWorksheet worksheet1 = excelPackage.Workbook.Worksheets["Sheet1"];
// 在新 Excel 文件中创建叫 Sheet2 的表格
ExcelWorksheet worksheet2 = excelPackage.Workbook.Worksheets.Add("Sheet2");
}
(四)读写数据
using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)) {
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
for (int i = worksheet.Dimension.Start.Row; i < worksheet.Dimension.End.Row; i++) { // 从有内容的最小行数开始,到最大行数结束
// Cells 是二维数组,第一个参数是读取第几行,第二个参数是读取第几列,需要 ToString 出数据
// Cells 的索引从 1 开始!!!
// 读取数据
string s = worksheet.Cells[i, 1].Value.ToString();
...
// 写入数据
worksheet.Cells[i, 2].Value = "xxx";
...
excelPackage.Save(); // 写入后保存表格
}
}
(五)小结
操作 | 代码 |
---|---|
获得 Excel 文件 | ExcelPackage excelPackage = new ExcelPackage(fileInfo); |
获取 Excel 文件的某个表格 | ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1]; ExcelWorksheet worksheet1 = excelPackage.Workbook.Worksheets["Sheet1"]; |
获得当前表格数目 | int i = excelPackage.Workbook.Worksheets.Count; |
表格中最大行和列 | int row = worksheet.Dimension.End.Row; int column = worksheet.Dimension.End.Column; |
添加一张表格 | ExcelWorksheet worksheet2 = excelPackage.Workbook.Worksheets.Add("Sheet2"); |
获得表格中第 i 行 j 列的内容 | worksheet.Cells[i, j].Value.ToString(); |
保存修改后的 Excel 文件 | excelPackage.Save(); |
二、ExcelWriter
(一)文件结构
类型 | 名称 | 说明 |
---|---|---|
enum | Orientation | 写入方向,垂直 or 水平 |
string | FILE_DIRECTORY | 存储 Excel 的文件夹位置 |
string | FILE_SUFFIX | 文件后缀名,默认为 .xlsx |
ExcelWriter | Instance | 单例模式实例化对象 |
function | string GetDirectory(string fileName) | 获取文件名所在的目录,非外部提供的 API |
function | void SetValue<T>(string fileName, string sheetName, int row, int column, T value) where T : struct void SetValue(string fileName, string sheetName, int row, int column, string value) | 写入单个数据,目前只支持值类型数据和字符串 |
function | void SetList<T>(string fileName, string sheetName, int row, int column, List<T> value, Orientation orientation) where T : struct void SetList(string fileName, string sheetName, int row, int column, List<string> value, Orientation orientation) | 写入列表数据,列表成员只支持值类型数据和字符串,可选垂直写入或竖直写入 |
function | void SetMemberList<T>(string fileName, string sheetName, int row, int column, List<T> value) where T : class | 写入多个自定义数据 T,T 的成员只支持值类型数据和字符串。横向排布 T 的数据内容,纵向排布 T 个数 |
function | void SetMemberDic<T, K>(string fileName, string sheetName, int row, int column, Dictionary<T, K> value) where T : struct where K : class void SetMemberDic<K>(string fileName, string sheetName, int row, int column, Dictionary<string, K> value) where K : class | 写入多个自定义数据 T,T 的成员只支持值类型数据和字符串。横向排布 T 的数据内容,纵向排布 T 个数。左侧会多加一列键 |
(二)操作说明
-
参数 fileName 命名规则为
"xxx/xxx/xxx"
或xxx
,寻找文件位置的规则为FILE_DIRECTORY + fileName + FILE_SUFFIX
。例如: FILE_DIRECTORY = “C:\Data\”;
fileName = “你好”;
FILE_SUFFIX = “.xlsx”;
则最终文件名为
"C:\Data\你好.xlsx"
。 -
sheetName 为 fileName 文件中的表名。若 sheetName 或 fileName 不存在,则会自动创建文件或表名;若已存在,则会打开已有文件进行写入。
-
初始化相关操作可在函数
private ExcelWriter() { }
中填写。 -
自定义内容仅支持公共变量,若需要写入私有变量,修改对应函数中的以下代码即可:
FieldInfo[] fieldInfos = type.GetFields();
(三)操作示例
以下操作中,FILE_DIRECTORY = Application.dataPath + "/Excel/";
(一)写入单个内容
向 haha.xlsx 文件的 sheet!! 表中第 1 行第 2 列写入内容 “瓜”,第 2 行第 1 列写入内容 “呆瓜”:
ExcelWriter.Instance.SetValue("haha", "sheet!!", 1, 2, "瓜");
ExcelWriter.Instance.SetValue("haha", "sheet!!", 2, 1, "呆瓜");
执行后会创建文件 haha.xlsx 并生成表 sheet!!。
(二)写入一行内容(列表)
向 shabi2.xlsx 文件的 ei 表中以第 2 行第 2 列为起始位置水平写入列表内容:
List<string> ls = new List<string>() { "aa", "bb", "cc", "dd" };
ExcelWriter.Instance.SetList("shabi2", "ei", 2, 2, ls, ExcelWriter.Orientation.Horizontal);
(三)写入自定义数据(表格)
自定义数据结构:
public class Man
{
public int id;
public string name;
public int age;
public float height;
public bool sex;
public Man(int id, string name, int age, float height, bool sex) {
this.id = id;
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
}
}
List<Man> lm = new List<Man>() {
new Man(1, "daidai", 23, 175.2f, true),
new Man(2, "dai", 53, 165.2f, true),
new Man(3, "daid", 25, 173.4f, false),
new Man(4, "d", 26, 176.2f, true),
new Man(5, "daida", 27, 175.2f, false),
new Man(6, "da", 43, 179.2f, true),
};
Dictionary<int, Man> dm = new Dictionary<int, Man>();
for (int i = 0; i < 6; i++) {
dm[i] = lm[i];
}
向 shabi2.xlsx 文件的 aasd 表中以第 4 行第 2 列为起始位置写入自定义列表内容:
ExcelWriter.Instance.SetMemberList<Man>("shabi2", "aasd", 4, 2, lm);
向 dashabi 目录下 aha.xlsx 文件的 aasd 表中以第 4 行第 2 列为起始位置写入自定义字典内容:
ExcelWriter.Instance.SetMemberDic<int, Man>("dashabi/aha", "aasd", 4, 2, dm);
(四)完整代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using OfficeOpenXml;
using UnityEditor;
using UnityEngine;
/// <summary>
/// Excel 文件写入器
/// </summary>
public class ExcelWriter
{
/// <summary>
/// 写入方向
/// </summary>
public enum Orientation
{
Horizontal, // 水平写入
Vertical // 竖直写入
}
/// <summary>
/// 存储 Excel 的文件夹位置
/// </summary>
private static readonly string FILE_DIRECTORY = Application.dataPath + "/Excel/";
/// <summary>
/// 文件后缀名,默认为 .xlsx
/// </summary>
private static readonly string FILE_SUFFIX = ".xlsx";
public static ExcelWriter Instance { get; set; } = new ExcelWriter();
private ExcelWriter() { }
/// <summary>
/// 获取文件名所在的目录
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private string GetDirectory(string fileName) {
int index = fileName.LastIndexOf('/');
if (index == -1) {
return "";
}
return fileName.Substring(0, index);
}
/// <summary>
/// 写入 Excel 数据
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入值</param>
public void SetValue<T>(string fileName, string sheetName, int row, int column, T value) where T : struct {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
currentSheet.Cells[row, column].Value = value.ToString(); // 设值
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 数据
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入值</param>
public void SetValue(string fileName, string sheetName, int row, int column, string value) {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
currentSheet.Cells[row, column].Value = value; // 设值
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 一行数组数据
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入数组</param>
/// <param name="orientation">写入方向</param>
public void SetList<T>(string fileName, string sheetName, int row, int column, List<T> value, Orientation orientation) where T : struct {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
// 写入数组
for (int i = 0; i < value.Count; i++) {
switch (orientation) {
case Orientation.Horizontal:
currentSheet.Cells[row, column + i].Value = value[i].ToString();
break;
case Orientation.Vertical:
currentSheet.Cells[row + i, column].Value = value[i].ToString();
break;
}
}
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 一行数组数据
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入数组</param>
/// <param name="orientation">写入方向</param>
public void SetList(string fileName, string sheetName, int row, int column, List<string> value, Orientation orientation) {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
// 写入数组
for (int i = 0; i < value.Count; i++) {
switch (orientation) {
case Orientation.Horizontal:
currentSheet.Cells[row, column + i].Value = value[i];
break;
case Orientation.Vertical:
currentSheet.Cells[row + i, column].Value = value[i];
break;
}
}
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 成员数据,水平为成员字段,竖直为成员数
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入值</param>
public void SetMemberList<T>(string fileName, string sheetName, int row, int column, List<T> value) where T : class {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
Type type = typeof(T);
FieldInfo[] fieldInfos = type.GetFields();
// 写入字段名称
for (int i = 0; i < fieldInfos.Length; i++) {
currentSheet.Cells[row, column + i].Value = fieldInfos[i].Name;
}
// 写入数据
for (int i = 0; i < value.Count; i++) {
for (int j = 0; j < fieldInfos.Length; j++) {
currentSheet.Cells[row + i + 1, column + j].Value = fieldInfos[j].GetValue(value[i]).ToString();
}
}
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 成员数据,水平为成员字段,竖直为成员数
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入值</param>
public void SetMemberDic<T, K>(string fileName, string sheetName, int row, int column, Dictionary<T, K> value) where T : struct where K : class {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
Type typeT = typeof(T);
Type typeK = typeof(K);
FieldInfo[] fieldInfos = typeK.GetFields();
// 写入字段名称
currentSheet.Cells[row, column].Value = typeT.Name;
for (int i = 0; i < fieldInfos.Length; i++) {
currentSheet.Cells[row, column + i + 1].Value = fieldInfos[i].Name;
}
// 写入数据
int index = 0;
foreach (KeyValuePair<T, K> pair in value) {
currentSheet.Cells[row + index + 1, column].Value = pair.Key.ToString();
for (int j = 0; j < fieldInfos.Length; j++) {
currentSheet.Cells[row + index + 1, column + j + 1].Value = fieldInfos[j].GetValue(pair.Value).ToString();
}
index++;
}
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
/// <summary>
/// 写入 Excel 成员数据,水平为成员字段,竖直为成员数
/// </summary>
/// <param name="fileName">Excel 文件名</param>
/// <param name="sheetName">Excel 表名</param>
/// <param name="row">行号(从 1 开始)</param>
/// <param name="column">列号(从 1 开始)</param>
/// <param name="value">写入值</param>
public void SetMemberDic<K>(string fileName, string sheetName, int row, int column, Dictionary<string, K> value) where K : class {
string path = FILE_DIRECTORY + fileName + FILE_SUFFIX; // 文件路径
string dir = FILE_DIRECTORY + GetDirectory(fileName);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
FileInfo fileInfo = new FileInfo(path); // 获取文件信息
// 打开 Excel,不存在不会创建
using (ExcelPackage package = new ExcelPackage(fileInfo)) {
ExcelWorksheets worksheets = package.Workbook.Worksheets; // 获取所有表格
// 寻找是否有对应名字的表格
ExcelWorksheet currentSheet = null;
foreach (ExcelWorksheet worksheet in worksheets) {
if (worksheet.Name == sheetName) {
currentSheet = worksheet;
break;
}
}
if (currentSheet == null) {
currentSheet = worksheets.Add(sheetName); // 不存在,则会创建表;如果 Excel 不存在,也会一并创建
}
Type typeK = typeof(K);
FieldInfo[] fieldInfos = typeK.GetFields();
// 写入字段名称
currentSheet.Cells[row, column].Value = "string";
for (int i = 0; i < fieldInfos.Length; i++) {
currentSheet.Cells[row, column + i + 1].Value = fieldInfos[i].Name;
}
// 写入数据
int index = 0;
foreach (KeyValuePair<string, K> pair in value) {
currentSheet.Cells[row + index + 1, column].Value = pair.Key;
for (int j = 0; j < fieldInfos.Length; j++) {
currentSheet.Cells[row + index + 1, column + j + 1].Value = fieldInfos[j].GetValue(pair.Value).ToString();
}
index++;
}
package.Save(); // 保存
}
AssetDatabase.Refresh();
}
}