CsvHelper说明文档&一个小例子

来源:互联网 发布:ubuntu dokuwiki 编辑:程序博客网 时间:2024/05/19 11:50

启动

要安装CsvHelper,请从包管理器控制台运行以下操作。

Install-Package CsvHelper

读取文件

读取所有记录。读取设置尽可能简单。 如果您有一个镜像CSV文件的类结构设置,您可以将整个文件读入可枚举。

var csv = new CsvReader( textReader );var records = csv.GetRecords<MyClass>();

如果要自定义CSV文件映射到自定义类对象的方式,可以使用映射。

返回的IEnumerable 将产生结果。 这意味着在实际访问结果之前不会返回结果。 这是方便的,因为整个文件将不会被加载到内存中,并且当您访问每一行时,该文件将被读取。 如果您在IEnumerable 上执行类似Count()的操作,那么需要读取整个文件,您将无法重新遍历它,而不会重新开始。 如果您需要多次迭代记录(例如使用Count),则可以将所有内容加载到列表和数据的工作中。

var csv = new CsvReader( textReader );var records = csv.GetRecords<MyClass>().ToList();

手动读取记录

您可以循环行并手动读取它们。

var csv = new CsvReader( textReader );while( csv.Read() ){    var record = csv.GetRecord<MyClass>();}

读取个别字段

您也可以手动阅读每个字段。

var csv = new CsvReader( textReader );while( csv.Read() ){    var intField = csv.GetField<int>( 0 );    var stringField = csv.GetField<string>( 1 );    var boolField = csv.GetField<bool>( "HeaderName" );}

TryGetField

如果获取字段不一致,可以使用TryGetField。

var csv = new CsvReader( textReader );while( csv.Read() ){    int intField;    if( !csv.TryGetField( 0, out intField ) )    {        // Do something when it can't convert.    }}

解析

您也可以直接使用解析器,而无需使用阅读器。 解析器将返回读取的每行的字符串数组,当它完成时为空。

var parser = new CsvParser( textReader );while( true ){    var row = parser.Read();    if( row == null )    {        break;    }}

写文件

写入所有记录

写作设置尽可能简单。 如果您有一个镜像CSV文件的类结构设置,您可以从枚举中写入整个文件。

var csv = new CsvWriter( textWriter );csv.WriteRecords( records );

手动写入记录

您可以循环对象并手动写入。

var csv = new CsvWriter( textWriter );foreach( var item in list ){    csv.WriteRecord( item );}

写入个别字段

如果您愿意,也可以手动写入每个字段。

var csv = new CsvWriter( textWriter );foreach( var item in list ){    csv.WriteField( "a" );    csv.WriteField( 2 );    csv.WriteField( true );    csv.NextRecord();}

映射(Mapping)

自动映射(Auto Mapping)

如果不提供映射文件,将使用自动映射。 自动映射将按照它们显示的顺序映射类中的属性。如果属性是一个自定义类,它会按照它们显示的顺序递归地将属性从该类映射。如果自动映射器命中循环引用,那么它将停止参考分支。

流畅的类映射(Fluent Class Mapping)

如果您的CSV文件与您的自定义类不完全匹配,则可以使用流畅的类映射来设置类映射到文件的选项。 您需要在配置中注册您的类映射。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.Id );        Map( m = > m.Name );    }}

索引映射(Reference Map)

索引映射用于将自定义类的属性映射到自己的映射,将这些属性映射到多个CSV列。 您可以根据需要将索引映射嵌套得很深。

public sealed class PersonMap : CsvClassMap<Person>{    public PersonMap()    {        Map( m => m.Id );        Map( m => m.Name );        References<AddressMap>( m => m.Address );    }}public sealed class AddressMap : CsvClassMap<Address>{    public AddressMap()    {        Map( m => m.Street );        Map( m => m.City );        Map( m => m.State );        Map( m => m.Zip );    }}

索引(Index)

当通过索引映射时,您指定要用于该属性的CSV列的索引。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.Id ).Index( 0 );        Map( m => m.Name ).Index( 1 );    }}

名称(Name)

