[Unity] 利用WinForm制作一个Excel转Bytes/Json以及C#的窗口小工具

今天分享一个用于将Excel表格的数据序列化为bytes和json文件,以及提供一个数据管理的C#脚本的窗口程序小工具,脚本中用反射进行反序列化(所以性能不是特别好,有待优化),界面如下:

处理后得到以下示例文件:

项目地址:https://gitee.com/fanguounicorn/excel-handler.git

ExcelHandler.cs

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using OfficeOpenXml;

namespace ExcelHandler
{
    public partial class ExcelHandler : Form
    {
        public ExcelHandler()
        {
            InitializeComponent();
        }

        public string offlinePath = "Path.txt";
        /// <summary>
        /// 获取上一次路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Init(object sender, EventArgs e)
        {
            if (File.Exists(offlinePath))
            {
                string[] paths = File.ReadAllLines(offlinePath);
                if(paths.Length < 3)
                {
                    return;
                }
                ExcelInputPath.Text = paths[0];
                BytesOutputPath.Text = paths[1];
                CSOutputPath.Text = paths[2];
            }
        }

        /// <summary>
        /// 存储本次路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Close(object sender, FormClosedEventArgs e)
        {
            using (StreamWriter writer = new StreamWriter(offlinePath))
            {
                writer.WriteLine(ExcelInputPath.Text);
                writer.WriteLine(BytesOutputPath.Text);
                writer.WriteLine(CSOutputPath.Text);
                writer.Close();
            }
        }

        /// <summary>
        /// 选择Excel读取路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectExcelPath(object sender, EventArgs e)
        {
            ExcelInputPath.Text = OpenDirectoryPath();
        }

        /// <summary>
        /// 选择Bytes保存路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectBytesPath(object sender, EventArgs e)
        {
            BytesOutputPath.Text = OpenDirectoryPath();
        }

        /// <summary>
        /// 选择Csharp保存路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectCSPath(object sender, EventArgs e)
        {
            CSOutputPath.Text = OpenDirectoryPath();
        }

        /// <summary>
        /// 打开文件管理器选择路径
        /// </summary>
        /// <returns></returns>
        public string OpenDirectoryPath()
        {
            // 创建一个 FolderBrowserDialog 对象
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();

            // 设置对话框的属性
            folderBrowserDialog.Description = "请选择文件夹"; // 设置对话框描述信息
            folderBrowserDialog.RootFolder = Environment.SpecialFolder.Desktop; // 设置根文件夹

            // 显示文件夹对话框
            DialogResult result = folderBrowserDialog.ShowDialog();


            // 处理对话框返回的结果
            if (result == DialogResult.OK)
            {
                // 获取所选文件的路径
                return folderBrowserDialog.SelectedPath;
            }
            return null;
        }
        
        /// <summary>
        /// 更新处理结果
        /// </summary>
        /// <param name="text"></param>
        public void UpdateProgress(string text)
        {
            SolvingProgress.AppendText(text + Environment.NewLine);

            // 滚动到最后一行
            SolvingProgress.SelectionStart = SolvingProgress.TextLength;
            SolvingProgress.ScrollToCaret();
        }

        /// <summary>
        /// 清空结果
        /// </summary>
        public void ClearProgress()
        {
            SolvingProgress.Clear();
        }

        private bool isSolving = false;

