在CSVHelper中添加空白字段

3

我使用CsvHelper库来写CSV。我的对象并不包含所有记录,我需要向我的CSV中添加空字段。例如:

public class Example
{
   public string Test1 { get; set; }
   public string Test2 { get; set; }
}

使用这张地图:

public class ExampleMap : ClassMap<Example>
{
    public ExampleMap()
    {
      Map(ex=>ex.Test1).Index(0);
      Map(ex=>ex.Test2).Index(4);
    }
}

我可以为这个对象提供帮助。
new Example() { Test1="dummy", Test2="field" };

这个CSV结果:
dummy;;;field

我非常困扰这个问题,如果有人可以帮我解决:)
非常感谢

4个回答

1
在ClassMap中使用常量值定义字段将允许您定义空列。这将生成带有标题的所需输出。
public class ExampleMap: ClassMap<Example>
{
     public ExampleMap()
     {
         Map(ex=>ex.Test1).Index(0).Name("Test1");
         Map().Index(1).Name("First Empty Column").Constant("");
         Map().Index(2).Name("Second Empty Column").Constant("");
         Map().Index(3).Name("Third Empty Column").Constant("");
         Map(ex=>ex.Test2).Index(4).Name("Test2");
     } 
}

0

看起来在中间有显式列映射的概念被违反了。

似乎CsvHelper库不支持这种情况,因为该库仅使用升序索引来进行定义的列映射(“映射列”)。

但是,如果确实需要这样的输出,则可以按以下方式引入“未使用”(保留)列:

internal sealed class Example
{
    public string Test1 { get; set; }
    public string Test2 { get; set; }

    public string Reserved1 { get; set; }
    public string Reserved2 { get; set; }
}

internal sealed class ExampleMap : CsvClassMap<Example>
{
    public ExampleMap()
    {
        Map(ex => ex.Test1).Index(0);
        Map(ex => ex.Reserved1).Index(1);
        Map(ex => ex.Reserved2).Index(2);
        Map(ex => ex.Test2).Index(3);
    }
}

这对我的情况来说将是一个巨大的时间浪费(我在我的一个csv文件中有100个空白字段)(我重写了一个旧的EDI,它可以处理空白字段...!)我尝试了很多(愚蠢的)方法(在PropertyMap中添加虚拟PropertyInfo,注册相同的虚拟属性...)。我考虑编辑csvhelper的核心来解决我的问题!(我看了你的博客,很不错!) - Creep
只返回翻译后的文本:无标题,仅数据! - Creep
是的,数据主要来自数据库,但是被塑造成适合与合作伙伴使用的旧EDI。另一部分来自我们的ERP,还有一部分来自文件系统。我查看了SSIS包,但我们的交换过程非常复杂,并且需要通过FTP存储进行双向传输等操作...! - Creep
总的来说,我想建议您从现有的 SQL 表格(以某种方式)生成“行”和“行映射”类,然后使用这些“行”和“行映射”类与 CsvHelper 库一起使用。您觉得呢? - Sergey Vyacheslavovich Brunov
它不能解决我的“空白字段”问题。所有的映射都已经完成(除了解决这个问题之外),索引也很好,但我无法弄清楚如何解决这个问题!:( - Creep
显示剩余6条评论

0

我最终选择直接编辑每行的最终CSV字符串...它有效,但很丑陋!


0
注意:在新版本中,这可能会被Constant()运算符所替代。
一种更加API一致的方法是使用自定义的ITypeConverter。以下是我使用它的示例:
Map(i => i.SomeUnusedId).Name("SomeId").TypeConverter<EmptyConverter>(); //converst to an empty string

那么转换器可能看起来像这样:

public class EmptyConverter : ITypeConverter {
    /// <inheritdoc />
    public bool CanConvertFrom(Type type) {
        return true;
    }

    /// <inheritdoc />
    public bool CanConvertTo(Type type) {
        return true;
    }

    /// <inheritdoc />
    public object ConvertFromString(TypeConverterOptions options, string text) {
        return string.Empty;
    }

    /// <inheritdoc />
    public string ConvertToString(TypeConverterOptions options, object value) {
        return string.Empty;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接