Files
zszq-trs/YLErpDAL/Helpers/CsvConverts.cs
2024-05-09 14:06:26 +08:00

426 lines
15 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
namespace YLErp.Helpers
{
/// <summary>
/// csv值转换器
/// </summary>
static class CsvTypeConverts
{
/// <summary>
/// 文本转换器(自带trim功能)
/// </summary>
public class StringConverter : CsvHelper.TypeConversion.StringConverter
{
readonly ICsvReaderValidator _readerValidator;
public StringConverter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
var line = row.Context.Parser.Row;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
return text?.Trim();
}
public static readonly StringConverter Required;
public static readonly StringConverter NoValidator;
static StringConverter()
{
NoValidator = new StringConverter();
Required = new StringConverter(CsvRequiredValidator.Default);
}
}
/// <summary>
/// 日期转换器
/// </summary>
public class DateConverter : CsvHelper.TypeConversion.DateTimeConverter
{
readonly ICsvReaderValidator _readerValidator;
public DateConverter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
if (value is DateTime dt)
{
return dt.ToString("yyyy-MM-dd");
}
return base.ConvertToString(value, row, memberMapData);
}
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
int line;
string colName;
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
line = row.Context.Parser.RawRow;
colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
if (string.IsNullOrWhiteSpace(text))
{
return DateTime.MinValue;
}
if (text.Length == 8 && text.All(n => n >= '0' && n <= '9') && DateTime.TryParseExact(text, "yyyyMMdd",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None, out DateTime date))
{
return date.Date;
}
if (text.Length >= 8 && DateTime.TryParse(text, out date))
{
return date.Date;
}
line = row.Context.Parser.RawRow;
colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',转换为日期失败,值:{text}");
}
public static readonly DateConverter Required;
public static readonly DateConverter NoValidator;
static DateConverter()
{
NoValidator = new DateConverter();
Required = new DateConverter(CsvRequiredValidator.Default);
}
}
/// <summary>
/// 数字转换器
/// </summary>
public class DoubleConverter : CsvHelper.TypeConversion.DoubleConverter
{
readonly ICsvReaderValidator _readerValidator;
public DoubleConverter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
if (string.IsNullOrWhiteSpace(text))
{
return 0d;
}
if (double.TryParse(text, out double dd))
{
return dd;
}
else
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',转换为数字失败,值:{text}");
}
}
public static readonly DoubleConverter Required;
public static readonly DoubleConverter NoValidator;
static DoubleConverter()
{
NoValidator = new DoubleConverter();
Required = new DoubleConverter(CsvRequiredValidator.Default);
}
}
/// <summary>
/// 百分比转换器
/// </summary>
public class PercentConverter : CsvHelper.TypeConversion.ITypeConverter
{
readonly ICsvReaderValidator _readerValidator;
public PercentConverter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
if (string.IsNullOrWhiteSpace(text))
{
return 0d;
}
text = text.Trim();
if (!text.EndsWith("%"))
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:值未以'%'结尾,值:{text}");
}
if (double.TryParse(text.TrimEnd('%'), out double dd))
{
return dd / 100;
}
else
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',转换为数字失败,值:{text}");
}
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
throw new NotImplementedException();
}
public static readonly PercentConverter Required;
public static readonly PercentConverter NoValidator;
static PercentConverter()
{
NoValidator = new PercentConverter();
Required = new PercentConverter(CsvRequiredValidator.Default);
}
}
/// <summary>
/// 短整数转换器
/// </summary>
public class Int16Converter : CsvHelper.TypeConversion.Int16Converter
{
readonly ICsvReaderValidator _readerValidator;
public Int16Converter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
if (string.IsNullOrWhiteSpace(text))
{
return (short)0;
}
if (short.TryParse(text, out short dd))
{
return dd;
}
else
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',转换为整数失败,值:{text}");
}
}
public static readonly Int16Converter Required;
public static readonly Int16Converter NoValidator;
static Int16Converter()
{
NoValidator = new Int16Converter();
Required = new Int16Converter(CsvRequiredValidator.Default);
}
}
/// <summary>
/// 短整数转换器
/// </summary>
public class Int32Converter : CsvHelper.TypeConversion.Int32Converter
{
readonly ICsvReaderValidator _readerValidator;
public Int32Converter(ICsvReaderValidator readValidator = null)
{
_readerValidator = readValidator;
}
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (_readerValidator != null && !_readerValidator.Validate(text, out string errorMsg))
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',验证失败:{errorMsg},值:{text}");
}
if (string.IsNullOrWhiteSpace(text))
{
return 0;
}
if (int.TryParse(text, out int dd))
{
return dd;
}
else
{
var line = row.Context.Parser.RawRow;
var colName = memberMapData.Names[memberMapData.NameIndex];
throw new ServiceException($"第{line}行,列'{colName}',转换为整数失败,值:{text}");
}
}
public static readonly Int32Converter Required;
public static readonly Int32Converter NoValidator;
static Int32Converter()
{
NoValidator = new Int32Converter();
Required = new Int32Converter(CsvRequiredValidator.Default);
}
}
public class BoolTypeConverter : ITypeConverter
{
private bool DefaultValue;
public BoolTypeConverter(bool defaultValue)
{
DefaultValue = defaultValue;
}
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (string.IsNullOrWhiteSpace(text))
{
return DefaultValue;
}
string[] bStringY = { "是", "Y", "YES", "√" };
string[] bStringN = { "否", "N", "NO", "×" };
if (bStringY.Contains(text.ToUpper()))
{
return true;
}
else if (bStringN.Contains(text.ToUpper()))
{
return false;
}
else
{
return DefaultValue;
}
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
throw new NotImplementedException();
}
}
public class EnumTypeConverter<T> : ITypeConverter where T : struct
{
private T? _defaultValue;
private string[] _enumArray;
private string _colName;
public EnumTypeConverter(string colName, T? defaultValue = null)
{
if (typeof(Enum) != typeof(T).BaseType)
{
throw new Exception("类型参数不合法,当前泛型类的类型参数必须为枚举类型");
}
_enumArray = Enum.GetNames(typeof(T));
_defaultValue = defaultValue;
_colName = colName;
}
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
var isEnum = Enum.TryParse(text, out T _type);
if (isEnum)
{
return _type;
}
var line = row.Context.Parser.RawRow;
//var colName = memberMapData.Names[memberMapData.NameIndex];
if (_defaultValue == null)
{
throw new Exception($"第{line}行,列'{_colName}',验证失败, 值必须在【{string.Join(",", _enumArray)}】之中");
}
else
{
return _defaultValue;
}
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
throw new NotImplementedException();
}
}
}
/// <summary>
/// CSV文件读取验证器
/// </summary>
interface ICsvReaderValidator
{
bool Validate(string text, out string errorMessage);
}
/// <summary>
/// CSV cell值必需验证
/// </summary>
class CsvRequiredValidator : ICsvReaderValidator
{
public bool Validate(string text, out string errorMessage)
{
if (string.IsNullOrWhiteSpace(text))
{
errorMessage = "值不能为空";
return false;
}
errorMessage = null;
return true;
}
public static readonly CsvRequiredValidator Default;
static CsvRequiredValidator()
{
Default = new CsvRequiredValidator();
}
}
}