CsvHelper是一个用于读写CSV(逗号分隔值)文件的开源.NET库。它提供了简单而强大的API,使得处理CSV文件变得轻而易举。本文将详细介绍CsvHelper的使用方法,并提供多个实用的例子。
首先,通过NuGet包管理器安装CsvHelper:
C#Install-Package CsvHelper
假设我们有一个名为people.csv
的文件,内容如下:
textName,Age,City John Doe,30,New York Jane Smith,25,London Mike Johnson,35,Paris
我们可以使用以下代码读取这个文件:
C#using System;
using System.Globalization;
using System.IO;
using CsvHelper;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (var reader = new StreamReader("people.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Person>();
foreach (var record in records)
{
Console.WriteLine($"{record.Name} is {record.Age} years old and lives in {record.City}.");
}
}
}
}
现在,让我们创建一个新的CSV文件:
C#using System.Collections.Generic;
using System.Globalization;
using System.IO;
using CsvHelper;
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
class Program
{
static void Main(string[] args)
{
var products = new List<Product>
{
new Product { Name = "Apple", Price = 0.5m, Quantity = 100 },
new Product { Name = "Banana", Price = 0.3m, Quantity = 150 },
new Product { Name = "Orange", Price = 0.4m, Quantity = 80 }
};
using (var writer = new StreamWriter("products.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(products);
}
}
}
有时,CSV文件的列名可能与我们的类属性名不匹配。我们可以使用自定义映射来解决这个问题:
C#using CsvHelper;
using CsvHelper.Configuration;
using System;
using System.Globalization;
using System.IO;
using System.Collections.Generic;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Map(m => m.Name).Name("FullName");
Map(m => m.Age).Name("YearsOld");
Map(m => m.City).Name("Location");
}
}
class Program
{
static void Main(string[] args)
{
string filePath = "people_custom.csv";
// 首先创建一些示例数据并写入CSV文件
CreateSampleCsvFile(filePath);
// 然后读取CSV文件
List<Person> people = ReadCsvFile(filePath);
// 打印读取的数据
foreach (var person in people)
{
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, City: {person.City}");
}
}
static void CreateSampleCsvFile(string filePath)
{
var records = new List<Person>
{
new Person { Name = "John Doe", Age = 30, City = "New York" },
new Person { Name = "Jane Smith", Age = 25, City = "Los Angeles" },
new Person { Name = "Bob Johnson", Age = 45, City = "Chicago" }
};
using (var writer = new StreamWriter(filePath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.Context.RegisterClassMap<PersonMap>();
csv.WriteRecords(records);
}
Console.WriteLine("Sample CSV file created.");
}
static List<Person> ReadCsvFile(string filePath)
{
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Context.RegisterClassMap<PersonMap>();
return csv.GetRecords<Person>().ToList();
}
}
}
如果我们只想读取或写入特定的字段,可以使用Ignore()
方法:
C#public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Map(m => m.Name);
Map(m => m.Age);
Map(m => m.City).Ignore();
}
}
CsvHelper可以自动处理日期时间的转换,但有时我们可能需要指定特定的格式:
C#using CsvHelper;
using CsvHelper.Configuration;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
public class Event
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
public class EventMap : ClassMap<Event>
{
public EventMap()
{
Map(m => m.Name);
Map(m => m.Date).TypeConverterOption.Format("yyyy-MM-dd");
}
}
class Program
{
static void Main(string[] args)
{
string filePath = "events.csv";
// 写入CSV文件
WriteEventsToCSV(filePath);
// 读取CSV文件
List<Event> events = ReadEventsFromCSV(filePath);
// 打印读取的数据
foreach (var evt in events)
{
Console.WriteLine($"Event: {evt.Name}, Date: {evt.Date:yyyy-MM-dd}");
}
}
static void WriteEventsToCSV(string filePath)
{
using (var writer = new StreamWriter(filePath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.Context.RegisterClassMap<EventMap>();
csv.WriteRecords(new List<Event>
{
new Event { Name = "Conference", Date = new DateTime(2023, 5, 15) },
new Event { Name = "Workshop", Date = new DateTime(2023, 6, 1) }
});
}
Console.WriteLine("CSV file written successfully.");
}
static List<Event> ReadEventsFromCSV(string filePath)
{
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Context.RegisterClassMap<EventMap>();
return csv.GetRecords<Event>().ToList();
}
}
}
CsvHelper可以很好地处理枚举类型:
C#public enum Category
{
Food,
Electronics,
Clothing
}
public class Product
{
public string Name { get; set; }
public Category Category { get; set; }
}
class Program
{
static void Main(string[] args)
{
var products = new List<Product>
{
new Product { Name = "Apple", Category = Category.Food },
new Product { Name = "Laptop", Category = Category.Electronics },
new Product { Name = "T-Shirt", Category = Category.Clothing }
};
using (var writer = new StreamWriter("products_with_category.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(products);
}
}
}
对于大型CSV文件,我们可以使用GetRecords<T>()
方法的延迟执行特性来提高性能:
C#using (var reader = new StreamReader("large_file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
foreach (var record in csv.GetRecords<Person>())
{
// 处理每条记录,而不是一次性加载所有记录到内存
ProcessRecord(record);
}
}
CsvHelper是一个功能强大且灵活的库,可以大大简化CSV文件的处理过程。通过本文提供的示例,你应该能够处理大多数常见的CSV相关任务。无论是简单的读写操作,还是复杂的自定义映射和类型转换,CsvHelper都能够胜任。在处理数据导入导出、日志分析等涉及CSV格式的场景时,CsvHelper是一个值得考虑的工具。
希望这篇文章对你有所帮助,祝你在C#开发中使用CsvHelper愉快!
本文作者:rick
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!