        private void StartSolve(object sender, EventArgs e)
        {
            if (isSolving)
            {
                //如果正在处理则返回
                return;
            }
            ClearProgress();
            string excelPath = ExcelInputPath.Text;
            string bytesPath = BytesOutputPath.Text;
            string csPath = CSOutputPath.Text;
            if(string.IsNullOrEmpty(excelPath) || Directory.Exists(excelPath) == false)
            {
                MessageBox.Show("请输入有效的Excel路径!");
                return;
            }
            if (string.IsNullOrEmpty(bytesPath))
            {
                MessageBox.Show("请输入Bytes路径!");
                return;
            }
            if (string.IsNullOrEmpty(csPath))
            {
                MessageBox.Show("请输入CS路径!");
                return;
            }
            int solveCount = 0;
            isSolving = true;
            SolvingTip.Text = "正在处理,请稍后...";
            string[] paths = Directory.GetFiles(excelPath, "*.xlsx", SearchOption.AllDirectories);
            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
            foreach (string path in paths)
            {
                try
                {
                    using (ExcelPackage package = new ExcelPackage(new FileInfo(path)))
                    {
                        int sheetCount = package.Workbook.Worksheets.Count;
                        for(int i = 0; i < sheetCount; i++)
                        {
                            ExcelWorksheet worksheet = package.Workbook.Worksheets[i];
                            
                            string sheetName = worksheet.Name;
                            int rowCount = worksheet.Dimension.Rows;
                            int colCount = worksheet.Dimension.Columns;
                            if(rowCount <= 3)
                            {
                                UpdateProgress(sheetName + "表格数据有误,路径:" + path);
                                continue;
                            }
                            UpdateProgress("正在处理" + sheetName + "表格,路径:" + path);
                            List<List<string>> datas = new List<List<string>>();
                            for(int r = 4; r <= rowCount; r++)
                            {
                                List<string> data = new List<string>();
                                for(int c = 1; c <= colCount; c++)
                                {
                                    data.Add(worksheet.Cells[r, c].Text);
                                }
                                datas.Add(data);
                            }
                            //创建Json和Bytes数据文件
                            if(Directory.Exists(bytesPath) == false)
                            {
                                Directory.CreateDirectory(bytesPath);
                            }
                            string json = JsonConvert.SerializeObject(datas);
                            if (CreateJson.Checked)
                            {
                                string json_path = bytesPath + "/" + sheetName + "Data.json";
                                json_path = json_path.Replace("\\", "/");
                                File.WriteAllText(json_path, json);
                            }
                            byte[] bytes = Encoding.UTF8.GetBytes(json);
                            string bytes_path = bytesPath + "/" + sheetName + "Data.bytes";
                            bytes_path = bytes_path.Replace("\\", "/");
                            string asset_path = bytes_path.Substring(bytes_path.LastIndexOf("/Assets") + 7);
                            File.WriteAllBytes(bytes_path, bytes);
                            //创建CS数据管理脚本
                            if (Directory.Exists(csPath) == false)
                            {
                                Directory.CreateDirectory(csPath);
                            }
                            string className = sheetName + "DataTable";
                            string dataName = sheetName + "Data";
                            string cs_path = csPath + "/" + className + ".cs";
                            using(StreamWriter writer = new StreamWriter(cs_path))
                            {
                                writer.WriteLine("using System;");
                                writer.WriteLine("using System.IO;");
                                writer.WriteLine("using System.Text;");
                                writer.WriteLine("using System.Reflection;");
                                writer.WriteLine("using System.Collections;");
                                writer.WriteLine("using System.Collections.Generic;");
                                writer.WriteLine("using UnityEngine;");
                                writer.WriteLine("using Newtonsoft.Json;");
                                writer.WriteLine();
                                writer.WriteLine("// 数据对象");
                                writer.WriteLine($"public class {dataName}");
                                writer.WriteLine("{");
                                for (int col = 1; col <= colCount; col++)
                                {
                                    string propertyName = worksheet.Cells[1, col].Text;
                                    string propertyType = worksheet.Cells[2, col].Text;
                                    if (worksheet.Cells[3, col].Value != null)
                                    {
                                        writer.WriteLine("    /// <summary>");
                                        writer.WriteLine($"    /// {worksheet.Cells[3, col].Text}");
                                        writer.WriteLine("    /// <summary>");
                                    }
                                    writer.WriteLine($"    public {propertyType} {propertyName}" + " { get; set;}");
                                }
                                writer.WriteLine("}");
                                writer.WriteLine();
                                writer.WriteLine($"public class {className} : Singleton<{className}>");
                                writer.WriteLine("{");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    /// 数据列表");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine($"    public List<{dataName}> Rows;");
                                writer.WriteLine();
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    /// 数据文件路径");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine($"    private string dataPath = Application.dataPath + @\"{asset_path}\";");
                                writer.WriteLine();
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    /// 数据初始化");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    public void Init()");
                                writer.WriteLine("    {");
                                writer.WriteLine($"        Rows = new List<{dataName}>();");
                                writer.WriteLine("        string json = Encoding.UTF8.GetString(File.ReadAllBytes(dataPath));");
                                writer.WriteLine("        List<List<string>> datas = (List<List<string>>)JsonConvert.DeserializeObject(json, typeof(List<List<string>>));");
                                writer.WriteLine($"        Type dataType = typeof({dataName});");
                                writer.WriteLine("        PropertyInfo[] properties = dataType.GetProperties();");
                                writer.WriteLine("        foreach(List<string> data in datas)");
                                writer.WriteLine("        {");
                                writer.WriteLine($"            {dataName} row= new {dataName}();");
                                writer.WriteLine("            for(int i = 0; i < properties.Length; i++)");
                                writer.WriteLine("            {");
                                writer.WriteLine("                string propertyName = properties[i].Name;");
                                writer.WriteLine("                string propertyValue = data[i];");
                                writer.WriteLine("                PropertyInfo property = dataType.GetProperty(propertyName);");
                                writer.WriteLine("                try");
                                writer.WriteLine("                {");
                                writer.WriteLine("                    object value = Convert.ChangeType(propertyValue, property.PropertyType);");
                                writer.WriteLine("                    // 设置属性值");
                                writer.WriteLine("                    property.SetValue(row, value);");
                                writer.WriteLine("                }");
                                writer.WriteLine("                catch (Exception ex)");
                                writer.WriteLine("                {");
                                writer.WriteLine("                    // 转换失败,输出错误信息或者处理错误");
                                writer.WriteLine("                    Debug.LogError($\"Failed to convert {propertyValue} to {property.PropertyType} for property {propertyName}: {ex.Message}\");");
                                writer.WriteLine("                }");
                                writer.WriteLine("            }");
                                writer.WriteLine("            Rows.Add(row);");
                                writer.WriteLine("        }");
                                writer.WriteLine("    }");
                                writer.WriteLine();
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    /// 获取数据");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine($"    public {dataName} GetData(int id)");
                                writer.WriteLine("    {");
                                writer.WriteLine("        int index = BinarySearch(id);");
                                writer.WriteLine("        if (index != -1)");
                                writer.WriteLine("        {");
                                writer.WriteLine("            return Rows[index];");
                                writer.WriteLine("        }");
                                writer.WriteLine("        else");
                                writer.WriteLine("        {");
                                writer.WriteLine("            // 未找到对应数据");
                                writer.WriteLine("            return null;");
                                writer.WriteLine("        }");
                                writer.WriteLine("    }");
                                writer.WriteLine();
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    /// 二分查找数据");
                                writer.WriteLine("    /// <summary>");
                                writer.WriteLine("    private int BinarySearch(int id)");
                                writer.WriteLine("    {");
                                writer.WriteLine("        int left = 0;");
                                writer.WriteLine("        int right = Rows.Count - 1;");
                                writer.WriteLine();
                                writer.WriteLine("        while (left <= right)");
                                writer.WriteLine("        {");
                                writer.WriteLine("            int mid = left + (right - left) / 2;");
                                writer.WriteLine("            int currentID = Rows[mid].ID;");
                                writer.WriteLine();
                                writer.WriteLine("            if (currentID == id)");
                                writer.WriteLine("            {");
                                writer.WriteLine("                return mid; // 找到了目标值");
                                writer.WriteLine("            }");
                                writer.WriteLine("            else if (currentID < id)");
                                writer.WriteLine("            {");
                                writer.WriteLine("                left = mid + 1; // 目标值在右半部分");
                                writer.WriteLine("            }");
                                writer.WriteLine("            else");
                                writer.WriteLine("            {");
                                writer.WriteLine("                right = mid - 1; // 目标值在左半部分");
                                writer.WriteLine("            }");
                                writer.WriteLine("        }");
                                writer.WriteLine();
                                writer.WriteLine("        return -1; // 没有找到目标值");
                                writer.WriteLine("    }");
                                writer.WriteLine("}");
                                solveCount++;
                                writer.Close();
                            }
                        }
                    }
                }
                catch(Exception ex)
                {
                    UpdateProgress("处理异常:" + ex.Message);
                    return;
                }
            }
            UpdateProgress("处理结束,本次共处理:" + solveCount + "个文件");
            SolvingTip.Text = "处理完成";
            isSolving = false;
            MessageBox.Show("处理成功!");
        }
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值