From f22dc4527353438c1d67fcbf9f4a6bce9dfddb6f Mon Sep 17 00:00:00 2001 From: walon Date: Wed, 13 Oct 2021 11:47:40 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=AE=8C=E5=96=84=E3=80=91LubanAssist?= =?UTF-8?q?ant=20=E8=83=BD=E5=A4=9F=E6=AD=A3=E7=A1=AE=E4=BB=8Ejson?= =?UTF-8?q?=E6=88=96=E8=80=85=E5=85=B6=E4=BB=96=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=AD=E5=8A=A0=E8=BD=BD=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=B8=94=E5=A1=AB=E5=85=85=E5=88=B0excel=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../DataCreators/ExcelNamedRowDataCreator.cs | 4 +- .../Source/DataSources/Excel/Sheet.cs | 43 +--- .../Source/DataSources/Excel/Title.cs | 49 ++++ src/Luban.Job.Cfg/Source/Utils/DataUtil.cs | 5 + src/LubanAssistant/AssistantTab.cs | 23 +- src/LubanAssistant/ExcelUtil.cs | 166 +++++++++++++ src/LubanAssistant/FillSheetVisitor.cs | 232 ++++++++++++++++++ src/LubanAssistant/LoadUtil.cs | 5 +- src/LubanAssistant/LubanAssistant.csproj | 7 + .../Source/DataSources/Excel/TitleInfo.cs | 21 ++ src/LubanAssistant/ToExcelStringVisitor.cs | 155 ++++++++++++ 12 files changed, 663 insertions(+), 48 deletions(-) create mode 100644 src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs create mode 100644 src/LubanAssistant/ExcelUtil.cs create mode 100644 src/LubanAssistant/FillSheetVisitor.cs create mode 100644 src/LubanAssistant/Source/DataSources/Excel/TitleInfo.cs create mode 100644 src/LubanAssistant/ToExcelStringVisitor.cs diff --git a/.gitignore b/.gitignore index 0682222..283ac63 100644 --- a/.gitignore +++ b/.gitignore @@ -270,3 +270,4 @@ __pycache__/ /config/output_lua /config/output_lua_without_test /src/Excel2TextDiff/Properties/launchSettings.json +/src/packages diff --git a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs index e6e3183..5bbb751 100644 --- a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs +++ b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs @@ -109,7 +109,7 @@ namespace Luban.Job.Cfg.DataCreators foreach (DefField f in bean.HierarchyFields) { string fname = f.Name; - Sheet.Title title = row.GetTitle(fname); + Title title = row.GetTitle(fname); if (title == null) { throw new Exception($"bean:'{bean.FullName}' 缺失 列:'{fname}',请检查是否写错或者遗漏"); @@ -288,7 +288,7 @@ namespace Luban.Job.Cfg.DataCreators } - private bool TryCreateColumnStream(Sheet.NamedRow x, Sheet.Title title, out ExcelStream stream) + private bool TryCreateColumnStream(Sheet.NamedRow x, Title title, out ExcelStream stream) { var cells = new List(); for (int i = title.FromIndex; i <= title.ToIndex; i++) diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs index f27ce22..8db5eb2 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs @@ -38,46 +38,7 @@ namespace Luban.Job.Cfg.DataSources.Excel public List> RowColumns => _rowColumns; - public class Title - { - public bool Root { get; set; } - public int FromIndex { get; set; } - - public int ToIndex { get; set; } - - public string Name { get; set; } - - public Dictionary SubTitles { get; set; } = new Dictionary(); - - public List SubTitleList { get; set; } = new List<Title>(); - - public void AddSubTitle(Title title) - { - if (!SubTitles.TryAdd(title.Name, title)) - { - throw new Exception($"标题:{title.Name} 重复"); - } - SubTitleList.Add(title); - } - - // 由于先处理merge再处理只占一列的标题头. - // sub titles 未必是有序的。对于大多数数据并无影响 - // 但对于 list类型的多级标题头,有可能导致element 数据次序乱了 - public void SortSubTitles() - { - SubTitleList.Sort((t1, t2) => t1.FromIndex - t2.FromIndex); - foreach (var t in SubTitleList) - { - t.SortSubTitles(); - } - } - - public override string ToString() - { - return $"name:{Name} [{FromIndex}, {ToIndex}] sub titles:[{string.Join(",\\n", SubTitleList)}]"; - } - } public class NamedRow { @@ -336,6 +297,10 @@ namespace Luban.Job.Cfg.DataSources.Excel HeaderRowCount = v; break; } + case "table": + { + break; + } default: { throw new Exception($"非法单元薄 meta 属性定义 {attr}, 合法属性有: orientation=r|row|c|column,title_rows=<number>"); diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs new file mode 100644 index 0000000..eb7b033 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/Title.cs @@ -0,0 +1,49 @@ +using Bright.Collections; +using System; +using System.Collections.Generic; + +namespace Luban.Job.Cfg.DataSources.Excel +{ + public class Title + { + public bool Root { get; set; } + + public int FromIndex { get; set; } + + public int ToIndex { get; set; } + + public string Name { get; set; } + + public string Sep { get; set; } = "|"; + + public Dictionary<string, Title> SubTitles { get; set; } = new Dictionary<string, Title>(); + + public List<Title> SubTitleList { get; set; } = new List<Title>(); + + public void AddSubTitle(Title title) + { + if (!SubTitles.TryAdd(title.Name, title)) + { + throw new Exception($"标题:{title.Name} 重复"); + } + SubTitleList.Add(title); + } + + // 由于先处理merge再处理只占一列的标题头. + // sub titles 未必是有序的。对于大多数数据并无影响 + // 但对于 list类型的多级标题头,有可能导致element 数据次序乱了 + public void SortSubTitles() + { + SubTitleList.Sort((t1, t2) => t1.FromIndex - t2.FromIndex); + foreach (var t in SubTitleList) + { + t.SortSubTitles(); + } + } + + public override string ToString() + { + return $"name:{Name} [{FromIndex}, {ToIndex}] sub titles:[{string.Join(",\\n", SubTitleList)}]"; + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Utils/DataUtil.cs b/src/Luban.Job.Cfg/Source/Utils/DataUtil.cs index ba59da2..12f9f22 100644 --- a/src/Luban.Job.Cfg/Source/Utils/DataUtil.cs +++ b/src/Luban.Job.Cfg/Source/Utils/DataUtil.cs @@ -62,6 +62,11 @@ namespace Luban.Job.Cfg.Utils return new DDateTime(dateTime); } + public static string FormatDateTime(DateTime datetime) + { + return datetime.ToString("yyyy-M-d HH:mm:ss"); + } + public static byte[] StreamToBytes(Stream stream) { byte[] bytes = new byte[stream.Length]; diff --git a/src/LubanAssistant/AssistantTab.cs b/src/LubanAssistant/AssistantTab.cs index 8aac8c9..b64869e 100644 --- a/src/LubanAssistant/AssistantTab.cs +++ b/src/LubanAssistant/AssistantTab.cs @@ -2,6 +2,7 @@ using Luban.Job.Cfg.Utils; using Luban.Job.Common.Defs; using Luban.Server.Common; +using Microsoft.Office.Interop.Excel; using Microsoft.Office.Tools.Ribbon; using System; using System.Collections.Concurrent; @@ -101,15 +102,27 @@ namespace LubanAssistant } } + + private bool TryGetTableName(out string tableName) { - tableName = "test.TbExcelFromJson"; - return true; + 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() { - if (!TryGetTableName(out var tableName)) + + Worksheet sheet = Globals.LubanAssistant.Application.ActiveSheet; + + var metaAttrs = ExcelUtil.ParseMetaAttrs(sheet); + if (!metaAttrs.TryGetValue("table", out var tableName)) { MessageBox.Show($"meta行未指定table名"); return; @@ -119,7 +132,9 @@ namespace LubanAssistant { try { - await LoadUtil.LoadTableDataToCurrentWorkSheetAsync(RootDefineFile, InputDataDir, tableName); + var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(RootDefineFile, InputDataDir, tableName); + var title = ExcelUtil.ParseTitles(sheet); + ExcelUtil.FillRecords(sheet, metaAttrs, title, tableDataInfo); } catch (Exception e) { diff --git a/src/LubanAssistant/ExcelUtil.cs b/src/LubanAssistant/ExcelUtil.cs new file mode 100644 index 0000000..cebc9a7 --- /dev/null +++ b/src/LubanAssistant/ExcelUtil.cs @@ -0,0 +1,166 @@ +using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataSources.Excel; +using Luban.Job.Cfg.Defs; +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LubanAssistant +{ + static class ExcelUtil + { + public static Dictionary<string, string> ParseMetaAttrs(Worksheet sheet) + { + Range metaRow = sheet.Rows[1]; + if (metaRow.Cells[1, 1].Text.ToString() != "##") + { + throw new Exception("A1 should be ##"); + } + var metaAttrs = new Dictionary<string, string>(); + for (int i = 2, n = sheet.UsedRange.Columns.Count; i <= n; i++) + { + Range cell = metaRow.Cells[1, i]; + string value = cell.Value?.ToString(); + if (!string.IsNullOrWhiteSpace(value)) + { + var attrs = value.Split('='); + if (attrs.Length != 2) + { + throw new Exception($"invalid meta attr:{value}"); + } + metaAttrs.Add(attrs[0], attrs[1]); + } + } + return metaAttrs; + } + + public static TitleInfo ParseTitles(Worksheet sheet) + { + + int titleRows = 1; + Range c1 = sheet.Cells[2, 1]; + if (c1.MergeCells) + { + titleRows = c1.MergeArea.Count; + } + + + var rootTile = new Title() + { + FromIndex = 2, + ToIndex = sheet.UsedRange.Columns.Count, + Name = "__root__", + Root = true, + }; + ParseSubTitle(sheet, 2, titleRows + 1, rootTile); + return new TitleInfo(rootTile, titleRows); + } + + private static void ParseSubTitle(Worksheet sheet, int rowIndex, int maxRowIndex, Title title) + { + Range row = sheet.Rows[rowIndex]; + for (int i = title.FromIndex; i <= title.ToIndex; i++) + { + Range subTitleRange = row.Cells[1, i]; + string subTitleValue = subTitleRange.Value?.ToString(); + if (string.IsNullOrWhiteSpace(subTitleValue)) + { + continue; + } + + var attrs = subTitleValue.Split('&'); + string subTitleName = attrs[0]; + string sep = ""; + foreach (var attrPair in attrs.Skip(1)) + { + var pairs = attrPair.Split('='); + if (pairs.Length != 2) + { + throw new Exception($"invalid title: {subTitleValue}"); + } + switch (pairs[0]) + { + case "sep": + { + sep = pairs[1]; + break; + } + default: + { + throw new Exception($"invalid title: {subTitleValue}"); + } + } + } + + if (title.SubTitles.ContainsKey(subTitleName)) + { + throw new Exception($"title:{subTitleName} 重复"); + } + var newSubTitle = new Title() + { + Name = subTitleName, + FromIndex = i, + ToIndex = i, + }; + if (!string.IsNullOrWhiteSpace(sep)) + { + newSubTitle.Sep = sep; + } + if (subTitleRange.MergeCells) + { + newSubTitle.ToIndex = i + subTitleRange.MergeArea.Count - 1; + } + else + { + newSubTitle.ToIndex = i; + } + title.SubTitles.Add(subTitleName, newSubTitle); + } + title.SubTitleList.AddRange(title.SubTitles.Values); + if (rowIndex < maxRowIndex) + { + foreach (var subTitle in title.SubTitleList) + { + ParseSubTitle(sheet, rowIndex + 1, maxRowIndex, subTitle); + } + } + } + + public static void FillRecords(Worksheet sheet, Dictionary<string, string> metaAttrs, TitleInfo title, TableDataInfo tableDataInfo) + { + int titleRowNum = 3; + if (metaAttrs.TryGetValue("title_rows", out var titleRowsStr) && !int.TryParse(titleRowsStr, out titleRowNum)) + { + throw new Exception($"meta 属性 title_rows 不合法"); + } + if (titleRowNum < title.RowNum) + { + throw new Exception($"meta 属性title_rows不能比字段名行的行数小"); + } + int usedRowNum = sheet.UsedRange.Rows.Count; + if (usedRowNum > titleRowNum + 1) + { + Range allDataRange = sheet.Range[$"A{titleRowNum + 2},A{usedRowNum}"].EntireRow; + allDataRange.ClearContents(); + } + + int nextRowIndex = titleRowNum + 2; + + foreach (var rec in tableDataInfo.MainRecords) + { + var fillVisitor = new FillSheetVisitor(sheet, nextRowIndex); + //FillRecord(sheet, ref nextRowIndex, title.RootTitle, rec); + nextRowIndex += rec.Data.Apply(fillVisitor, title.RootTitle); + } + } + + //public static void FillRecord(Worksheet sheet, ref int nextRowIndex, Title title, Record record) + //{ + + // nextRowIndex += FillField(sheet, nextRowIndex, title, record.Data); + //} + } +} diff --git a/src/LubanAssistant/FillSheetVisitor.cs b/src/LubanAssistant/FillSheetVisitor.cs new file mode 100644 index 0000000..1ba24a9 --- /dev/null +++ b/src/LubanAssistant/FillSheetVisitor.cs @@ -0,0 +1,232 @@ +using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.DataSources.Excel; +using Luban.Job.Cfg.DataVisitors; +using Luban.Job.Cfg.Defs; +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LubanAssistant +{ + class FillSheetVisitor : IDataFuncVisitor<Title, int> + { + private readonly Worksheet _sheet; + + private readonly Range _cells; + + private readonly int _startRowIndex; + + public FillSheetVisitor(Worksheet sheet, int startRowIndex) + { + _sheet = sheet; + _cells = sheet.Cells; + _startRowIndex = startRowIndex; + } + + public int Accept(DBool type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DByte type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DShort type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DFshort type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DInt type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DFint type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DLong type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DFlong type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DFloat type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DDouble type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DEnum type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.StrValue; + return 1; + } + + public int Accept(DString type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Value; + return 1; + } + + public int Accept(DBytes type, Title x) + { + throw new NotImplementedException(); + } + + 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; + return 1; + } + + public int Accept(DBean type, Title x) + { + if (x.SubTitleList.Count > 0) + { + if (type.Type.IsAbstractType) + { + if (!x.SubTitles.TryGetValue(DefBean.TYPE_NAME_KEY, out var typeTitle)) + { + throw new Exception($"多态bean:{type.Type.FullName} 缺失 __type__ 标题列"); + } + if (type.ImplType != null) + { + (_cells[_startRowIndex, typeTitle.FromIndex] as Range).Value = type.ImplType.Name; + } + else + { + (_cells[_startRowIndex, typeTitle.FromIndex] as Range).Value = DefBean.BEAN_NULL_STR; + } + } + else + { + if (type.ImplType != null) + { + + } + else + { + //(_cells[_startRowIndex, x.FromIndex] as Range).Value = "null"; + throw new Exception($"title:{x.Name} 不支持 值为null的普通bean"); + } + } + if (type.ImplType != null) + { + int index = 0; + foreach (var field in type.ImplType.HierarchyFields) + { + var data = type.Fields[index++]; + if (!x.SubTitles.TryGetValue(field.Name, out var fieldTitle)) + { + throw new Exception($"title:{x.Name} 子title:{field.Name} 缺失"); + } + + if (data != null) + { + //if (fieldTitle.SubTitleList.Count > 0) + //{ + data.Apply(this, fieldTitle); + //} + //else + //{ + + // (_cells[_startRowIndex, fieldTitle.FromIndex] as Range).Value = data.Apply(ToExcelStringVisitor.Ins, fieldTitle.Sep); + //} + } + } + } + } + else + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + } + return 1; + } + + public int Accept(DArray type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + return 1; + } + + public int Accept(DList type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + return 1; + } + + public int Accept(DSet type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + return 1; + } + + public int Accept(DMap type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep); + return 1; + } + + public int Accept(DVector2 type, Title x) + { + var v = type.Value; + (_cells[_startRowIndex, x.FromIndex] as Range).Value = $"{v.X},{v.Y}"; + return 1; + } + + public int Accept(DVector3 type, Title x) + { + var v = type.Value; + (_cells[_startRowIndex, x.FromIndex] as Range).Value = $"{v.X},{v.Y},{v.Z}"; + return 1; + } + + public int Accept(DVector4 type, Title x) + { + var v = type.Value; + (_cells[_startRowIndex, x.FromIndex] as Range).Value = $"{v.X},{v.Y},{v.Z},{v.W}"; + return 1; + } + + public int Accept(DDateTime type, Title x) + { + (_cells[_startRowIndex, x.FromIndex] as Range).Value = type.Time; + return 1; + } + } +} diff --git a/src/LubanAssistant/LoadUtil.cs b/src/LubanAssistant/LoadUtil.cs index 3d6fc26..3661d28 100644 --- a/src/LubanAssistant/LoadUtil.cs +++ b/src/LubanAssistant/LoadUtil.cs @@ -1,8 +1,10 @@ using Bright.Common; +using Bright.Time; using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Utils; using Luban.Job.Common.Defs; using Luban.Server.Common; +using Microsoft.Office.Interop.Excel; using System; using System.Collections.Generic; using System.Linq; @@ -19,9 +21,6 @@ namespace LubanAssistant var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(rootDefineFile, inputDataDir, tableName); Console.WriteLine("load record num:{0}", tableDataInfo.MainRecords.Count); - - Microsoft.Office.Interop.Excel.Worksheet cur = Globals.LubanAssistant.Application.ActiveSheet; - Console.WriteLine("== active sheet name:{0}", cur.Name); } } } diff --git a/src/LubanAssistant/LubanAssistant.csproj b/src/LubanAssistant/LubanAssistant.csproj index 99e391f..a3a084e 100644 --- a/src/LubanAssistant/LubanAssistant.csproj +++ b/src/LubanAssistant/LubanAssistant.csproj @@ -270,6 +270,9 @@ <Compile Include="..\Luban.Job.Cfg\Source\DataSources\Excel\Sheet.cs"> <Link>Source\DataSources\Excel\Sheet.cs</Link> </Compile> + <Compile Include="..\Luban.Job.Cfg\Source\DataSources\Excel\Title.cs"> + <Link>Source\DataSources\Excel\Title.cs</Link> + </Compile> <Compile Include="..\Luban.Job.Cfg\Source\DataSources\Json\JsonDataSource.cs"> <Link>Source\DataSources\Json\JsonDataSource.cs</Link> </Compile> @@ -531,10 +534,13 @@ <Compile Include="AssistantTab.Designer.cs"> <DependentUpon>AssistantTab.cs</DependentUpon> </Compile> + <Compile Include="ExcelUtil.cs" /> + <Compile Include="FillSheetVisitor.cs" /> <Compile Include="LoadUtil.cs" /> <Compile Include="Properties\AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="ToExcelStringVisitor.cs" /> <EmbeddedResource Include="AssistantTab.resx"> <DependentUpon>AssistantTab.cs</DependentUpon> </EmbeddedResource> @@ -559,6 +565,7 @@ <DependentUpon>Settings.settings</DependentUpon> <DesignTimeSharedInput>True</DesignTimeSharedInput> </Compile> + <Compile Include="Source\DataSources\Excel\TitleInfo.cs" /> <Compile Include="Source\Utils\AtomicLong.cs" /> <Compile Include="Source\Utils\CacheFileUtil.cs" /> <Compile Include="Source\Collections\CollectionExtension.cs" /> diff --git a/src/LubanAssistant/Source/DataSources/Excel/TitleInfo.cs b/src/LubanAssistant/Source/DataSources/Excel/TitleInfo.cs new file mode 100644 index 0000000..9456852 --- /dev/null +++ b/src/LubanAssistant/Source/DataSources/Excel/TitleInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.DataSources.Excel +{ + class TitleInfo + { + public Title RootTitle { get; } + + public int RowNum { get; } + + public TitleInfo(Title rootTitle, int rowNum) + { + RootTitle = rootTitle; + RowNum = rowNum; + } + } +} diff --git a/src/LubanAssistant/ToExcelStringVisitor.cs b/src/LubanAssistant/ToExcelStringVisitor.cs new file mode 100644 index 0000000..e1ceec9 --- /dev/null +++ b/src/LubanAssistant/ToExcelStringVisitor.cs @@ -0,0 +1,155 @@ +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.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LubanAssistant +{ + class ToExcelStringVisitor : IDataFuncVisitor<string, string> + { + public static ToExcelStringVisitor Ins { get; } = new(); + + public string Accept(DBool type, string sep) + { + return type.Value ? "true" : "false"; + } + + public string Accept(DByte type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DShort type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DFshort type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DInt type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DFint type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DLong type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DFlong type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DFloat type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DDouble type, string sep) + { + return type.Value.ToString(); + } + + public string Accept(DEnum type, string sep) + { + return type.StrValue; + } + + private string Enscape(string s) + { + return string.IsNullOrEmpty(s) ? "\"\"" : s; + } + + public string Accept(DString type, string sep) + { + return Enscape(type.Value.ToString()); + } + + public string Accept(DBytes type, string sep) + { + throw new NotImplementedException(); + } + + public string Accept(DText type, string sep) + { + return $"{Enscape(type.Key)}{sep}{Enscape(type.RawValue)}"; + } + + public string Accept(DBean type, string sep) + { + var sb = new List<string>(); + if (type.Type.IsAbstractType) + { + sb.Add(type.ImplType != null ? type.ImplType.Name : DefBean.BEAN_NULL_STR); + } + + foreach (var field in type.Fields) + { + if (field == null) + { + sb.Add("null"); + continue; + } + sb.Add(field.Apply(this, sep)); + } + return string.Join(sep, sb); + } + + public string Accept(DArray type, string sep) + { + return string.Join(sep, type.Datas.Select(d => d.Apply(this, sep))); + } + + public string Accept(DList type, string sep) + { + return string.Join(sep, type.Datas.Select(d => d.Apply(this, sep))); + } + + public string Accept(DSet type, string sep) + { + return string.Join(sep, type.Datas.Select(d => d.Apply(this, sep))); + } + + public string Accept(DMap type, string sep) + { + return string.Join(sep, type.Datas.Select(d => $"{d.Key.Apply(this, sep)}{sep}{d.Value.Apply(this, sep)}")); + } + + public string Accept(DVector2 type, string sep) + { + var v = type.Value; + return $"{v.X},{v.Y}"; + } + + public string Accept(DVector3 type, string sep) + { + var v = type.Value; + return $"{v.X},{v.Y},{v.Z}"; + } + + public string Accept(DVector4 type, string sep) + { + var v = type.Value; + return $"{v.X},{v.Y},{v.Z},{v.W}"; + } + + public string Accept(DDateTime type, string sep) + { + return DataUtil.FormatDateTime(type.Time); + } + } +}