2023-05-30 Unity 2进制6——Excel写入器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
(一)文件结构
image-20230530040306303
类型名称说明
enumOrientation写入方向,垂直 or 水平
stringFILE_DIRECTORY存储 Excel 的文件夹位置
stringFILE_SUFFIX文件后缀名,默认为 .xlsx
ExcelWriterInstance单例模式实例化对象
functionstring GetDirectory(string fileName)获取文件名所在的目录,非外部提供的 API
functionvoid 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)
写入单个数据,目前只支持值类型数据和字符串
functionvoid 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)
写入列表数据,列表成员只支持值类型数据和字符串,可选垂直写入或竖直写入
functionvoid SetMemberList<T>(string fileName, string sheetName, int row, int column, List<T> value) where T : class写入多个自定义数据 T,T 的成员只支持值类型数据和字符串。横向排布 T 的数据内容,纵向排布 T 个数
functionvoid 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!!。

image-20230529162813934 image-20230529162940956

(二)写入一行内容(列表)

​ 向 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);
image-20230529163212105 image-20230529163232176

(三)写入自定义数据(表格)

​ 自定义数据结构:

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);
image-20230529164743204

​ 向 dashabi 目录下 aha.xlsx 文件的 aasd 表中以第 4 行第 2 列为起始位置写入自定义字典内容:

ExcelWriter.Instance.SetMemberDic<int, Man>("dashabi/aha", "aasd", 4, 2, dm);
image-20230529164929220
(四)完整代码
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();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔗理苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值