Files
SzmediTools/Szmedi.RvKits/Assists/ExcelReaderExtensions.cs

135 lines
5.5 KiB
C#
Raw Normal View History

2025-09-16 16:06:41 +08:00

using System.Globalization;
using System.Linq;
using OfficeOpenXml;
using Szmedi.Toolkit.Assists;
namespace Szmedi.RvKits.Assists
{
public static class ExcelReaderExtensions
{
public static IEnumerable<T> Read<T>(this ExcelWorksheet sheet, int headerIndex = 1, Type type = null)
where T : new()
{
var results = new List<T>();
if (sheet == null)
{
return results;
}
var mapClass = type ?? AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => a.FullName.StartsWith("Namespace"))
.SelectMany(i => i.GetTypes().Where(i => i.IsClass && typeof(BaseTypeConfiguration<T>).IsAssignableFrom(i)))
.FirstOrDefault();
var instance = (BaseTypeConfiguration<T>)Activator.CreateInstance(mapClass);
var mappings = instance.GetMappings();
var rows = sheet.Dimension.Rows;
var cols = new List<(int index, string name, PropertyConfiguration propertyConfiguration)>();
for (var i = 1; i < sheet.Dimension.Columns; i++)
{
var col = mappings.FirstOrDefault(a => !string.IsNullOrEmpty(a.Name) && a.Name == (string)sheet.Cells[headerIndex, i].Value);
if (col != null)
{
cols.Add((index: i, name: col.Name, propertyConfiguration: col));
}
}
if (cols.Any())
{
mappings.Where(x => x.DefaultValue != null)
.ToList()
.ForEach(map =>
{
cols.Add((index: cols.Max(x => x.index) + 1, name: map.Name, propertyConfiguration: map));
});
}
for (var i = ++headerIndex; i <= rows; i++)
{
var t = new T();
for (var j = 0; j < cols.Count; j++)
{
var property = cols[j];
var propertyInfo = t.GetType().GetProperty(property.propertyConfiguration.Member.Name);
if (property.propertyConfiguration.DefaultValue != null)
{
propertyInfo.SetValue(t, property.propertyConfiguration.DefaultValue);
}
else
{
var value = Cast(sheet.Cells[i, property.index].Value, propertyInfo.PropertyType, property.propertyConfiguration);
if (propertyInfo.PropertyType.IsEnum && value != null)
{
propertyInfo.SetValue(t, Enum.Parse(propertyInfo.PropertyType, value.ToString()));
}
else
{
propertyInfo.SetValue(t, value);
}
}
}
results.Add(t);
}
return results;
}
private static object Cast(object value, Type propertyType, PropertyConfiguration propertyConfiguration)
{
if (value == null)
{
return null;
}
if (propertyType == typeof(byte) || propertyType == typeof(byte?))
{
byte.TryParse(propertyConfiguration.StringFormatFunc == null ? value.ToString() : propertyConfiguration.StringFormatFunc(value.ToString()), out var result);
return result;
}
else if (propertyType == typeof(int))
{
int.TryParse(propertyConfiguration.StringFormatFunc == null ? value.ToString() : propertyConfiguration.StringFormatFunc(value.ToString()), out var result);
return result;
}
else if (propertyType == typeof(short))
{
short.TryParse(propertyConfiguration.StringFormatFunc == null ? value.ToString() : propertyConfiguration.StringFormatFunc(value.ToString()), out var result);
return result;
}
else
{
return propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)
? propertyConfiguration.DateFormatFunc != null ? propertyConfiguration.DateFormatFunc(value.ToString()) : value
: propertyType == typeof(double) || propertyType == typeof(double?)
|| propertyType == typeof(decimal) || propertyType == typeof(decimal?)
? propertyConfiguration.DecimalFormatFunc != null
? propertyConfiguration.DecimalFormatFunc(value.ToString())
: (object)value.ToString().ToDecimal()
: propertyConfiguration.StringFormatFunc != null
? propertyConfiguration.StringFormatFunc(value.ToString())
: (object)value.ToString().Trim();
}
}
private static decimal ToDecimal(this string value, CultureInfo cultureInfo = null)
{
decimal.TryParse(value, NumberStyles.Any, cultureInfo ?? CultureInfo.InvariantCulture, out var decimalValue);
return decimalValue;
}
}
}