private static string GetCsvText <TEntity>(this IEnumerable <TEntity> entities, bool includeHeader) { if (entities == null || !entities.Any()) { return(string.Empty); } var isBasicType = typeof(TEntity).IsBasicType(); IReadOnlyList <PropertyInfo> props = InternalHelper.GetPropertiesForCsvHelper <TEntity>(); if (!isBasicType && props.Count == 0) { return(string.Empty); } var data = new StringBuilder(); if (includeHeader) { if (isBasicType) { data.Append(InternalConstants.DefaultPropertyNameForBasicType); } else { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(InternalConstants.CsvSeparator); } data.Append(props[i].Name); } } data.AppendLine(); } if (isBasicType) { foreach (var entity in entities) { data.AppendLine(Convert.ToString(entity)); } } else { foreach (var entity in entities) { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(InternalConstants.CsvSeparator); } data.Append(props[i].GetValueGetter().Invoke(entity)); } data.AppendLine(); } } return(data.ToString()); }
private static string GetCsvText <TEntity>(this IEnumerable <TEntity> entities, bool includeHeader) { if (entities == null) { return(string.Empty); } var data = new StringBuilder(); var isBasicType = typeof(TEntity).IsBasicType(); if (isBasicType) { if (includeHeader) { data.AppendLine(InternalConstants.DefaultPropertyNameForBasicType); } foreach (var entity in entities) { data.AppendLine(Convert.ToString(entity)); } } else { IReadOnlyList <PropertyInfo> props = InternalHelper.GetPropertiesForCsvHelper <TEntity>(); if (includeHeader) { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(CsvSeparatorCharacter); } data.Append(props[i].Name); } data.AppendLine(); } foreach (var entity in entities) { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(CsvSeparatorCharacter); } // https://stackoverflow.com/questions/4617935/is-there-a-way-to-include-commas-in-csv-columns-without-breaking-the-formatting var val = props[i].GetValueGetter().Invoke(entity)?.ToString().Replace("\"", "\"\""); if (!string.IsNullOrEmpty(val)) { data.Append(val.IndexOf(',') > -1 ? $"\"{val}\"" : val); } } data.AppendLine(); } } return(data.ToString()); }
/// <summary> /// convert csv file data to entity list /// </summary> /// <param name="filePath">csv file path</param> public static List <TEntity> ToEntityList <TEntity>(string filePath) where TEntity : new() { if (!File.Exists(filePath)) { throw new ArgumentException(Resource.FileNotFound, nameof(filePath)); } var entities = new List <TEntity>(); if (typeof(TEntity).IsBasicType()) { using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (var sr = new StreamReader(fs, Encoding.UTF8)) { string strLine; var isFirstLine = true; while ((strLine = sr.ReadLine()).IsNotNullOrEmpty()) { if (isFirstLine) { isFirstLine = false; continue; } // entities.Add(strLine.Trim().To <TEntity>()); } } } } else { IReadOnlyList <PropertyInfo> props = InternalHelper.GetPropertiesForCsvHelper <TEntity>(); using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (var sr = new StreamReader(fs, Encoding.UTF8)) { string strLine; var isFirstLine = true; while ((strLine = sr.ReadLine()).IsNotNullOrEmpty()) { var cols = strLine.Split(new[] { InternalConstants.CsvSeparatorCharacter }); if (isFirstLine) { isFirstLine = false; } else { var entity = new TEntity(); if (typeof(TEntity).IsValueType) { var obj = (object)entity;// boxing for value types for (int i = 0; i < cols.Length; i++) { props[i].GetValueSetter().Invoke(obj, cols[i].ToOrDefault(props[i].PropertyType)); } entity = (TEntity)obj;// unboxing } else { for (int i = 0; i < cols.Length; i++) { props[i].GetValueSetter().Invoke(entity, cols[i].ToOrDefault(props[i].PropertyType)); } } entities.Add(entity); } } } } } return(entities); }
private static string GetCsvText <TEntity>(this IEnumerable <TEntity> entities, bool includeHeader) { if (entities == null) { return(string.Empty); } var data = new StringBuilder(); var isBasicType = typeof(TEntity).IsBasicType(); if (isBasicType) { if (includeHeader) { data.AppendLine(InternalConstants.DefaultPropertyNameForBasicType); } foreach (var entity in entities) { data.AppendLine(Convert.ToString(entity)); } } else { var dic = InternalHelper.GetPropertyColumnDictionary <TEntity>(); var props = InternalHelper.GetPropertiesForCsvHelper <TEntity>(); if (includeHeader) { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(CsvSeparatorCharacter); } data.Append(dic[props[i]].ColumnTitle); } data.AppendLine(); } foreach (var entity in entities) { for (var i = 0; i < props.Count; i++) { var propertyValue = props[i].GetValueGetter <TEntity>()?.Invoke(entity); if (InternalCache.OutputFormatterFuncCache.TryGetValue(props[i], out var formatterFunc) && formatterFunc?.Method != null) { try { // apply custom formatterFunc propertyValue = formatterFunc.Invoke(new[] { entity, propertyValue }); } catch (Exception e) { Debug.WriteLine(e); InvokeHelper.OnInvokeException?.Invoke(e); } } if (i > 0) { data.Append(CsvSeparatorCharacter); } // https://stackoverflow.com/questions/4617935/is-there-a-way-to-include-commas-in-csv-columns-without-breaking-the-formatting var val = propertyValue?.ToString().Replace("\"", "\"\""); if (!string.IsNullOrEmpty(val)) { data.Append(val.IndexOf(CsvSeparatorCharacter) > -1 ? $"\"{val}\"" : val); } } data.AppendLine(); } } return(data.ToString()); }
private static string GetCsvText <TEntity>(this IEnumerable <TEntity> entities, bool includeHeader) { if (entities == null) { return(string.Empty); } var data = new StringBuilder(); var isBasicType = typeof(TEntity).IsBasicType(); if (isBasicType) { if (includeHeader) { data.AppendLine(InternalConstants.DefaultPropertyNameForBasicType); } foreach (var entity in entities) { data.AppendLine(Convert.ToString(entity)); } } else { var dic = InternalHelper.GetPropertyColumnDictionary <TEntity>(); var props = InternalHelper.GetPropertiesForCsvHelper <TEntity>(); if (includeHeader) { for (var i = 0; i < props.Count; i++) { if (i > 0) { data.Append(CsvSeparatorCharacter); } data.Append(dic[props[i]].ColumnTitle); } data.AppendLine(); } foreach (var entity in entities) { for (var i = 0; i < props.Count; i++) { var propertyValue = props[i].GetValueGetter <TEntity>().Invoke(entity); var entityType = typeof(TEntity); var formatterFunc = InternalCache.OutputFormatterFuncCache.GetOrAdd(props[i], p => { var propertyType = typeof(PropertySetting <,>).MakeGenericType(entityType, p.PropertyType); return(propertyType.GetProperty(InternalConstants.OutputFormatterFuncName)?.GetValueGetter() .Invoke(dic[props[i]])); }); if (null != formatterFunc) { var funcType = typeof(Func <, ,>).MakeGenericType(entityType, props[i].PropertyType, typeof(object)); var method = funcType.GetProperty("Method")?.GetValueGetter().Invoke(formatterFunc) as MethodInfo; var target = funcType.GetProperty("Target")?.GetValueGetter().Invoke(formatterFunc); if (null != method && target != null) { // apply custom formatterFunc propertyValue = method.Invoke(target, new[] { entity, propertyValue }); } } if (i > 0) { data.Append(CsvSeparatorCharacter); } // https://stackoverflow.com/questions/4617935/is-there-a-way-to-include-commas-in-csv-columns-without-breaking-the-formatting var val = propertyValue?.ToString().Replace("\"", "\"\""); if (!string.IsNullOrEmpty(val)) { data.Append(val.IndexOf(CsvSeparatorCharacter) > -1 ? $"\"{val}\"" : val); } } data.AppendLine(); } } return(data.ToString()); }