当按名称(Name)映射时,您指定要用于该属性的CSV列的名称。 为了使其工作,CSV文件必须具有标题记录。 您指定的名称必须与标题记录的名称相匹配。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.Id ).Name( "The Id Column" );        Map( m => m.Name ).Name( "The Name Column" );    }}

名称索引(NameIndex)

有时CSV文件有多个名称相同的列。 发生这种情况时,可以使用NameIndex来指定您所指的列名。 NameIndex不是CSV文件中的列。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.FirstName ).Name( "Name" ).NameIndex( 0 );        Map( m => m.LastName ).Name( "Name" ).NameIndex( 1 );    }}

忽略(Ignore)

目前没有使用。 映射只会映射您指定的属性。 将来会有一个在类映射中自动映射的选项,明确声明的任何映射将覆盖自动映射的映射。 当这种情况发生时,ignore将忽略自动映射的属性

默认(Default)

如果字段为空,Default用于设置要使用的默认值。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public override void MyClassMap()    {        Map( m => m.Id ).Index( 0 ).Default( -1 );        Map( m => m.Name ).Index( 1 ).Default( "Unknown" );    }}

类型转换(TypeConverter)

如果CSV字段的值不能自动转换为该属性的类型,则可以指定用于转换该值的自定义CsvHelper.TypeConversion.ITypeConverter。 有关如何创建自定义类型转换器的文档,请参阅类型转换。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.Id ).Index( 0 ).TypeConverter<MyIdConverter>();    }}

类型转换器选项(TypeConverterOption)

默认内置转换器将处理大多数类型转换的情况,但有时您会想要做一些小的更改,但不希望创建一个全新的类型转换器,只需解析一个int(例如)不同的。 您可以指定一些类型转换器选项来处理这些情况。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        Map( m => m.Description ).Index( 0 ).TypeConverterOption( CultureInfo.InvariantCulture );        Map( m => m.TimeStamp ).Index( 1 ).TypeConverterOption( DateTimeStyles.AdjustToUniversal );        Map( m => m.Cost ).Index( 2 ).TypeConverterOption( NumberStyles.Currency );        Map( m => m.CurrencyFormat ).Index( 3 ).TypeConverterOption( "C" );        Map( m => m.BooleanValue ).Index( 4 ).TypeConverterOption( true, "sure" ).TypeConverterOption( false, "nope" );    }}

转换使用(Convert Using)

当其他所有失败时,您都可以使用ConvertUsing。 ConvertUsing允许您编写内嵌自定义代码将该行转换为单个属性值。

