using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
public class CsvHelper
{
/// <summary>
/// 读CSV文件
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="path">文件路径</param>
/// <param name="func">数值转换方法</param>
/// <param name="encoding">编码格式</param>
/// <returns></returns>
public static List<T> Read<T>(string path, Func<string[], T> func = null, Encoding encoding = null) where T : class
{
if (encoding == null)
{
encoding = Encoding.UTF8;
}
if (func == null)
{
func = SetObjValues<T>;
}
var rslt = new List<T>();
using (var parser = new TextFieldParser(path, encoding))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
parser.TrimWhiteSpace = false; // 不忽略字段前后的空格
bool isLine = false;
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
if (isLine)
{
var obj = func(fields);
if (obj != null)
{
rslt.Add(obj);
}
}
else
{
// 忽略标题行
isLine = true;
}
}
}
return rslt;
}
/// <summary>
/// 写CSV文件
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="data">数据集合</param>
/// <param name="path">文件路径</param>
/// <param name="append">true追加,false不追加新建</param>
/// <param name="func">字段转换方法</param>
/// <param name="encoding">编码格式</param>
public static void Write<T>(IList<T> data, string path, bool append = false, Func<T, bool, IEnumerable<string>> func = null, Encoding encoding = null) where T : class
{
if (data == null || data.Count == 0)
{
return;
}
if (encoding == null)
{
encoding = Encoding.UTF8;
}
if (func == null)
{
func = GetObjValues;
}
try
{
if (!File.Exists(path) || !append)
{
var fields = func(data[0], true);
string title = FieldsToLine(fields);
File.WriteAllText(path, title, encoding);
}
using (var sw = new StreamWriter(path, true, encoding))
{
foreach (var item in data)
{
var fields = func(item, false);
string line = FieldsToLine(fields);
sw.Write(line);
}
}
}
catch (Exception ex)
{
throw new InvalidOperationException("写入失败!" + ex.Message);
}
}
/// <summary>
/// 字段拼接一行
/// </summary>
/// <param name="fields"></param>
/// <returns></returns>
private static string FieldsToLine(IEnumerable<string> fields)
{
if (fields == null)
{
return string.Empty;
}
var rslt = fields.Select(x =>
{
if (string.IsNullOrWhiteSpace(x))
{
return string.Empty;
}
// 所有字段都加双引号,按需使用
//x = string.Format("\"{0}\"", x.Replace("\"", "\"\""));
return x;
});
return string.Format("{0}{1}", string.Join(",", rslt), Environment.NewLine);
}
/// <summary>
/// 设置对象值
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="data">值集合</param>
/// <returns></returns>
private static T SetObjValues<T>(string[] data) where T : class
{
T rslt = Activator.CreateInstance<T>();
var type = typeof(T);
try
{
var properties = type.GetProperties();
// 确保值的顺序与属性顺序一致,且值类型也一致
for (int i = 0; i < data.Length; i++)
{
var pi = properties[i];
var typeConverter = TypeDescriptor.GetConverter(pi.PropertyType);
var value = typeConverter.ConvertFromString(data[i]);
type.InvokeMember(pi.Name, System.Reflection.BindingFlags.SetProperty, Type.DefaultBinder, rslt, new object[] { value });
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return rslt;
}
/// <summary>
/// 获取对象形式值
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="obj">实体对象</param>
/// <param name="isTitle">true,行首标题;false,每行值</param>
/// <returns></returns>
private static IEnumerable<string> GetObjValues<T>(T obj, bool isTitle) where T : class
{
IEnumerable<string> rslt = null;
if (isTitle)
{
rslt = obj.GetType().GetProperties().Select(x => x.Name);
}
else
{
rslt = obj.GetType().GetProperties().Select(x =>
{
if (x.GetValue(obj) == null)
{
return string.Empty;
}
return x.GetValue(obj).ToString();
});
}
return rslt;
}
}
CSV 文件的读写
发布时间 2023-04-27 15:35:10作者: wesson2019