新建控制台项目
安装csvhelper 33.0.1
写入csv
新建Foo.cs
namespace CsvSut02;
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
批量写入
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>();
for (int i = 0; i < 100; i++)
{
foos.Add(new Foo()
{
Id = i,
Name = "我是" + i
});
}
var fileName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.csv";
using (var writer = new StreamWriter(fileName))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
using (var csv = new CsvWriter(writer, config))
{
csv.WriteRecords(foos);
}
}
}
}
逐条写入
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>();
for (int i = 0; i < 100; i++)
{
foos.Add(new Foo()
{
Id = i,
Name = "我是" + i
});
}
var fileName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.csv";
using (var writer = new StreamWriter(fileName))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
using (var csv = new CsvWriter(writer, config))
{
//这里看过来
foreach (var foo in foos)
{
csv.WriteRecord(foo);
csv.NextRecord();
}
}
}
}
}
增加标题
特性方式
using CsvHelper.Configuration.Attributes;
namespace CsvSut02;
public class Foo
{
[Name("Id")]
public int Id { get; set; }
[Name("Name")]
public string Name { get; set; }
}
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>();
for (int i = 0; i < 100; i++)
{
foos.Add(new Foo()
{
Id = i,
Name = "我是" + i
});
}
var fileName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.csv";
using (var writer = new StreamWriter(fileName))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
using (var csv = new CsvWriter(writer, config))
{
csv.WriteHeader<Foo>();
csv.NextRecord();
foreach (var foo in foos)
{
csv.WriteRecord(foo);
csv.NextRecord();
}
}
}
}
}
配置类
新建FooClassMap.cs
using CsvHelper.Configuration;
namespace CsvSut02;
public class FooClassMap : ClassMap<Foo>
{
public FooClassMap()
{
Map(m => m.Id)
.Index(0)
.Name("id");
Map(m => m.Name)
.Index(1)
.Name("name");
}
}
修改Program.cs
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>();
for (int i = 0; i < 100; i++)
{
foos.Add(new Foo()
{
Id = i,
Name = "我是" + i
});
}
var fileName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.csv";
using (var writer = new StreamWriter(fileName))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
using (var csv = new CsvWriter(writer, config))
{
csv.Context.RegisterClassMap<FooClassMap>();
csv.WriteHeader<Foo>();
csv.NextRecord();
foreach (var foo in foos)
{
csv.WriteRecord(foo);
csv.NextRecord();
}
}
}
}
}
可能有人觉得麻烦,使用配置类可以保证原始类的纯粹,保证poco
读取csv
读取和写入一样,可以两种方式实现一个是配置类一个是特性,下面都以特性演示
无标题csv
using CsvHelper.Configuration.Attributes;
namespace CsvSut02;
public class Foo
{
[Index(0)]
public int Id { get; set; }
[Index(1)]
public string Name { get; set; }
}
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
var file = "2024_07_24_18_24_00.csv";
using (var reader = new StreamReader(file))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.HasHeaderRecord = false;//没有头部
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Foo>().ToList();
foreach (var record in records)
{
Console.WriteLine(record.Id);
}
}
}
}
}
有标题csv
using CsvHelper.Configuration.Attributes;
namespace CsvSut02;
public class Foo
{
[Name("id")]
public int Id { get; set; }
[Name("name")]
public string Name { get; set; }
}
using CsvHelper.Configuration.Attributes;
namespace CsvSut02;
public class Foo
{
[Name("id")]
public int Id { get; set; }
[Name("name")]
public string Name { get; set; }
}
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
var file = "2024_07_24_18_30_49.csv";
using (var reader = new StreamReader(file))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.HasHeaderRecord = true;//有头部
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Foo>().ToList();
foreach (var record in records)
{
Console.WriteLine(record.Id);
}
}
}
}
}
增量写入
using System.Globalization;
using System.Text;
using CsvHelper;
using CsvHelper.Configuration;
namespace CsvSut02;
class Program
{
static void Main(string[] args)
{
var fileName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.csv";
WriteModelWithAppend(fileName);
WriteModelWithAppend(fileName);
}
/// <summary>
/// 追加方式写入
/// </summary>
/// <param name="fileName"></param>
static void WriteModelWithAppend(string fileName)
{
var model = new Foo();
model.Id = 1;
model.Name = "测试";
// 检查文件是否存在,以确定是否应该以追加模式打开
var mode = File.Exists(fileName) ? FileMode.Append : FileMode.Create;
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
using var writer = new StreamWriter(new FileStream(fileName, mode, FileAccess.Write, FileShare.Read),
Encoding.UTF8);
using var csv = new CsvWriter(writer, config);
if (mode == FileMode.Create)
{
csv.WriteHeader<Foo>();
csv.NextRecord();
}
csv.WriteRecord(model);
csv.NextRecord();
}
}
注意多线程有问题需要加锁
参考
https://blog.csdn.net/guliang21/article/details/106233049
https://joshclose.github.io/CsvHelper/getting-started