当前位置: 首页 > news >正文

告别Excel.dll!在Unity 2018+中快速集成ExcelDataReader读取.xlsx表格(保姆级教程)

Unity 2018高效读取Excel全攻略告别Excel.dll的兼容噩梦还在为Unity中Excel.dll频繁报错而抓狂每次项目升级都要重新折腾Excel导入导出今天带你彻底摆脱这些烦恼。作为Unity开发者我们经常需要在游戏中动态读取Excel表格数据——可能是关卡配置、道具属性表或是多语言本地化文件。传统方案使用Excel.dll配合SharpZipLib不仅步骤繁琐而且对.xlsx新格式支持极差经常出现莫名其妙的报错。更糟的是这些方案往往随着Unity版本更新突然失效让开发者苦不堪言。ExcelDataReader这个轻量级开源库完美解决了这些问题。它专为.NET平台设计支持.xlsx/.xls/.csv等多种格式无需安装Office组件跨平台表现稳定。更重要的是它通过NuGet管理依赖版本更新及时与Unity 2018的兼容性经过大量项目验证。下面我们就从零开始手把手教你搭建一个健壮的Excel读取系统。1. 环境准备与依赖安装1.1 创建NuGet下载工程首先我们需要获取ExcelDataReader的核心组件。由于Unity暂不支持直接使用NuGet我们需要一个中间步骤# 在任意位置创建.NET Framework控制台项目 dotnet new console -n ExcelReaderInstaller -f net472打开Visual Studio通过包管理器控制台执行Install-Package ExcelDataReader -Version 3.6.0 Install-Package ExcelDataReader.DataSet -Version 3.6.0提示建议固定版本号以避免后续兼容性问题3.6.0版经过长期验证最为稳定安装完成后在解决方案资源管理器中展开依赖项→程序集右键点击ExcelDataReader和ExcelDataReader.DataSet选择在文件资源管理器中打开。你会看到类似这样的目录结构packages └── ExcelDataReader.3.6.0 └── lib ├── net20 ├── net45 └── netstandard2.01.2 选择正确的.NET版本Unity 2018默认使用.NET 4.x等效运行时因此我们需要选择net45目录下的DLL复制ExcelDataReader.dll和ExcelDataReader.DataSet.dll在Unity项目中创建Plugins文件夹如果不存在将两个DLL粘贴到Plugins目录下版本兼容性对照表Unity版本推荐.NET版本所需DLL路径2017.x.NET 3.5net202018-2020.NET 4.xnet452021.NET Standardnetstandard2.0注意如果使用Unity 2017或更早版本还需额外添加System.Data.dll到Plugins目录2. 基础数据读取实战2.1 创建读取脚本在Unity中新建C#脚本ExcelLoader.csusing ExcelDataReader; using System.IO; using UnityEngine; public class ExcelLoader : MonoBehaviour { public string excelPath Data/test.xlsx; void Start() { // 获取完整的文件路径 string fullPath Path.Combine(Application.streamingAssetsPath, excelPath); // 确保文件存在 if (!File.Exists(fullPath)) { Debug.LogError($Excel文件不存在: {fullPath}); return; } // 打开文件流 using (var stream File.Open(fullPath, FileMode.Open, FileAccess.Read)) { // 创建读取器 using (var reader ExcelReaderFactory.CreateReader(stream)) { // 转换为DataSet var dataSet reader.AsDataSet(); // 遍历第一个工作表 var table dataSet.Tables[0]; for (int row 0; row table.Rows.Count; row) { // 输出每行前两列内容 Debug.Log($行{row}: 列1{table.Rows[row][0]}, 列2{table.Rows[row][1]}); } } } } }2.2 数据存储最佳实践建议采用StreamingAssets目录存放Excel文件在Assets下创建StreamingAssets/Data文件夹将测试Excel文件(test.xlsx)放入其中文件结构示例Assets └── StreamingAssets └── Data ├── test.xlsx └── config.xlsx文件读取路径方案对比存储位置访问方式平台兼容性打包后修改ResourcesResources.Load全平台不可修改StreamingAssetsApplication.streamingAssetsPath全平台可修改PersistentDataPathApplication.persistentDataPath全平台可修改3. 高级数据处理技巧3.1 多工作表处理实际项目中一个Excel文件通常包含多个工作表var dataSet reader.AsDataSet(); foreach (DataTable table in dataSet.Tables) { Debug.Log($处理工作表: {table.TableName}); // 添加表头判断 if (table.Rows.Count 1) continue; // 假设第一行是表头 for (int row 1; row table.Rows.Count; row) { // 处理数据行 } }3.2 类型安全转换Excel数据默认以object类型返回建议进行安全转换// 扩展方法示例 public static class DataRowExtensions { public static string GetString(this DataRow row, int index, string defaultValue ) { return row.IsNull(index) ? defaultValue : row[index].ToString(); } public static int GetInt(this DataRow row, int index, int defaultValue 0) { if (row.IsNull(index)) return defaultValue; int.TryParse(row[index].ToString(), out int result); return result; } public static float GetFloat(this DataRow row, int index, float defaultValue 0f) { if (row.IsNull(index)) return defaultValue; float.TryParse(row[index].ToString(), out float result); return result; } } // 使用示例 string name table.Rows[0].GetString(0); int level table.Rows[0].GetInt(1); float damage table.Rows[0].GetFloat(2);4. 性能优化与异常处理4.1 大文件读取优化处理大型Excel文件时可采用分块读取策略// 配置读取选项 var config new ExcelReaderConfiguration() { // 跳过空行 LeaveOpen false, // 自动检测编码 AutodetectEncoding true, // 分析格式化的值 AnalyzeInitialCsvRows 100 }; using (var reader ExcelReaderFactory.CreateReader(stream, config)) { // 逐行读取代替加载完整DataSet while (reader.Read()) { // 处理当前行 for (int col 0; col reader.FieldCount; col) { Debug.Log(reader.GetValue(col)); } } }4.2 常见错误处理典型异常及解决方案异常类型可能原因解决方案BadSignatureException文件损坏/格式错误验证文件完整性HeaderException文件头损坏重新保存Excel文件InvalidPasswordException文件受密码保护移除密码保护MissingFieldException列索引越界检查数据范围增强版错误处理示例try { using (var reader ExcelReaderFactory.CreateReader(stream)) { // 数据处理代码 } } catch (Exception ex) when ( ex is BadSignatureException || ex is HeaderException) { Debug.LogError($Excel文件损坏: {ex.Message}); // 恢复逻辑 } catch (InvalidPasswordException) { Debug.LogError(Excel文件受密码保护); // 提示用户 } catch (Exception ex) { Debug.LogError($未知错误: {ex}); // 通用错误处理 }5. 实际项目集成方案5.1 数据缓存机制避免重复读取Excel文件建议实现数据缓存public class ExcelDataCache { private static Dictionarystring, DataSet _cache new Dictionarystring, DataSet(); public static DataSet Load(string path) { if (_cache.TryGetValue(path, out var cachedData)) return cachedData; using (var stream File.Open(path, FileMode.Open, FileAccess.Read)) { using (var reader ExcelReaderFactory.CreateReader(stream)) { var data reader.AsDataSet(); _cache[path] data; return data; } } } public static void ClearCache() { _cache.Clear(); } }5.2 编辑器扩展开发创建自定义编辑器窗口简化操作#if UNITY_EDITOR using UnityEditor; using System.Linq; public class ExcelImporterWindow : EditorWindow { [MenuItem(Tools/Excel Importer)] public static void ShowWindow() { GetWindowExcelImporterWindow(Excel导入器); } void OnGUI() { if (GUILayout.Button(导入物品数据)) { ImportItemData(); } } void ImportItemData() { string path EditorUtility.OpenFilePanel(选择Excel文件, Application.streamingAssetsPath, xlsx,xls,csv); if (string.IsNullOrEmpty(path)) return; try { var data ExcelDataCache.Load(path); var table data.Tables[Items]; // 转换为游戏数据对象 var items new ListItemData(); foreach (DataRow row in table.Rows) { items.Add(new ItemData { id row.GetInt(0), name row.GetString(1), price row.GetInt(2) }); } // 保存为ScriptableObject var asset ScriptableObject.CreateInstanceItemDatabase(); asset.items items.ToArray(); string assetPath Assets/Resources/ItemDatabase.asset; AssetDatabase.CreateAsset(asset, assetPath); AssetDatabase.SaveAssets(); Debug.Log($成功导入{items.Count}个物品); } catch (Exception ex) { EditorUtility.DisplayDialog(导入失败, ex.Message, 确定); } } } #endif6. 跨平台注意事项6.1 Android/iOS特殊处理移动平台需要额外注意Android确保Excel文件设置为不压缩[MenuItem(Assets/Android - 不压缩Excel)] static void SetExcelAndroidSettings() { var importer AssetImporter.GetAtPath(Assets/StreamingAssets/Data/test.xlsx); importer.SetPlatformData(Android, Compression, 0); }使用WWW或UnityWebRequest读取IEnumerator LoadExcelAndroid(string path) { string url Path.Combine(Application.streamingAssetsPath, path); var request UnityWebRequest.Get(url); yield return request.SendWebRequest(); using (var stream new MemoryStream(request.downloadHandler.data)) { using (var reader ExcelReaderFactory.CreateReader(stream)) { // 处理数据 } } }iOS确保文件扩展名正确区分大小写避免使用特殊字符命名文件6.2 WebGL兼容方案WebGL平台限制较多推荐方案提前将Excel转换为JSON使用TextAsset加载TextAsset jsonFile Resources.LoadTextAsset(data/items); var items JsonUtility.FromJsonItemList(jsonFile.text);或通过后端服务中转各平台推荐数据格式平台推荐格式优点编辑器原生Excel方便编辑PC/主机Excel或二进制灵活高效移动端预转换JSON加载快WebGLJSON兼容性好7. 替代方案对比虽然ExcelDataReader是Unity中处理Excel的优选方案但了解其他选项也很重要主流Excel处理库对比方案优点缺点适用场景ExcelDataReader轻量、开源、跨平台不能写入只读场景EPPlus读写支持完善商业用途需授权需要编辑功能NPOI功能全面较复杂、体积大复杂Excel操作CSV简单通用无格式和多表简单数据交换对于纯数据配置也可以考虑直接使用JSON或ScriptableObject// JSON转换示例 [System.Serializable] public class ItemData { public int id; public string name; public float price; } public static ListItemData LoadFromJson(string jsonPath) { string json File.ReadAllText(jsonPath); return JsonConvert.DeserializeObjectListItemData(json); }选择依据主要取决于是否需要非技术人员编辑数据数据量大小跨平台要求是否需要保留Excel公式和格式
http://www.gsyq.cn/news/1409200.html

