luban/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs

205 lines
6.4 KiB
C#

using Bright.Collections;
using ExcelDataReader;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using Luban.Job.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Cfg.DataSources.Excel
{
class Sheet
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
public string Name { get; }
public string RawUrl { get; }
public List<(string Tag, TitleRow Row)> Rows { get; } = new();
public Sheet(string rawUrl, string name)
{
this.RawUrl = rawUrl;
this.Name = name;
}
private string GetRowTag(List<Cell> row)
{
return row.Count > 0 ? row[0].Value?.ToString() ?? "" : "";
}
public void Load(RawSheet rawSheet)
{
var cells = rawSheet.Cells;
Title title = rawSheet.Title;
if (!title.HierarchyMultiRows)
{
foreach (var row in cells)
{
if (IsBlankRow(row, title.FromIndex, title.ToIndex))
{
continue;
}
Rows.Add((GetRowTag(row), ParseOneLineTitleRow(title, row)));
}
}
else
{
foreach (var oneRecordRows in SplitRows(title, cells))
{
Rows.Add((GetRowTag(oneRecordRows[0]), ParseMultiLineTitleRow(title, oneRecordRows)));
}
}
}
private TitleRow ParseOneLineTitleRow(Title title, List<Cell> row)
{
if (title.SubTitleList.Count == 0)
{
return new TitleRow(title, row);
}
Dictionary<string, TitleRow> fields = new();
foreach (var subTitle in title.SubTitleList)
{
fields.Add(subTitle.Name, ParseOneLineTitleRow(subTitle, row));
}
return new TitleRow(title, fields);
}
private static bool IsMultiRowsExtendRow(List<Cell> row, Title title)
{
if (title.HasSubTitle)
{
foreach (var t in title.SubTitleList)
{
if (!t.SelfMultiRows && !IsMultiRowsExtendRow(row, t))
{
return false;
}
}
//return title.SubTitleList.All(t => t.SelfMultiRows || IsMultiRowsExtendRow(row, t));
return true;
}
else
{
return IsBlankRow(row, title.FromIndex, title.ToIndex);
}
}
private IEnumerable<List<List<Cell>>> SplitRows(Title title, List<List<Cell>> rows)
{
List<List<Cell>> oneRecordRows = null;
foreach (var row in rows)
{
if (IsBlankRow(row, title.FromIndex, title.ToIndex))
{
continue;
}
if (oneRecordRows == null)
{
oneRecordRows = new List<List<Cell>>() { row };
}
else
{
if (IsMultiRowsExtendRow(row, title))
{
oneRecordRows.Add(row);
}
else
{
yield return oneRecordRows;
oneRecordRows = new List<List<Cell>>() { row };
}
}
}
if (oneRecordRows != null)
{
yield return oneRecordRows;
}
}
private TitleRow ParseMultiLineTitleRow(Title title, List<List<Cell>> rows)
{
if (title.SubTitleList.Count == 0)
{
if (title.SelfMultiRows)
{
return new TitleRow(title, rows);
}
else
{
return new TitleRow(title, rows[0]);
}
}
else
{
var fields = new Dictionary<string, TitleRow>();
foreach (var subTitle in title.SubTitleList)
{
if (subTitle.SelfMultiRows)
{
var eles = new List<TitleRow>();
if (subTitle.SubHierarchyMultiRows)
{
foreach (var eleRows in SplitRows(subTitle, rows))
{
eles.Add(ParseMultiLineTitleRow(subTitle, eleRows));
}
}
else
{
foreach (var eleRow in rows)
{
if (IsBlankRow(eleRow, subTitle.FromIndex, subTitle.ToIndex))
{
continue;
}
eles.Add(ParseOneLineTitleRow(subTitle, eleRow));
}
}
fields.Add(subTitle.Name, new TitleRow(subTitle, eles));
}
else
{
if (subTitle.SubHierarchyMultiRows)
{
fields.Add(subTitle.Name, ParseMultiLineTitleRow(subTitle, rows));
}
else
{
fields.Add(subTitle.Name, ParseOneLineTitleRow(subTitle, rows[0]));
}
}
}
return new TitleRow(title, fields);
}
}
public IEnumerable<(string Tag, TitleRow Row)> GetRows()
{
return Rows;
}
public static bool IsBlankRow(List<Cell> row, int fromIndex, int toIndex)
{
for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row.Count - 1); i <= n; i++)
{
var v = row[i].Value;
if (v != null && !(v is string s && string.IsNullOrEmpty(s)))
{
return false;
}
}
return true;
}
}
}