CVSHELPER 使用指南
用於讀取和寫入CSV文件的.NET庫。 非常快速,靈活和易於使用。 支持讀寫自定義類對象。
入門
要安裝CsvHelper,請從包管理器控制檯運行以下操作。
Install-Package CsvHelper
讀
讀取所有記錄
閱讀所有記錄很簡單。 如果有一個的類結構的鏡像CSV文件,可以將整個文件讀入。
var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>();
如果要自定義CSV文件映射到自定義類對象的方式,可以使用映射。(後面將會介紹)
返回的IEnumerable <T>將產生結果。 這意味着在實際訪問數據之前不會返回結果。 因爲整個文件將不會被加載到內存中,並且當您訪問數據時,該文件將被讀取。 如果您需要多次迭代記錄(例如使用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。
var csv = new CsvReader( textReader );
while( csv.Read() )
{
int intField;
if( !csv.TryGetField( 0, out intField ) )
{
// Do something when it can't convert.
}
}
讀取一行(分析器)
您還可以直接使用分析器而不使用讀取器。分析器將爲讀取的每一行返回一個字符串數組,當它完成時將返回null。
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();
}
映射
自動映射
如果不提供映射文件,將使用自動映射。 自動映射將按照它們顯示的順序映射類中的屬性。如果屬性是一個自定義類,它會按照它們顯示的順序遞歸地的屬性類映射。如果自動映射器命中循環引用,那麼它將 停止映射.
類的映射
如果您的CSV文件與自定義類不匹配,您可以使用一個類映射來設置類如何映射到文件的列。您需要在配置中註冊您的類映射。
public sealed class MyClassMap : CsvClassMap<MyClass>
{
public MyClassMap()
{
Map( m => m.Id );
Map( m = > m.Name );
}
}
引用地圖
引用地圖用於將自定義類的屬性,將其映射到幾個CSV列。您可以嵌套參考圖的許多層深,只要你喜歡。
public class PersonMap : CsvClassMap<Person>
{
public PersonMap()
{
Map( m => m.Id );
Map( m => m.Name );
References<AddressMap>( m => m.Address );
}
}
public class AddressMap : CsvClassMap<Address>
{
public AddressMap()
{
Map( m => m.Street );
Map( m => m.City );
Map( m => m.State );
Map( m => m.Zip );
}
}
指數
當通過索引映射時,您指定要爲該屬性使用的CSV列的索引。
public sealed class MyClassMap : CsvClassMap<MyClass>
{
public MyClassMap()
{
Map( m => m.Id ).Index( 0 );
Map( m => m.Name ).Index( 1 );
}
}
列名
按列名映射時,指定要爲該屬性使用的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" );
}
}
同名列索引
有時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 );
}
}
默認
如果字段爲空,默認值用於設置要使用的默認值。
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" );
}
}
類型轉換器
如果CSV字段的值不能被自動轉換爲屬性的類型,你可以指定一個自定義csvhelper.typeconversion.itypeconverter用來轉換。有關如何創建自定義類型請看類型轉換器的文檔。
public sealed class MyClassMap : CsvClassMap<MyClass>
{
public MyClassMap()
{
Map( m => m.Id ).Index( 0 ).TypeConverter<MyIdConverter>();
}
}
類型轉換器的設置
默認內置轉換器將處理大多數類型轉換的情況,但有時也有一些小的變化,你想做,但不想創建一個完整的新型轉換器,只是一個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" );
}
}
使用轉換
當一切都失敗了,你可以用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);