public sealed class MyClassMap : CsvClassMap<MyClass>{    public MyClassMap()    {        // Constant value.        Map( m => m.Constant ).ConvertUsing( row => 3 );        // Aggregate of two rows.        Map( m => m.Aggregate ).ConvertUsing( row => row.Get<int>( 0 ) + row.Get<int>( 1 ) );        // Collection with a single value.        Map( m => m.Names ).ConvertUsing( row => new List<string>{ row.Get<string>( "Name" ) } );        // Just about anything.        Map( m => m.Anything ).ConvertUsing( row =>        {            // You can do anything you want in a block.            // Just make sure to return the same type as the property.        } );    }}

运行时映射

映射可以在运行时创建。 事实上,自动映射功能会动态地进行。 您可以查看以下链接的一些灵感:https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/Configuration/CsvClassMap.cs#L91

另一个简单的例子如下所示:

var customerMap = new DefaultCsvClassMap();// mapping holds the Property - csv column mapping foreach( string key in mapping.Keys ){    var columnName = mapping[key].ToString();    if( !String.IsNullOrEmpty( columnName ) )    {        var propertyInfo = typeof( Customer ).GetType().GetProperty( key );        var newMap = new CsvPropertyMap( propertyInfo );        newMap.Name( columnName );        customerMap.PropertyMaps.Add( newMap );    }}csv.Configuration.RegisterClassMap(CustomerMap);

配置

允许注释(Allow Comments)

该标志告诉解析器是否启用了注释。

// Default valuecsv.Configuration.AllowComments = false;

自动映射(Auto Map)

这用于从类型自动生成CsvClassMap,而无需流畅的类映射。 这将尝试映射所有属性,包括为非本机类型的属性创建引用映射。 如果自动映射器检测到循环引用,则该路径将不会继续。

var generatedMap = csv.Configuration.AutoMap<MyClass>();

缓冲区大小(Buffer Size)

当从TextReader和TextWriter读取或写入数据时使用的内部缓冲区的大小。 取决于您的TextReader或TextWriter来自哪里,您可能希望使此值更大或更小。

// Default valuecsv.Configuration.BufferSize = 2048;

注释(Comment)

用于表示被注释掉的行的值。

// Default valuecsv.Configuration.Comment = '#';

计数字节(Count Bytes)

一个标志,将告诉解析器保留已读取的所有字节的计数。 您需要将Configuration.Encoding设置为CSV文件的相同编码,以使其正常工作。 这也将减慢解析文件的速度.

// Default valuecsv.Configuration.CountBytes = false;

Culture Info

用于读写。在索引配置中,每个属性都可以复写。

// Default valuecsv.Configuration.CultureInfo = CultureInfo.CurrentCulture;

分隔符(Delimiter)

用于分隔CSV行中的字段的值。

// Default valuecsv.Configuration.Delimiter = ",";

检测列计数更改(Detect Column Count Changes)

该标志将检查从行到行的列数的更改。 如果为true并检测到更改,则将抛出CsvBadDataException异常。

// Default valuecsv.Configuration.DetectColumnCountChanges = false;

编码(Encoding)

CSV文件的编码。 这仅在计数字节时使用。 TextReader和TextWriter的底层将使用自己的编码。

// Default valuecsv.Configuration.Encoding = Encoding.UTF8;

有标题记录(Has Header Record)

该标志告诉读写器CSV文件中是否有标题行。 对于通过名称映射属性,必须是正确的(并且必须有一个标题行)。

// Default valuecsv.Configuration.HasHeaderRecord = true;

忽略标题空白(Ignore Header White Space)

当通过名称将列与属性匹配时,此标志会告知读者忽略标题中的空格。

// Default valuecsv.Configuration.IgnoreHeaderWhiteSpace = false;

忽略私有访问(Ignore Private Accessor)

一个标志,告诉读写器在读取和写入时忽略私有访问者。 默认情况下,您无法从私有的getter读取或写入私有设置器。 打开它将允许。 无法读取或写入的属性被忽略。

// Default valuecsv.Configuration.IgnorePrivateAccessor = false;

忽略读取异常(Ignore Reading Exceptions)

一个标志,告诉读者吞咽读取时发生的任何异常并继续。 解析器中发生的异常不会被忽略。 解析器异常意味着文件在某些方面是坏的,解析器不能恢复。

// Default valuecsv.Configuration.IgnoreReadingExceptions = false;

忽略引号(Ignore Quotes)

一个标志,告诉解析器忽略引号作为转义字符,并像任何其他字符一样对待它。

// Default valuecsv.Configuration.IgnoreQuotes = false;

标题大小写敏感(Is Header Case Sensitive)

该标志设置匹配的CSV头名称是否区分大小写。

// Default valuecsv.Configuration.IsHeaderCaseSensitive = true;

映射(Maps)

您可以访问注册的类映射。

var myMap = csv.Configuration.Maps[typeof( MyClass )];

属性绑定标志(Property Binding Flags)

PropertyBindingFlags是用于在自定义类中查找属性的标志。

// Default valuecsv.Configuration.PropertyBindingFlags = BindingFlags.Public | BindingFlags.Instance;

引号(Quote)

用于转义包含分隔符,引号或行结束的字段的值。

// Default valuecsv.Configuration.Quote = '"';

引用所有字段(Quote All Fields)

一个告诉写入器所有写的字段是否应该有引号; 不管该字段是否包含任何应该被转义的内容。 QuoteAllFields和QuoteNoFields都不能同时存在。 将一个设置为true将将另一个设置为false。

// Default valuecsv.Configuration.QuoteAllFields = false;

不引用字段(Quote No Fields)

一个告诉写入器所写的所有字段是不应该有引号的; 不管该字段是否包含任何应该被转义的内容。 QuoteAllFields和QuoteNoFields都不能同时存在。 将一个设置为true将将另一个设置为false。

// Default valuecsv.Configuration.QuoteNoFields = false;

读取异常回调(Reading Exception Callback)

如果您有Configuration.IgnoreReaderExceptions,并且您想知道异常已经发生,并且可能会与他们做某事,您可以使用它。

csv.Configuration.ReadingExceptionCallback = ( ex, row ) =>{    // Log the exception and current row information.};

注册类映射(Register Class Map)

当使用流畅的类映射时,需要注册类映射才能使用它们。 您可以注册要使用的多个类映射。

csv.Configuration.RegisterClassMap<MyClassMap>();csv.Configuration.RegisterClassMap<AnotherClassMap>();

跳过空记录(Skip Empty Records)

一个标志,让读入器知道当读入时是否应该跳过记录,如果它是空的。 如果所有字段都为空,则记录被视为空。

// Default valuecsv.Configuration.SkipEmptyRecords = false;

修剪字段(Trim Fields)

该标志告诉读者在阅读时从字段值的开头和结尾修剪空格。

// Default valuecsv.Configuration.TrimFields = false;

修剪头(Trim Headers)

这个标志告诉读入器从名称的开头和结尾处忽略空格,并将这些列与属性进行匹配。

// Default valuecsv.Configuration.TrimHeaders = false;

取消注册类映射(Unregister Class Map)

如果需要,您可以取消注册类映射。

// Unregister single map.csv.Configuration.UnregisterClassMap<MyClassMap>();// Unregister all class maps.csv.Configuration.UnregisterClassMap();

字段丢失抛出异常(Will Throw On Missing Field)

此标志指示如果读取和预期字段丢失时是否应抛出异常。 如果您想知道CSV文件是否有问题,这很有用。

// Default valuecsv.Configuration.WillThrowOnMissingField = true;

一个用CsvHelper读取csv文件的例子

//program.cs//用来读取csv文件using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Text;using CsvHelper;namespace CSVHelperReadSample{    internal class Program    {        private static void Main(string[] args)        {          //文件流的操作            using (FileStream fileStream = new FileStream(@"D:\path\test.csv", FileMode.Open, FileAccess.Read))            //以GB2312的编码方式读入            using (var sr = new StreamReader(fileStream, Encoding.GetEncoding("GB2312")))            {                using (var reader = new CsvReader(sr))                {                    //读入到枚举,CSVReader会将整个文件读入到一个enumerable中                    IEnumerable<StudentInformationClass> records = reader.GetRecords<StudentInformationClass>();                    foreach (StudentInformationClass record in records)                    {                        Console.Write("{0} {1} {2} {3} {4} {5}\n", record.NoClass, record.StudentNo, record.NameStudent, record.Sex, record.BirthdayStudent, record.GradeStudent);                    }                    //objs = reader.GetRecords<StudentInformationClass>().ToList();                }                //var objs = new List<StudentInformationClass>();                //CSVReader will now read the whole file into an enumerable                //Console.WriteLine(objs.Count);            }        }    }}
//学生信息类using System;namespace CSVHelperReadSample{    public class StudentInformationClass    {        private int _classNo;//班级号        private string _studentNo;//学号        private string _nameStudent;//学生姓名        private int _gradeStudent;//成绩        private string _sex;//学生姓名        private string _birthdayStudent;//生日        public int NoClass        {            set { this._classNo = value; }            get { return this._classNo; }        }        public string StudentNo        {            set { this._studentNo = value; }            get { return this._studentNo; }        }        public string NameStudent        {            set { this._nameStudent = value; }            get { return this._nameStudent; }        }        public int GradeStudent        {            set { this._gradeStudent = value; }            get { return this._gradeStudent; }        }        public string Sex        {            set { this._sex = value; }            get { return this._sex; }        }        public string BirthdayStudent        {            set { this._birthdayStudent = value; }            get { return _birthdayStudent; }        }    }}
原创粉丝点击