diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelStream.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelStream.cs index bf22973..d3eb008 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelStream.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelStream.cs @@ -175,7 +175,7 @@ namespace Luban.Job.Cfg.DataSources.Excel } - private const string END_OF_LIST = "}"; + public const string END_OF_LIST = "}"; private bool IsSkip(object x) diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs index eb7b033..99ff82c 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs @@ -14,12 +14,14 @@ namespace Luban.Job.Cfg.DataSources.Excel public string Name { get; set; } - public string Sep { get; set; } = "|"; + public string Sep { get; set; } public Dictionary SubTitles { get; set; } = new Dictionary(); public List SubTitleList { get; set; } = new List<Title>(); + public bool HasSubTitle => SubTitleList.Count > 0; + public void AddSubTitle(Title title) { if (!SubTitles.TryAdd(title.Name, title)) diff --git a/src/Luban.Job.Cfg/Source/DataVisitors/ToStringVisitor.cs b/src/Luban.Job.Cfg/Source/DataVisitors/ToStringVisitor.cs index 78b1d90..de67d24 100644 --- a/src/Luban.Job.Cfg/Source/DataVisitors/ToStringVisitor.cs +++ b/src/Luban.Job.Cfg/Source/DataVisitors/ToStringVisitor.cs @@ -11,8 +11,12 @@ namespace Luban.Job.Cfg.DataVisitors public override string Accept(DText type) { +#if !LUBAN_LITE var ass = DefAssembly.LocalAssebmly as DefAssembly; return $"\"{type.Key}#{type.GetText(ass.ExportTextTable, ass.NotConvertTextSet)}\""; +#else + return $"\"{type.Key}#{type.RawValue}\""; +#endif } public override string Accept(DBean type) diff --git a/src/LubanAssistant/AssistantTab.cs b/src/LubanAssistant/AssistantTab.cs index b64869e..4dde56b 100644 --- a/src/LubanAssistant/AssistantTab.cs +++ b/src/LubanAssistant/AssistantTab.cs @@ -1,4 +1,6 @@ -using Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataSources.Excel; +using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Utils; using Luban.Job.Common.Defs; using Luban.Server.Common; @@ -37,6 +39,8 @@ namespace LubanAssistant } } + public TableDataInfo LastLoadTableData { get; private set; } + private void AssistantTab_Load(object sender, RibbonUIEventArgs e) { } @@ -73,16 +77,6 @@ namespace LubanAssistant return true; } inputDataDir = null; - //var dialog = new OpenFileDialog(); - //dialog.Title = "Select Data Dir"; - //dialog.CheckFileExists = false; - //dialog.CheckPathExists = true; - //if (dialog.ShowDialog() == DialogResult.OK) - //{ - // inputDataDir = dialog.FileName; - // return true; - //} - //inputDataDir = null; return false; } @@ -102,20 +96,6 @@ namespace LubanAssistant } } - - - private bool TryGetTableName(out string tableName) - { - Worksheet cur = Globals.LubanAssistant.Application.ActiveSheet; - var metaAttrs = ExcelUtil.ParseMetaAttrs(cur); - if (metaAttrs.TryGetValue("table", out tableName)) - { - return true; - } - tableName = null; - return false; - } - private void LoadDataToCurrentDoc() { @@ -132,7 +112,7 @@ namespace LubanAssistant { try { - var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(RootDefineFile, InputDataDir, tableName); + var tableDataInfo = LastLoadTableData = await DataLoaderUtil.LoadTableDataAsync(RootDefineFile, InputDataDir, tableName); var title = ExcelUtil.ParseTitles(sheet); ExcelUtil.FillRecords(sheet, metaAttrs, title, tableDataInfo); } @@ -179,14 +159,101 @@ namespace LubanAssistant } } + private void SaveRecords(Action<Worksheet, Dictionary<string, string>, TableDataInfo, DefTable, TitleInfo> saveTask) + { + Worksheet sheet = Globals.LubanAssistant.Application.ActiveSheet; + + var metaAttrs = ExcelUtil.ParseMetaAttrs(sheet); + if (!metaAttrs.TryGetValue("table", out var tableName)) + { + MessageBox.Show($"meta行未指定table名"); + return; + } + + _ = Task.Run(async () => + { + try + { + if (LastLoadTableData == null) + { + LastLoadTableData = await DataLoaderUtil.LoadTableDataAsync(RootDefineFile, InputDataDir, tableName); + } + + var tableDef = await DataLoaderUtil.LoadTableDefAsync(RootDefineFile, InputDataDir, tableName); + var title = ExcelUtil.ParseTitles(sheet); + saveTask(sheet, metaAttrs, LastLoadTableData, tableDef, title); + } + catch (Exception e) + { + MessageBox.Show(e.StackTrace, e.Message); + } + }); + } + private void BtnSaveAllClick(object sender, RibbonControlEventArgs e) { - MessageBox.Show("点击save"); + SaveRecords((Worksheet sheet, Dictionary<string, string> metaAttrs, TableDataInfo tableDataInfo, DefTable defTable, TitleInfo title) => + { + int usedRowNum = sheet.UsedRange.Rows.Count; + int firstDataRowNum = int.Parse(metaAttrs["title_rows"]) + 2; + if (firstDataRowNum <= usedRowNum) + { + var newRecords = ExcelUtil.LoadRecordsInRange(defTable, sheet, title.RootTitle, (sheet.Range[$"A{firstDataRowNum}:A{usedRowNum}"]).EntireRow); + ExcelUtil.SaveRecords(InputDataDir, defTable, newRecords); + CleanRemovedRecordFiles(LastLoadTableData, newRecords); + } + else + { + MessageBox.Show("没有可保存的数据"); + } + }); + } + + private void CleanRemovedRecordFiles(TableDataInfo lastTableDataInfo, List<Record> newRecords) + { + string index = lastTableDataInfo.Table.IndexField.Name; + + var oldRecordDic = lastTableDataInfo.MainRecords.ToDictionary(r => r.Data.GetField(index)); + var newRecordDic = newRecords.ToDictionary(r => r.Data.GetField(index)); + foreach (var rec in lastTableDataInfo.MainRecords) + { + DType key = rec.Data.GetField(index); + if (!newRecordDic.ContainsKey(key)) + { + try + { + File.Delete(Path.Combine(InputDataDir, rec.Source)); + //MessageBox.Show($"删除 {Path.Combine(InputDataDir, rec.Source)}"); + } + catch (Exception e) + { + MessageBox.Show($"删除记录:{rec.Source}失败.\n:{e.StackTrace}", "删除失败"); + } + } + } } private void BtnSaveSelectedClick(object sender, RibbonControlEventArgs e) { - MessageBox.Show("点击save"); + var selectRange = (Range)Globals.LubanAssistant.Application.Selection; + if (selectRange == null || selectRange.Count == 0) + { + MessageBox.Show("没有选中的行"); + return; + } + SaveRecords((Worksheet sheet, Dictionary<string, string> metaAttrs, TableDataInfo tableDataInfo, DefTable defTable, TitleInfo title) => + { + int usedRowNum = sheet.UsedRange.Rows.Count; + if (title.RowNum + 1 < usedRowNum) + { + var newRecords = ExcelUtil.LoadRecordsInRange(defTable, sheet, title.RootTitle, selectRange.EntireRow); + ExcelUtil.SaveRecords(InputDataDir, defTable, newRecords); + } + else + { + MessageBox.Show("没有可保存的数据"); + } + }); } } } diff --git a/src/LubanAssistant/ExcelUtil.cs b/src/LubanAssistant/ExcelUtil.cs index cebc9a7..595961b 100644 --- a/src/LubanAssistant/ExcelUtil.cs +++ b/src/LubanAssistant/ExcelUtil.cs @@ -1,11 +1,16 @@ -using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataExporters; +using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.DataSources.Excel; +using Luban.Job.Cfg.DataVisitors; using Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.Utils; using Microsoft.Office.Interop.Excel; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading.Tasks; namespace LubanAssistant @@ -157,6 +162,55 @@ namespace LubanAssistant } } + public static List<Record> LoadRecordsInRange(DefTable table, Worksheet sheet, Title title, Range toSaveRecordRows) + { + var recs = new List<Record>(); + foreach (Range row in toSaveRecordRows) + { + bool allEmpty = true; + for (int i = title.FromIndex; i <= title.ToIndex; i++) + { + if (!string.IsNullOrEmpty((row.Cells[1, i] as Range).Value?.ToString())) + { + allEmpty = false; + break; + } + } + if (allEmpty) + { + continue; + } + string tags = (row.Cells[1, 1] as Range).Value?.ToString(); + recs.Add(new Record( + (DBean)table.ValueTType.Apply(new SheetDataCreator(sheet, row.Row, table.Assembly), title, null), + "", + DataUtil.ParseTags(tags))); + } + return recs; + } + + public static void SaveRecords(string inputDataDir, DefTable table, List<Record> records) + { + var recordOutputDir = Path.Combine(inputDataDir, table.InputFiles[0]); + string index = table.IndexField.Name; + foreach (var r in records) + { + var ss = new MemoryStream(); + var jsonWriter = new Utf8JsonWriter(ss, new JsonWriterOptions() + { + Indented = true, + SkipValidation = false, + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All), + }); + RawJsonExportor.Ins.Accept(r.Data, jsonWriter); + + jsonWriter.Flush(); + var key = r.Data.GetField(index); + var fileName = $"{key.Apply(ToStringVisitor.Ins)}.json"; + File.WriteAllBytes(Path.Combine(recordOutputDir, fileName), DataUtil.StreamToBytes(ss)); + } + } + //public static void FillRecord(Worksheet sheet, ref int nextRowIndex, Title title, Record record) //{ diff --git a/src/LubanAssistant/FillSheetVisitor.cs b/src/LubanAssistant/FillSheetVisitor.cs index 1ba24a9..8b26fa0 100644 --- a/src/LubanAssistant/FillSheetVisitor.cs +++ b/src/LubanAssistant/FillSheetVisitor.cs @@ -105,12 +105,12 @@ namespace LubanAssistant public int Accept(DText type, Title x) { - if (x.FromIndex == x.ToIndex) - { - throw new Exception($"title:{x.Name}为text类型,至少要占两列"); - } - (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Key; - (_cells[_startRowIndex, x.FromIndex + 1] as Range).Value = type.RawValue; + //if (x.FromIndex == x.ToIndex) + //{ + // throw new Exception($"title:{x.Name}为text类型,至少要占两列"); + //} + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + //(_cells[_startRowIndex, x.FromIndex + 1] as Range).Value = type.RawValue; return 1; } diff --git a/src/LubanAssistant/LoadUtil.cs b/src/LubanAssistant/LoadUtil.cs index 3661d28..de82754 100644 --- a/src/LubanAssistant/LoadUtil.cs +++ b/src/LubanAssistant/LoadUtil.cs @@ -16,11 +16,6 @@ namespace LubanAssistant { static class LoadUtil { - public static async Task LoadTableDataToCurrentWorkSheetAsync(string rootDefineFile, string inputDataDir, string tableName) - { - var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(rootDefineFile, inputDataDir, tableName); - Console.WriteLine("load record num:{0}", tableDataInfo.MainRecords.Count); - } } } diff --git a/src/LubanAssistant/LubanAssistant.csproj b/src/LubanAssistant/LubanAssistant.csproj index a3a084e..53539fa 100644 --- a/src/LubanAssistant/LubanAssistant.csproj +++ b/src/LubanAssistant/LubanAssistant.csproj @@ -360,6 +360,12 @@ <Compile Include="..\Luban.Job.Cfg\Source\DataVisitors\IDataFuncVisitor.cs"> <Link>Source\DataVisitors\IDataFuncVisitor.cs</Link> </Compile> + <Compile Include="..\Luban.Job.Cfg\Source\DataVisitors\ToLiteralVisitorBase.cs"> + <Link>Source\DataVisitors\ToLiteralVisitorBase.cs</Link> + </Compile> + <Compile Include="..\Luban.Job.Cfg\Source\DataVisitors\ToStringVisitor.cs"> + <Link>Source\DataVisitors\ToStringVisitor.cs</Link> + </Compile> <Compile Include="..\Luban.Job.Cfg\Source\Defs\CfgDefTypeBase.cs"> <Link>Source\Defs\CfgDefTypeBase.cs</Link> </Compile> @@ -540,6 +546,8 @@ <Compile Include="Properties\AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="SheetDataCreator.cs" /> + <Compile Include="Source\DataExporters\RawJsonExportor.cs" /> <Compile Include="ToExcelStringVisitor.cs" /> <EmbeddedResource Include="AssistantTab.resx"> <DependentUpon>AssistantTab.cs</DependentUpon> diff --git a/src/LubanAssistant/SheetDataCreator.cs b/src/LubanAssistant/SheetDataCreator.cs new file mode 100644 index 0000000..7d02cc1 --- /dev/null +++ b/src/LubanAssistant/SheetDataCreator.cs @@ -0,0 +1,201 @@ +using Luban.Common.Utils; +using Luban.Job.Cfg.DataCreators; +using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataSources.Excel; +using Luban.Job.Cfg.Defs; +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LubanAssistant +{ + class SheetDataCreator : ITypeFuncVisitor<Title, DefField, DType> + { + private readonly Worksheet _sheet; + private readonly int _rowIndex; + private readonly DefAssembly _defAss; + + public SheetDataCreator(Worksheet sheet, int rowIndex, DefAssembly ass) + { + _sheet = sheet; + _rowIndex = rowIndex; + _defAss = ass; + } + + + private ExcelStream CreateStream(Title title, bool nameMode = true) + { + return new ExcelStream(new Cell(title.FromIndex, title.ToIndex, _sheet.Cells[_rowIndex, title.FromIndex].Value), title.Sep, nameMode); + } + + public DType Accept(TBool type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TByte type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TShort type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TFshort type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TInt type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TFint type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TLong type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TFlong type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TFloat type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TDouble type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TEnum type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TString type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TBytes type, Title x, DefField y) + { + throw new NotSupportedException(); + } + + public DType Accept(TText type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TBean type, Title title, DefField defField) + { + if (title.HasSubTitle) + { + var originBean = (DefBean)type.Bean; + DefBean implType; + if (originBean.IsAbstractType) + { + if (!title.SubTitles.TryGetValue(DefBean.TYPE_NAME_KEY, out var typeTitle)) + { + throw new Exception($"title:{title.Name} 缺失 子title:{DefBean.TYPE_NAME_KEY}"); + } + + string subType = (_sheet.Cells[_rowIndex, typeTitle.FromIndex] as Range).Value.ToString().Trim(); + if (subType.ToLower() == DefBean.BEAN_NULL_STR) + { + if (!type.IsNullable) + { + throw new Exception($"type:'{type}' 不是可空类型 '{type.Bean.FullName}?' , 不能为空"); + } + return null; + } + string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType); + implType = (DefBean)originBean.GetNotAbstractChildType(subType); + if (implType == null) + { + throw new Exception($"type:'{fullType}' 不是 bean 类型"); + } + + + } + else + { + implType = originBean; + } + var fields = new List<DType>(); + foreach (var f in implType.HierarchyFields) + { + if (!title.SubTitles.TryGetValue(f.Name, out var subTitle)) + { + throw new Exception($"title:{title.Name} 缺失子title:{f.Name}"); + } + fields.Add(f.CType.Apply(this, subTitle, (DefField)f)); + } + + return new DBean(originBean, implType, fields); + } + else + { + return type.Apply(ExcelDataCreator.Ins, defField, CreateStream(title, false), _defAss); + } + } + + public DType Accept(TArray type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TList type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TSet type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TMap type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TVector2 type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TVector3 type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TVector4 type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + public DType Accept(TDateTime type, Title x, DefField y) + { + return type.Apply(ExcelDataCreator.Ins, y, CreateStream(x), _defAss); + } + + + } +} diff --git a/src/LubanAssistant/Source/DataExporters/RawJsonExportor.cs b/src/LubanAssistant/Source/DataExporters/RawJsonExportor.cs new file mode 100644 index 0000000..5d31784 --- /dev/null +++ b/src/LubanAssistant/Source/DataExporters/RawJsonExportor.cs @@ -0,0 +1,201 @@ +using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataVisitors; +using Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.Utils; +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Luban.Job.Cfg.DataExporters +{ + class RawJsonExportor : IDataActionVisitor<Utf8JsonWriter> + { + public static RawJsonExportor Ins { get; } = new(); + + public void WriteAsArray(List<Record> datas, Utf8JsonWriter x) + { + x.WriteStartArray(); + foreach (var d in datas) + { + d.Data.Apply(this, x); + } + x.WriteEndArray(); + } + + public void Accept(DBool type, Utf8JsonWriter x) + { + x.WriteBooleanValue(type.Value); + } + + public void Accept(DByte type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DShort type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DFshort type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DInt type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DFint type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DLong type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DFlong type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DFloat type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DDouble type, Utf8JsonWriter x) + { + x.WriteNumberValue(type.Value); + } + + public void Accept(DEnum type, Utf8JsonWriter x) + { + x.WriteStringValue(type.StrValue); + } + + public void Accept(DString type, Utf8JsonWriter x) + { + x.WriteStringValue(type.Value); + } + + public void Accept(DBytes type, Utf8JsonWriter x) + { + throw new NotImplementedException(); + } + + public void Accept(DText type, Utf8JsonWriter x) + { + x.WriteStartObject(); + x.WritePropertyName(DText.KEY_NAME); + x.WriteStringValue(type.Key); + x.WritePropertyName(DText.TEXT_NAME); + x.WriteStringValue(type.RawValue); + x.WriteEndObject(); + } + + public void Accept(DBean type, Utf8JsonWriter x) + { + x.WriteStartObject(); + + if (type.Type.IsAbstractType) + { + x.WritePropertyName(DefBean.TYPE_NAME_KEY); + x.WriteStringValue(type.ImplType.Name); + } + + var defFields = type.ImplType.HierarchyFields; + int index = 0; + foreach (var d in type.Fields) + { + var defField = (DefField)defFields[index++]; + + // 特殊处理 bean 多态类型 + // 另外,不生成 xxx:null 这样 + if (d == null || !defField.NeedExport) + { + //x.WriteNullValue(); + } + else + { + x.WritePropertyName(defField.Name); + d.Apply(this, x); + } + } + x.WriteEndObject(); + } + + public void WriteList(List<DType> datas, Utf8JsonWriter x) + { + x.WriteStartArray(); + foreach (var d in datas) + { + d.Apply(this, x); + } + x.WriteEndArray(); + } + + public void Accept(DArray type, Utf8JsonWriter x) + { + WriteList(type.Datas, x); + } + + public void Accept(DList type, Utf8JsonWriter x) + { + WriteList(type.Datas, x); + } + + public void Accept(DSet type, Utf8JsonWriter x) + { + WriteList(type.Datas, x); + } + + public virtual void Accept(DMap type, Utf8JsonWriter x) + { + x.WriteStartArray(); + foreach (var d in type.Datas) + { + x.WriteStartArray(); + d.Key.Apply(this, x); + d.Value.Apply(this, x); + x.WriteEndArray(); + } + x.WriteEndArray(); + } + + public void Accept(DVector2 type, Utf8JsonWriter x) + { + x.WriteStartObject(); + x.WriteNumber("x", type.Value.X); + x.WriteNumber("y", type.Value.Y); + x.WriteEndObject(); + } + + public void Accept(DVector3 type, Utf8JsonWriter x) + { + x.WriteStartObject(); + x.WriteNumber("x", type.Value.X); + x.WriteNumber("y", type.Value.Y); + x.WriteNumber("z", type.Value.Z); + x.WriteEndObject(); + } + + public void Accept(DVector4 type, Utf8JsonWriter x) + { + x.WriteStartObject(); + x.WriteNumber("x", type.Value.X); + x.WriteNumber("y", type.Value.Y); + x.WriteNumber("z", type.Value.Z); + x.WriteNumber("w", type.Value.W); + x.WriteEndObject(); + } + + public void Accept(DDateTime type, Utf8JsonWriter x) + { + x.WriteStringValue(DataUtil.FormatDateTime(type.Time)); + } + } +} diff --git a/src/LubanAssistant/Source/Utils/DataLoaderUtil.cs b/src/LubanAssistant/Source/Utils/DataLoaderUtil.cs index 1350852..59fc86f 100644 --- a/src/LubanAssistant/Source/Utils/DataLoaderUtil.cs +++ b/src/LubanAssistant/Source/Utils/DataLoaderUtil.cs @@ -192,7 +192,7 @@ namespace Luban.Job.Cfg.Utils } } - public static async Task<TableDataInfo> LoadTableDataAsync(string rootDefineFile, string inputDataDir, string tableName) + public static async Task<DefAssembly> LoadDefAssemblyAsync(string rootDefineFile, string inputDataDir) { IAgent agent = new LocalAgent(); var loader = new CfgDefLoader(agent); @@ -209,6 +209,12 @@ namespace Luban.Job.Cfg.Utils ass.Load("all", rawDefines); DefAssemblyBase.LocalAssebmly = ass; + return ass; + } + + public static async Task<DefTable> LoadTableDefAsync(string rootDefineFile, string inputDataDir, string tableName) + { + DefAssembly ass = await LoadDefAssemblyAsync(rootDefineFile, inputDataDir); var table = ass.GetCfgTable(tableName); @@ -216,7 +222,13 @@ namespace Luban.Job.Cfg.Utils { throw new Exception($"table:{tableName}不存在"); } - var tableDataInfo = await LoadTableAsync(agent, table, inputDataDir, "", ""); + return table; + } + + public static async Task<TableDataInfo> LoadTableDataAsync(string rootDefineFile, string inputDataDir, string tableName) + { + var table = await LoadTableDefAsync(rootDefineFile, inputDataDir, tableName); + var tableDataInfo = await LoadTableAsync(table.Assembly.Agent, table, inputDataDir, "", ""); //MessageBox.Show($"table:{table.FullName} input:{StringUtil.CollectionToString(table.InputFiles)} record num:{datas.Count}"); return tableDataInfo; } diff --git a/src/LubanAssistant/ToExcelStringVisitor.cs b/src/LubanAssistant/ToExcelStringVisitor.cs index e1ceec9..59666e6 100644 --- a/src/LubanAssistant/ToExcelStringVisitor.cs +++ b/src/LubanAssistant/ToExcelStringVisitor.cs @@ -1,4 +1,5 @@ using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataSources.Excel; using Luban.Job.Cfg.DataVisitors; using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Utils; @@ -105,6 +106,18 @@ namespace LubanAssistant continue; } sb.Add(field.Apply(this, sep)); + // 对于数目不定的数据类型,需要加分割符 + switch (field) + { + case DArray: + case DList: + case DSet: + case DMap: + { + sb.Add(ExcelStream.END_OF_LIST); + break; + } + } } return string.Join(sep, sb); }