csv文件作为一种excel可以读写的文件,方便使用,且格式为分隔符类型的文件,任何程序都可以很方便的读写其中的数据,可以作为不同系统间简单的非实时的数据接口交互方式。
实际上,我们自己在写程序的时候也会写自己的工具库,不过,自己的用起来不如第三方很多人开发维护的,所以,给团队中其他同事,尤其是新人而言,这类工具会更高效。
C#中本身的标准库中好像没有csv相关工具,这里使用了第三方库CsvHelper。通过如下方式安装
根据官网实例如下:
实例1 读取文件直接转为类对象
这个是个比较实际的例子,假设文件名file.csv,其中数据格式为如下
Id | Name |
---|---|
1 | One |
2 | Two |
我们新建一个数据类:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
然后就可以直接通过如下代码读取csv文件数据了,csv文件中的列名需要和类的属性名相同。
private void button1_Click(object sender, EventArgs e)
{
using (var reader = new StreamReader("file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.Delimiter = ",";
var records = csv.GetRecords<Foo>(); //一次性读取所有数据,并且转换为对象集合。
foreach (Foo line in records)
{
Console.WriteLine($"{line.Id} {line.Name}");
}
}
}
实例2 读取文件按字段提取
这个适用于比较灵活的方式,比如一个csv中有许多字段,但是我只需要其中某几个字段而已。
private void button3_Click(object sender, EventArgs e)
{
using (var reader = new StreamReader("file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = new List<Foo>();
csv.Read();//开始读取文件
csv.ReadHeader(); //读取首行记录作为表头
while (csv.Read()) //逐行读取
{
var record = new Foo
{
Id = csv.GetField<int>("Id"), //读取Id列
Name = csv.GetField("Name") //读取Name列
};
records.Add(record);
}
foreach (Foo line in records)
{
Console.WriteLine($"{line.Id} {line.Name}");
}
}
}
实例3 读取文件到DataTable
这个应该是在UI开发中经常用到的,利用DataTable和Datagridview控件绑定可以很容易修改和现实数据。 但是csvHelper有个不足的地方,没有提供DataTable到csv文件的方法。 通过csvhelper读取的datatable对象绑定到Datagridview控件之后,只能显示,不能修改。 所以,如果需要修改,我这里采用的重新自定义了一个datatable对象的方式。
private DataTable dt_new = new DataTable();
private void button4_Click(object sender, EventArgs e)
{
using (var reader = new StreamReader("file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
// Do any configuration to `CsvReader` before creating CsvDataReader.
using (var dr = new CsvDataReader(csv))
{
dt_new.Columns.Clear();
var dt = new DataTable();
dt.Load(dr);
//如果想实现datagridview修改同步到datatable,需要重新生成一个datatable对象,不能直接使用csv初始化
foreach (DataColumn col in dt.Columns)
{
dt_new.Columns.Add(col.ColumnName, col.DataType);
}
foreach (DataRow row in dt.Rows)
{
dt_new.Rows.Add(row["Id"],row["Name"]);
}
dt_new.TableName = "ddd";
dataGridView1.DataSource = dt_new;
Console.WriteLine(dataGridView1.Columns.IsReadOnly);
}
}
}
、
实例4 写入对象集合到文件
使用类对象的集合数据写入
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
};
using (var writer = new StreamWriter("file.csv",false)) //覆盖方式写入
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
实例5 写入DataTable到文件
这个可以配合实例3,从而方便的读取和写入到csv文件,又很好的使用客户端UI界面进行更新等操作。
var records = new List<Foo>();
DataTable dt = dataGridView1.DataSource as DataTable;
foreach (DataRow row in dt.Rows)
{
Foo foo = new Foo();
foo.Id = Int32.Parse(row["Id"].ToString());
foo.Name = row["Name"].ToString();
records.Add(foo);
}
using (var writer = new StreamWriter("file.csv", false))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}