【完善】LubanAssistant 能够正确从json或者其他配置文件中加载配置,并且填充到excel中
parent
4e7c993d53
commit
f22dc45273
|
|
@ -270,3 +270,4 @@ __pycache__/
|
||||||
/config/output_lua
|
/config/output_lua
|
||||||
/config/output_lua_without_test
|
/config/output_lua_without_test
|
||||||
/src/Excel2TextDiff/Properties/launchSettings.json
|
/src/Excel2TextDiff/Properties/launchSettings.json
|
||||||
|
/src/packages
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
foreach (DefField f in bean.HierarchyFields)
|
foreach (DefField f in bean.HierarchyFields)
|
||||||
{
|
{
|
||||||
string fname = f.Name;
|
string fname = f.Name;
|
||||||
Sheet.Title title = row.GetTitle(fname);
|
Title title = row.GetTitle(fname);
|
||||||
if (title == null)
|
if (title == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"bean:'{bean.FullName}' 缺失 列:'{fname}',请检查是否写错或者遗漏");
|
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<Cell>();
|
var cells = new List<Cell>();
|
||||||
for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
||||||
|
|
|
||||||
|
|
@ -38,46 +38,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public List<List<Cell>> RowColumns => _rowColumns;
|
public List<List<Cell>> 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<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)}]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NamedRow
|
public class NamedRow
|
||||||
{
|
{
|
||||||
|
|
@ -336,6 +297,10 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
HeaderRowCount = v;
|
HeaderRowCount = v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "table":
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
throw new Exception($"非法单元薄 meta 属性定义 {attr}, 合法属性有: orientation=r|row|c|column,title_rows=<number>");
|
throw new Exception($"非法单元薄 meta 属性定义 {attr}, 合法属性有: orientation=r|row|c|column,title_rows=<number>");
|
||||||
|
|
|
||||||
|
|
@ -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)}]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,6 +62,11 @@ namespace Luban.Job.Cfg.Utils
|
||||||
return new DDateTime(dateTime);
|
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)
|
public static byte[] StreamToBytes(Stream stream)
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[stream.Length];
|
byte[] bytes = new byte[stream.Length];
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using Luban.Job.Cfg.Utils;
|
using Luban.Job.Cfg.Utils;
|
||||||
using Luban.Job.Common.Defs;
|
using Luban.Job.Common.Defs;
|
||||||
using Luban.Server.Common;
|
using Luban.Server.Common;
|
||||||
|
using Microsoft.Office.Interop.Excel;
|
||||||
using Microsoft.Office.Tools.Ribbon;
|
using Microsoft.Office.Tools.Ribbon;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
@ -101,15 +102,27 @@ namespace LubanAssistant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private bool TryGetTableName(out string tableName)
|
private bool TryGetTableName(out string tableName)
|
||||||
{
|
{
|
||||||
tableName = "test.TbExcelFromJson";
|
Worksheet cur = Globals.LubanAssistant.Application.ActiveSheet;
|
||||||
|
var metaAttrs = ExcelUtil.ParseMetaAttrs(cur);
|
||||||
|
if (metaAttrs.TryGetValue("table", out tableName))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
tableName = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void LoadDataToCurrentDoc()
|
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名");
|
MessageBox.Show($"meta行未指定table名");
|
||||||
return;
|
return;
|
||||||
|
|
@ -119,7 +132,9 @@ namespace LubanAssistant
|
||||||
{
|
{
|
||||||
try
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using Bright.Common;
|
using Bright.Common;
|
||||||
|
using Bright.Time;
|
||||||
using Luban.Job.Cfg.Defs;
|
using Luban.Job.Cfg.Defs;
|
||||||
using Luban.Job.Cfg.Utils;
|
using Luban.Job.Cfg.Utils;
|
||||||
using Luban.Job.Common.Defs;
|
using Luban.Job.Common.Defs;
|
||||||
using Luban.Server.Common;
|
using Luban.Server.Common;
|
||||||
|
using Microsoft.Office.Interop.Excel;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -19,9 +21,6 @@ namespace LubanAssistant
|
||||||
var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(rootDefineFile, inputDataDir, tableName);
|
var tableDataInfo = await DataLoaderUtil.LoadTableDataAsync(rootDefineFile, inputDataDir, tableName);
|
||||||
|
|
||||||
Console.WriteLine("load record num:{0}", tableDataInfo.MainRecords.Count);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -270,6 +270,9 @@
|
||||||
<Compile Include="..\Luban.Job.Cfg\Source\DataSources\Excel\Sheet.cs">
|
<Compile Include="..\Luban.Job.Cfg\Source\DataSources\Excel\Sheet.cs">
|
||||||
<Link>Source\DataSources\Excel\Sheet.cs</Link>
|
<Link>Source\DataSources\Excel\Sheet.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Luban.Job.Cfg\Source\DataSources\Json\JsonDataSource.cs">
|
||||||
<Link>Source\DataSources\Json\JsonDataSource.cs</Link>
|
<Link>Source\DataSources\Json\JsonDataSource.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
@ -531,10 +534,13 @@
|
||||||
<Compile Include="AssistantTab.Designer.cs">
|
<Compile Include="AssistantTab.Designer.cs">
|
||||||
<DependentUpon>AssistantTab.cs</DependentUpon>
|
<DependentUpon>AssistantTab.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ExcelUtil.cs" />
|
||||||
|
<Compile Include="FillSheetVisitor.cs" />
|
||||||
<Compile Include="LoadUtil.cs" />
|
<Compile Include="LoadUtil.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs">
|
<Compile Include="Properties\AssemblyInfo.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ToExcelStringVisitor.cs" />
|
||||||
<EmbeddedResource Include="AssistantTab.resx">
|
<EmbeddedResource Include="AssistantTab.resx">
|
||||||
<DependentUpon>AssistantTab.cs</DependentUpon>
|
<DependentUpon>AssistantTab.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
@ -559,6 +565,7 @@
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\DataSources\Excel\TitleInfo.cs" />
|
||||||
<Compile Include="Source\Utils\AtomicLong.cs" />
|
<Compile Include="Source\Utils\AtomicLong.cs" />
|
||||||
<Compile Include="Source\Utils\CacheFileUtil.cs" />
|
<Compile Include="Source\Utils\CacheFileUtil.cs" />
|
||||||
<Compile Include="Source\Collections\CollectionExtension.cs" />
|
<Compile Include="Source\Collections\CollectionExtension.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue