使用CsvHelper编写CSV文件时的自定义转换

我最近一直在做一些CSV阅读和写作,然后跑过CsvHelper ,到目前为止这很棒。 我遇到了一个小问题; 我在读取文件时使用自定义转换器,但是当我将它们写回时,该格式将丢失。 我的CSV格式如下所示:

67,1234-1,20150115,750,20150115,1340,549,549,406,0,FRG 

字段20150115,750映射到名为Start (So,01/15/2015 7:50 AM)的单个DateTime字段。 我的class级地图如下所示:

 public sealed class DutyMap : CsvClassMap { static readonly CultureInfo enUS = new CultureInfo("en-US"); public DutyMap() { Map(m => m.PersonId).Index(0); Map(m => m.DutyName).Index(1); Map(m => m.Start).ConvertUsing(row => ParseDate(row.GetField(2), row.GetField(3))); Map(m => m.End).ConvertUsing(row => ParseDate(row.GetField(4), row.GetField(5))); Map(m => m.DutyTime1).Index(6); Map(m => m.DutyTime2).Index(7); Map(m => m.FlightTime).Index(8); Map(m => m.CreditHours).Index(9); Map(m => m.DutyType).Index(10); } private static DateTime ParseDate(string date, string time) { DateTime ret; if (time.Length < 4) time = new String('0', 4 - time.Length) + time; if (!DateTime.TryParseExact(date + time, "yyyyMMddHHmm", enUS, DateTimeStyles.None, out ret)) throw new FormatException(String.Format("Could not parse DateTime. Date: {0} Time: {1}", date, time)); return ret; } } 

这很好用,我现在可以调用解析整个文件,如下所示:

 var csv = new CsvReader(sr); csv.Configuration.HasHeaderRecord = false; csv.Configuration.RegisterClassMap(); Data = csv.GetRecords().ToList(); 

但是,当我文件时:

 csv.WriteRecords(Data); 

该文件是这样写出来的:

 67,7454-1,1/15/2015 7:50:00 AM,1/15/2015 1:40:00 PM,549,549,406,0,FPG 

通过文档查看,我没有看到在写入时指定对话function的方法,只有阅读 。 到目前为止,我发现的唯一解决方案是手动编写每条记录:

 var csv = new CsvWriter(sw); foreach (var item in Data) { csv.WriteField(item.PersonId); csv.WriteField(item.DutyName); csv.WriteField(item.Start.ToString("yyyyMMdd")); csv.WriteField(item.Start.ToString("Hmm")); csv.WriteField(item.End.ToString("yyyyMMdd")); csv.WriteField(item.End.ToString("Hmm")); csv.WriteField(item.DutyTime1); csv.WriteField(item.DutyTime2); csv.WriteField(item.FlightTime); csv.WriteField(item.CreditHours); csv.WriteField(item.DutyType); csv.NextRecord(); } 

有一个更好的方法吗? 谢谢!

您可以使用自定义类型转换器( https://github.com/JoshClose/CsvHelper/wiki/Custom-TypeConverter )来完成此操作。 只需覆盖ConvertToString方法。

 public class TestConverter : DefaultTypeConverter { public override string ConvertToString(TypeConverterOptions options, object value) { return base.ConvertToString(options, value); } } 

并在映射时指定转换器:

 Map(m => m.PersonId).Index(0).TypeConverter();