使用CsvHelper写入CSV文件时的自定义转换 [英] Custom conversions when writing CSV files using CsvHelper
问题描述
最近我一直在做一些CSV读写操作,遇到了 CsvHelper 至今。我遇到了一个小问题;我在读取文件时使用自定义转换器,但是当我将它们写回时,该格式会丢失。我的CSV格式如下:
I've been doing some CSV reading and writing lately, and ran across CsvHelper which is fantastic so far. I've ran into one small problem; I use a custom converter when reading the files, but when I write them back out, that format is lost. My CSV format looks like this:
67,1234-1,20150115,750,20150115,1340,549,549,406,0,FRG
20150115,750
字段映射到称为开始
的单个 DateTime
字段(因此,2015年1月15日上午7:50)。我的类映射如下所示:
The fields 20150115,750
map to a single DateTime
field called Start
(So, 01/15/2015 7:50 AM). My class map looks like this:
public sealed class DutyMap : CsvClassMap<Duty>
{
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<String>(2), row.GetField<String>(3)));
Map(m => m.End).ConvertUsing(row => ParseDate(row.GetField<String>(4), row.GetField<String>(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;
}
}
这很好用,现在我可以调用par整个文件如下所示:
This works great, and I can now call parse an entire file like so:
var csv = new CsvReader(sr);
csv.Configuration.HasHeaderRecord = false;
csv.Configuration.RegisterClassMap<DutyMap>();
Data = csv.GetRecords<Duty>().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
在文档中,我看不到在编写时指定对话功能的方法>,仅阅读。到目前为止,我发现的唯一解决方案是手动手动写入每条记录:
Looking through the documentation, I don't see a way to specify a conversation function upon writing, only reading. The only solution I've found so far is to manually write each record by hand:
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();
}
是否有更好的方法?谢谢!
Is there a better way to do this? Thanks!
推荐答案
您可以使用自定义类型转换器( https://github.com/JoshClose/CsvHelper/wiki/Custom-TypeConverter )。只需重写 ConvertToString
方法。
You can do it with a custom type converters (https://github.com/JoshClose/CsvHelper/wiki/Custom-TypeConverter). Just override ConvertToString
method.
public class TestConverter : DefaultTypeConverter
{
public override string ConvertToString(TypeConverterOptions options, object value)
{
return base.ConvertToString(options, value);
}
}
并在映射时指定转换器:
and specify converter when mapping:
Map(m => m.PersonId).Index(0).TypeConverter<TestConverter>();
这篇关于使用CsvHelper写入CSV文件时的自定义转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!