【优化】大幅优化了 LubanAssistant加载和保存的速度(慢如牛到闪电)
parent
7d4b9e049d
commit
fb55a7a4c6
|
|
@ -12,6 +12,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace LubanAssistant
|
namespace LubanAssistant
|
||||||
{
|
{
|
||||||
|
|
@ -32,12 +33,14 @@ namespace LubanAssistant
|
||||||
Title title = ParseTitles(sheet);
|
Title title = ParseTitles(sheet);
|
||||||
var cells = new List<List<Cell>>();
|
var cells = new List<List<Cell>>();
|
||||||
|
|
||||||
foreach (Range row in toSaveRecordRows)
|
var rangeAsArray = (object[,])toSaveRecordRows.Value;
|
||||||
|
int lowBound0 = rangeAsArray.GetLowerBound(0);
|
||||||
|
for (int r = lowBound0, n = r + rangeAsArray.GetLength(0); r < n; r++)
|
||||||
{
|
{
|
||||||
var rowCell = new List<Cell>();
|
var rowCell = new List<Cell>();
|
||||||
for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
||||||
{
|
{
|
||||||
rowCell.Add(new Cell(row.Row - 1, i, (row.Cells[1, i + 1] as Range).Value));
|
rowCell.Add(new Cell(r - 1, i, rangeAsArray[r, i + 1]));
|
||||||
}
|
}
|
||||||
cells.Add(rowCell);
|
cells.Add(rowCell);
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +93,7 @@ namespace LubanAssistant
|
||||||
Tags = new Dictionary<string, string>(),
|
Tags = new Dictionary<string, string>(),
|
||||||
};
|
};
|
||||||
ParseSubTitle(sheet, 2, titleRows + 1, rootTile);
|
ParseSubTitle(sheet, 2, titleRows + 1, rootTile);
|
||||||
|
rootTile.ToIndex = rootTile.SubTitleList.Max(t => t.ToIndex);
|
||||||
rootTile.Init();
|
rootTile.Init();
|
||||||
return rootTile;
|
return rootTile;
|
||||||
}
|
}
|
||||||
|
|
@ -140,18 +144,32 @@ namespace LubanAssistant
|
||||||
int usedRowNum = sheet.UsedRange.Rows.Count;
|
int usedRowNum = sheet.UsedRange.Rows.Count;
|
||||||
if (usedRowNum > titleRowNum + 1)
|
if (usedRowNum > titleRowNum + 1)
|
||||||
{
|
{
|
||||||
//Range allDataRange = sheet.Range[sheet.Cells[titleRowNum + 1, 1], sheet.Cells[$"A{titleRowNum + 2},A{usedRowNum}"].EntireRow;
|
|
||||||
Range allDataRange = sheet.Range[sheet.Cells[titleRowNum + 2, 1], sheet.Cells[usedRowNum, sheet.UsedRange.Columns.Count]];
|
Range allDataRange = sheet.Range[sheet.Cells[titleRowNum + 2, 1], sheet.Cells[usedRowNum, sheet.UsedRange.Columns.Count]];
|
||||||
allDataRange.ClearContents();
|
allDataRange.ClearContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextRowIndex = titleRowNum + 2;
|
//int nextRowIndex = titleRowNum + 2;
|
||||||
|
|
||||||
|
int totalRowCount = 0;
|
||||||
|
var dataRangeArray = new List<object[]>();
|
||||||
foreach (var rec in tableDataInfo.MainRecords)
|
foreach (var rec in tableDataInfo.MainRecords)
|
||||||
{
|
{
|
||||||
var fillVisitor = new FillSheetVisitor(sheet, nextRowIndex);
|
var fillVisitor = new FillSheetVisitor(dataRangeArray, title.ToIndex + 1, totalRowCount);
|
||||||
nextRowIndex += rec.Data.Apply(fillVisitor, title);
|
totalRowCount += rec.Data.Apply(fillVisitor, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object[,] resultDataRangeArray = new object[dataRangeArray.Count, title.ToIndex + 1];
|
||||||
|
for (int i = 0; i < dataRangeArray.Count; i++)
|
||||||
|
{
|
||||||
|
object[] row = dataRangeArray[i];
|
||||||
|
for (int j = 0; j < row.Length; j++)
|
||||||
|
{
|
||||||
|
resultDataRangeArray[i, j] = row[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Range recordFillRange = sheet.Range[sheet.Cells[titleRowNum + 2, 1], sheet.Cells[titleRowNum + dataRangeArray.Count, title.ToIndex + 1]];
|
||||||
|
recordFillRange.Value = resultDataRangeArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Record> LoadRecordsInRange(DefTable table, Worksheet sheet, Title title, Range toSaveRecordRows)
|
public static List<Record> LoadRecordsInRange(DefTable table, Worksheet sheet, Title title, Range toSaveRecordRows)
|
||||||
|
|
|
||||||
|
|
@ -13,90 +13,98 @@ namespace LubanAssistant
|
||||||
{
|
{
|
||||||
class FillSheetVisitor : IDataFuncVisitor<Title, int>
|
class FillSheetVisitor : IDataFuncVisitor<Title, int>
|
||||||
{
|
{
|
||||||
private readonly Worksheet _sheet;
|
|
||||||
|
|
||||||
private readonly Range _cells;
|
private readonly List<object[]> _cells;
|
||||||
|
|
||||||
|
private readonly int _columnSize;
|
||||||
private int _startRowIndex;
|
private int _startRowIndex;
|
||||||
|
|
||||||
public FillSheetVisitor(Worksheet sheet, int startRowIndex)
|
public FillSheetVisitor(List<object[]> cells, int columnSize, int startRowIndex)
|
||||||
{
|
{
|
||||||
_sheet = sheet;
|
_cells = cells;
|
||||||
_cells = sheet.Cells;
|
_columnSize = columnSize;
|
||||||
_startRowIndex = startRowIndex;
|
_startRowIndex = startRowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Range Current(Title title) => _cells[_startRowIndex, title.FromIndex + 1] as Range;
|
void SetTitleValue(Title title, object value)
|
||||||
|
{
|
||||||
|
while (_cells.Count <= _startRowIndex)
|
||||||
|
{
|
||||||
|
var row = new object[_columnSize];
|
||||||
|
_cells.Add(row);
|
||||||
|
}
|
||||||
|
_cells[_startRowIndex][title.FromIndex] = value;
|
||||||
|
}
|
||||||
|
|
||||||
public int Accept(DBool type, Title x)
|
public int Accept(DBool type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DByte type, Title x)
|
public int Accept(DByte type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DShort type, Title x)
|
public int Accept(DShort type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DFshort type, Title x)
|
public int Accept(DFshort type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DInt type, Title x)
|
public int Accept(DInt type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DFint type, Title x)
|
public int Accept(DFint type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DLong type, Title x)
|
public int Accept(DLong type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DFlong type, Title x)
|
public int Accept(DFlong type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DFloat type, Title x)
|
public int Accept(DFloat type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DDouble type, Title x)
|
public int Accept(DDouble type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DEnum type, Title x)
|
public int Accept(DEnum type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.StrValue;
|
SetTitleValue(x, type.StrValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DString type, Title x)
|
public int Accept(DString type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Value;
|
SetTitleValue(x, type.Value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +119,7 @@ namespace LubanAssistant
|
||||||
//{
|
//{
|
||||||
// throw new Exception($"title:{x.Name}为text类型,至少要占两列");
|
// throw new Exception($"title:{x.Name}为text类型,至少要占两列");
|
||||||
//}
|
//}
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
//(_cells[_startRowIndex, x.FromIndex + 1] as Range).Value = type.RawValue;
|
//(_cells[_startRowIndex, x.FromIndex + 1] as Range).Value = type.RawValue;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -129,11 +137,11 @@ namespace LubanAssistant
|
||||||
}
|
}
|
||||||
if (type.ImplType != null)
|
if (type.ImplType != null)
|
||||||
{
|
{
|
||||||
Current(typeTitle).Value = type.ImplType.Name;
|
SetTitleValue(typeTitle, type.ImplType.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Current(typeTitle).Value = DefBean.BEAN_NULL_STR;
|
SetTitleValue(typeTitle, DefBean.BEAN_NULL_STR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -178,7 +186,7 @@ namespace LubanAssistant
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +213,7 @@ namespace LubanAssistant
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,47 +240,47 @@ namespace LubanAssistant
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DSet type, Title x)
|
public int Accept(DSet type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DMap type, Title x)
|
public int Accept(DMap type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Apply(ToExcelStringVisitor.Ins, x.Sep);
|
SetTitleValue(x, type.Apply(ToExcelStringVisitor.Ins, x.Sep));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DVector2 type, Title x)
|
public int Accept(DVector2 type, Title x)
|
||||||
{
|
{
|
||||||
var v = type.Value;
|
var v = type.Value;
|
||||||
Current(x).Value = $"{v.X},{v.Y}";
|
SetTitleValue(x, $"{v.X},{v.Y}");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DVector3 type, Title x)
|
public int Accept(DVector3 type, Title x)
|
||||||
{
|
{
|
||||||
var v = type.Value;
|
var v = type.Value;
|
||||||
Current(x).Value = $"{v.X},{v.Y},{v.Z}";
|
SetTitleValue(x, $"{v.X},{v.Y},{v.Z}");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DVector4 type, Title x)
|
public int Accept(DVector4 type, Title x)
|
||||||
{
|
{
|
||||||
var v = type.Value;
|
var v = type.Value;
|
||||||
Current(x).Value = $"{v.X},{v.Y},{v.Z},{v.W}";
|
SetTitleValue(x, $"{v.X},{v.Y},{v.Z},{v.W}");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Accept(DDateTime type, Title x)
|
public int Accept(DDateTime type, Title x)
|
||||||
{
|
{
|
||||||
Current(x).Value = type.Time;
|
SetTitleValue(x, type.Time);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue