Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用CsvHelper写入CSV文件时的自定义转换_C#_.net_Csvhelper - Fatal编程技术网

C# 使用CsvHelper写入CSV文件时的自定义转换

C# 使用CsvHelper写入CSV文件时的自定义转换,c#,.net,csvhelper,C#,.net,Csvhelper,我最近一直在做一些CSV的阅读和写作,到目前为止,这是非常棒的。我遇到了一个小问题;我在读取文件时使用自定义转换器,但当我将其写回时,格式会丢失。我的CSV格式如下所示: 67,1234-1,20150115,750,20150115,1340,549,549,406,0,FRG public sealed class DutyMap : CsvClassMap<Duty> { static readonly CultureInfo enUS = new CultureIn

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

67,1234-1,20150115,750,20150115,1340,549,549,406,0,FRG
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;
    }
}
字段
20150115750
映射到名为
Start
的单个
DateTime
字段(因此,2015年1月15日上午7:50)。我的类映射如下所示:

67,1234-1,20150115,750,20150115,1340,549,549,406,0,FRG
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;
    }
}
文件是这样写的:

67,7454-1,1/15/2015 7:50:00 AM,1/15/2015 1:40:00 PM,549,549,406,0,FPG
通过查看文档,我看不到一种在编写时指定对话函数的方法,而只是在阅读时。到目前为止,我找到的唯一解决方案是手动写入每条记录:

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();
}

有更好的方法吗?谢谢

您可以使用自定义类型转换器()完成此操作。只需重写
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<TestConverter>();
Map(m=>m.PersonId).Index(0).TypeConverter();

谢谢!我开始研究它,但是文档看起来有点稀疏。我会更深入地研究它!哦,这是否也允许我将CSV文件中的一个字段(
Start
)拆分为两个不同的字段?记住,我必须将日期部分和时间部分分开。只需多次使用不同列名称的Map语句Map(m=>m.PersonId).Index(0).Name(“col1”);Map(m=>m.PersonId).Index(0).Name(“col2”);我必须使用以下代码:public override object ConvertFromString(string text,IReaderRow行,MemberMapData MemberMapData)