using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
namespace YLErp.Helpers
{
///
/// csv值转换器
///
static class CsvTypeConverts
{
///
/// 文本转换器(自带trim功能)
///
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);
}
}
///
/// 日期转换器
///
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);
}
}
///
/// 数字转换器
///
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);
}
}
///
/// 百分比转换器
///
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);
}
}
///
/// 短整数转换器
///
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);
}
}
///
/// 短整数转换器
///
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 : 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();
}
}
}
///
/// CSV文件读取验证器
///
interface ICsvReaderValidator
{
bool Validate(string text, out string errorMessage);
}
///
/// CSV cell值必需验证
///
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();
}
}
}