using OfficeOpenXml; using System.Collections.Generic; using System.IO; using System.Text; using AlicizaX.Editor.Extension; using Newtonsoft.Json; using UnityEditor; using UnityEngine; class ExcelLocalizationExporter { // 配置写死路径(按实际需求修改) private const string LocalizationPath = "Assets/Resources/Localization/"; private const string HotfixLocalizationPath = "Assets/Bundles/Configs/Localization/"; private const string LocalizationDynamicKey = "Assets/Scripts/HotFix/GameBase/LocalizationKey.cs"; [EditorToolFunction("Config/Dynamic")] public static void GenerateDynamicLocalization() { Export("Assets/Editor/Localization/Localization.xlsx"); } public static void Export(string excelPath) { var fileInfo = new FileInfo(excelPath); using var package = new ExcelPackage(fileInfo); foreach (var worksheet in package.Workbook.Worksheets) { // 确定导出目录 var outputDir = worksheet.Name.Contains("HotFix", System.StringComparison.OrdinalIgnoreCase) ? HotfixLocalizationPath : LocalizationPath; Directory.CreateDirectory(outputDir); var dimension = worksheet.Dimension; if (dimension == null) continue; var languages = new List(); for (int col = 2; col <= dimension.End.Column; col++) { languages.Add(worksheet.Cells[1, col].Text.Trim()); } var langDictionaries = new Dictionary>(); foreach (var lang in languages) { langDictionaries[lang] = new Dictionary(); } for (int row = 2; row <= dimension.End.Row; row++) { var keyCell = worksheet.Cells[row, 1]; if (keyCell.Value == null) continue; var key = keyCell.Text.Trim(); if (string.IsNullOrEmpty(key)) continue; for (int i = 0; i < languages.Count; i++) { var lang = languages[i]; var valueCell = worksheet.Cells[row, i + 2]; var value = valueCell.Value?.ToString() ?? string.Empty; langDictionaries[lang][key] = value.Trim(); } } foreach (var lang in langDictionaries) { var settings = new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore, StringEscapeHandling = StringEscapeHandling.EscapeNonAscii }; var json = JsonConvert.SerializeObject(lang.Value, settings); var outputPath = Path.Combine(outputDir, $"{lang.Key}.json"); File.WriteAllText(outputPath, json); } AssetDatabase.Refresh(); } ExportLocalizationKey(); } public static void ExportLocalizationKey() { string filePath = "Assets/Bundles/Configs/Localization/ChineseSimplified.json"; Dictionary jsonData = JsonConvert.DeserializeObject>(System.IO.File.ReadAllText(filePath)); StringBuilder sb = new StringBuilder(); sb.AppendLine("/// "); sb.AppendLine("/// AutoGenerate"); sb.AppendLine("/// "); sb.AppendLine("public static class LocalizationKey"); sb.AppendLine("{"); foreach (var item in jsonData) { if (item.Key.Contains("\\")) continue; sb.AppendLine("\t/// "); sb.AppendLine($"\t/// {item.Value}"); sb.AppendLine("\t/// "); sb.AppendLine($"\tpublic const string {item.Key} = \"{item.Key}\";"); } sb.AppendLine(); sb.AppendLine("}"); System.IO.File.WriteAllText(LocalizationDynamicKey, sb.ToString()); AssetDatabase.Refresh(); } }