c# List与Csv文件互转(特性实现)
有个自定义类NPOIMemoryStream ,去见https://blog.csdn.net/Daniel_yka/article/details/124708404?spm=1001.2014.3001.5502
public static class CsvOrTsvHelper
{
/// List转流(csv,tsv格式)
/// </summary>
/// <param name="fileFormat">文件格式</param>
/// <returns>success flag</returns>
public static NPOIMemoryStream SaveDataToCSVFile<T>(this List<T> dataList, string fileFormat) where T : class
{
string separator;
if (fileFormat.ToLower() == "csv")
separator = ",";
else
separator = "\t";
NPOIMemoryStream stream = new NPOIMemoryStream();
StreamWriter writer = new StreamWriter(stream);
StringBuilder strColumn = new StringBuilder();
StringBuilder strValue = new StringBuilder();
var tp = typeof(T);
PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
int[] filter = new int[props.Length];
try
{
//标题
for (int i = 0; i < props.Length; i++)
{
var itemPropery = props[i];
DescriptionAttribute labelAttr = itemPropery.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault() as DescriptionAttribute;
if (null != labelAttr)
{
strColumn.Append(labelAttr.Description);
strColumn.Append(separator);
}
else
{
filter[i] = 1;
}
}
strColumn.Remove(strColumn.Length - 1, 1);
writer.WriteLine(strColumn.ToString());
//内容
for (int i = 0; i < dataList.Count; i++)
{
var model = dataList[i];
strValue.Clear();
for (int m = 0; m < props.Length; m++)
{
var itemPropery = props[m];
if (filter[m] == 1) continue;
var val = itemPropery.GetValue(model, null);
if (m == 0)
{
strValue.Append(val);
}
else
{
strValue.Append(separator);
strValue.Append(val);
}
}
writer.WriteLine(strValue.ToString());
}
writer.Flush();
stream.Position = 0;
}
catch (Exception ex)
{
return null;
}
finally
{
if (writer != null)
{
writer.Dispose();
}
}
return stream;
}
/// <summary>
/// 流转list
/// </summary>
/// <param name="fileStream">文件流</param>
/// <returns></returns>
public static List<T> CsvOrTsvConvertToList<T>(this Stream fileStream, bool isCsv = true)
{
List<T> list = new List<T> { };
StreamReader sr = new StreamReader(fileStream, Encoding.GetEncoding("utf-8"));
string tempText = "";
int Rows = 1; //标注第几行
//缓存列索引对应属性名
Dictionary<int, string> colIndexMapName = new Dictionary<int, string>();
while ((tempText = sr.ReadLine()) != null)
{
string[] arr = CsvOrTsvstrToArry(tempText, isCsv ? ',' : '\t');
var obj = Activator.CreateInstance<T>();
Type type = obj.GetType();
//获取所有公共字段名
PropertyInfo[] peroperties = type.GetProperties();
if (Rows == 1)
{
for (int i = 0; i < arr.Length; i++)
{
foreach (var property in peroperties)
{
var proName = property.Name;
object[] objs = property.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (objs != null && objs.Length > 0)
{
var description = ((DescriptionAttribute)objs[0]).Description;
if (description == arr[i])
{
colIndexMapName.Add(i, proName);
}
}
}
}
}
else
{
for (int i = 0; i < arr.Length; i++)
{
foreach (var property in peroperties)
{
if (colIndexMapName.ContainsKey(i) && property.Name == colIndexMapName[i])
{
ExcelHelper.ConvertByPropTypeName(property, obj, arr[i]);
}
}
}
list.Add(obj);
}
Rows++;
}
return list;
}
private static string[] CsvOrTsvstrToArry(string splitStr, char ignoreChar)
{
splitStr = splitStr.Replace("\"\"", "'");
var newstr = string.Empty;
List<string> sList = new List<string>();
bool isSplice = false;
string[] array = splitStr.Split(new char[] { ignoreChar });
foreach (var str in array)
{
if (!string.IsNullOrEmpty(str) && str.IndexOf('"') > -1)
{
var firstchar = str.Substring(0, 1);
var lastchar = string.Empty;
if (str.Length > 0)
{
lastchar = str.Substring(str.Length - 1, 1);
}
if (firstchar.Equals("\"") && !lastchar.Equals("\""))
{
isSplice = true;
}
if (lastchar.Equals("\""))
{
if (!isSplice)
newstr += str;
else
newstr = newstr + ignoreChar + str;
isSplice = false;
}
}
else
{
if (string.IsNullOrEmpty(newstr))
newstr += str;
}
if (isSplice)
{
//添加因拆分时丢失的逗号
if (string.IsNullOrEmpty(newstr))
newstr += str;
else
newstr = newstr + ignoreChar + str;
}
else
{
sList.Add(newstr.Replace("\"", "").Replace("'", "\"").Trim());//去除字符中的双引号和首尾空格
newstr = string.Empty;
}
}
return sList.ToArray();
}
}