相关文章:

  • 彻底搞懂:半导体、内存、硬盘、CPU存储的底层关系
  • 通过curl命令快速诊断taotoken api连接与认证问题的排查方法
  • 客流统计系统如何做长期数据沉淀?聊聊去重、Session 化与数据一致性问题
  • 别再傻傻分不清!用Arduino和ESP32驱动电机,NPN三极管与N-MOS管实战选型指南
  • 从扭矩控制到总线拓扑:多自由度高动态机器人实机调试的底层逻辑与工程痛点
  • 避开这3个坑!用Tushare获取股票数据时新手常犯的错误(附正确代码示例)
  • 别再让CPU干苦力了!手把手教你用STM32G4的FMAC硬件加速器做FIR滤波
  • HC-276合金厂商那家好?资深采购员实地测评 - 品牌2025
  • AI代码审查:让AI帮你把关代码质量
  • 文章没人看?多半是标题的锅:我用 Codex + Obsidian 做了个爆款标题 Skil
  • 2026年至今福建好的餐边柜制造商:如何精准选型避坑? - 2026年企业资讯
  • 化工领域热门推荐:Incoloy 800在高温高压下的表现如何? - 品牌2025
  • S32K3 eMIOS实战:从MCAL配置到PWM与ICU的精准控制
  • 2026年高端制造新标杆:探秘深圳市聚德鑫特殊钢材的Inconel 718品质之道 - 品牌2025
  • 2026年 电磁离合器/电磁制动器/电磁刹车器推荐榜单:单片、多片与通电失电式全系优选解析 - 品牌企业推荐师(官方)
  • C251嵌入式开发中的精准延时实现与优化
  • 2026年 3051DP差压变送器厂家推荐榜:TK-DZS-3051DP/天康智能变送器品牌与高精度优选 - 品牌企业推荐师(官方)
  • AR 智能眼镜智正优化警务领域的日常巡逻和排查麻烦的难点
  • 用Python实战MUSIC算法:手把手教你实现麦克风阵列的声源定位(附代码)
  • Ali-tianchi news:all
  • 基于 okbiye 的 AI 期刊论文写作实践:从普通刊到 SCI 的全场景辅助路径
  • 拯救老系统:手把手教你在macOS Ventura/Sonoma上配置金蝶EAS 8.2客户端
  • Windsurf 完整实战教程
  • STM32F4 HAL库开发 -- DMA实战:从零构建高效串口数据搬运工
  • 新手避坑指南:在Ubuntu 22.04上用virt-manager创建虚拟机时,我遇到的3个权限问题和解决方法
  • 618要买什么?盘点2026年闭眼入不踩坑的内衣洗衣机品牌!海尔、希亦、小米等十款王者级别的内衣洗衣机
  • OPC中国未来五年的发展方向
  • C语言字符串API大全!9个核心函数速记,零基础编程入门必备
  • 荣耀出征官方网站下载三端正版:战盟体系玩法与贡献收益最大化指南
  • FPG财盛国际:投教支持与服务响应表现解析