编写 CSV 文件 - 为列名添加前缀
Writing a CSV file - adding a prefix to the column names
在 CSV 文件中写入 collection 我想添加一个 属性 值作为列名的前缀。
有没有一种方法可以将映射器配置为使用 属性 值写入列名,如下例所示。
csv 文件
属性,身份证,123_Property1,123_Property2,身份证,456_Property1,456_Property2
标题,123,约翰,史密斯,456,海伦,汤姆森
public class MyClass
{
public string Property {get; set;}
public List<MyCustom> MyCustoms {get; set;}
}
public class MyCustom
{
public string Id {get; set;}
public string Property2 {get; set;}
public string Property3 {get; set;}
}
public class MyClassMap : ClassMap<MyClass>
{
public MyClassMap(){
this.Map(m => m.Property).Name("Property");
(?)this.Map(m => m.MyCustoms).Name("IdVALUE ...");
}
你想做的都能做,但它做了一些假设,很容易被打破。最终您应该重新考虑您的 CSV 结构。此解决方案手动写入 header 记录并使用自定义 TypeConverter
打印出每个 MyCustom
class。
假设
- 每个
MyClass
将具有相同数量的 MyCustom
并且 ID 将在每个 MyClass
记录之间匹配。
MyCustom Id 每次都会以相同的顺序打印出来。(更新:添加 OrderBy
以解决此问题。)
public static void Main(string[] args)
{
var records = new List<MyClass> {
new MyClass {
Property = "Title",
MyCustoms = new List<MyCustom> {
new MyCustom { Id = "123", Property1 = "John", Property2 = "Smith" },
new MyCustom { Id = "456", Property1 = "Helen", Property2 = "Thomson"}
}
},
new MyClass {
Property = "AnotherProperty",
MyCustoms = new List<MyCustom> {
new MyCustom { Id = "123", Property1 = "Another11", Property2 = "Another12" },
new MyCustom { Id = "456", Property1 = "Another21", Property2 = "Another22"}
}
}
};
using (var csv = new CsvWriter(Console.Out))
{
csv.Configuration.TypeConverterCache.AddConverter<List<MyCustom>>(new MyTypeConverter());
csv.Configuration.HasHeaderRecord = false;
// Get all of the ids from the first record.
var ids = records[0].MyCustoms.OrderBy(m => m.Id).Select(m => m.Id).ToList();
csv.WriteField("Property");
foreach (var id in ids)
{
csv.WriteField("Id");
csv.WriteField($"{id}_Property1");
csv.WriteField($"{id}_Property2");
}
csv.NextRecord();
csv.WriteRecords(records);
}
Console.ReadKey();
}
public class MyClass
{
public string Property { get; set; }
public List<MyCustom> MyCustoms {get;set;}
}
public class MyCustom
{
public string Id { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
}
private class MyTypeConverter : DefaultTypeConverter
{
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
var list = ((List<MyCustom>)value).OrderBy(m => m.Id).ToList();
foreach (var item in list)
{
row.WriteField(item.Id);
row.WriteField(item.Property1);
row.WriteField(item.Property2);
}
return null;
}
}
在 CSV 文件中写入 collection 我想添加一个 属性 值作为列名的前缀。 有没有一种方法可以将映射器配置为使用 属性 值写入列名,如下例所示。
csv 文件
属性,身份证,123_Property1,123_Property2,身份证,456_Property1,456_Property2
标题,123,约翰,史密斯,456,海伦,汤姆森
public class MyClass
{
public string Property {get; set;}
public List<MyCustom> MyCustoms {get; set;}
}
public class MyCustom
{
public string Id {get; set;}
public string Property2 {get; set;}
public string Property3 {get; set;}
}
public class MyClassMap : ClassMap<MyClass>
{
public MyClassMap(){
this.Map(m => m.Property).Name("Property");
(?)this.Map(m => m.MyCustoms).Name("IdVALUE ...");
}
你想做的都能做,但它做了一些假设,很容易被打破。最终您应该重新考虑您的 CSV 结构。此解决方案手动写入 header 记录并使用自定义 TypeConverter
打印出每个 MyCustom
class。
假设
- 每个
MyClass
将具有相同数量的MyCustom
并且 ID 将在每个MyClass
记录之间匹配。 MyCustom Id 每次都会以相同的顺序打印出来。(更新:添加OrderBy
以解决此问题。)
public static void Main(string[] args)
{
var records = new List<MyClass> {
new MyClass {
Property = "Title",
MyCustoms = new List<MyCustom> {
new MyCustom { Id = "123", Property1 = "John", Property2 = "Smith" },
new MyCustom { Id = "456", Property1 = "Helen", Property2 = "Thomson"}
}
},
new MyClass {
Property = "AnotherProperty",
MyCustoms = new List<MyCustom> {
new MyCustom { Id = "123", Property1 = "Another11", Property2 = "Another12" },
new MyCustom { Id = "456", Property1 = "Another21", Property2 = "Another22"}
}
}
};
using (var csv = new CsvWriter(Console.Out))
{
csv.Configuration.TypeConverterCache.AddConverter<List<MyCustom>>(new MyTypeConverter());
csv.Configuration.HasHeaderRecord = false;
// Get all of the ids from the first record.
var ids = records[0].MyCustoms.OrderBy(m => m.Id).Select(m => m.Id).ToList();
csv.WriteField("Property");
foreach (var id in ids)
{
csv.WriteField("Id");
csv.WriteField($"{id}_Property1");
csv.WriteField($"{id}_Property2");
}
csv.NextRecord();
csv.WriteRecords(records);
}
Console.ReadKey();
}
public class MyClass
{
public string Property { get; set; }
public List<MyCustom> MyCustoms {get;set;}
}
public class MyCustom
{
public string Id { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
}
private class MyTypeConverter : DefaultTypeConverter
{
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
var list = ((List<MyCustom>)value).OrderBy(m => m.Id).ToList();
foreach (var item in list)
{
row.WriteField(item.Id);
row.WriteField(item.Property1);
row.WriteField(item.Property2);
}
return null;
}
}