JoshClose / CsvHelper

Library to help reading and writing CSV files
http://joshclose.github.io/CsvHelper/
Other
4.65k stars 1.05k forks source link

Cannot control column order when exporting objects with nested objects #2172

Open isak1080 opened 11 months ago

isak1080 commented 11 months ago

When exporting a complex class containing nested objects, it is hard, and sometime impossible to control the ordering of columns (at least using attributes - let me know if there's another way to do this using class maps).

The main reason is because [Index] is treated as a global value.

Consider this example:

public class MainContent
{
    [Index(0)]
    public int Id { get; set; }
    [Index(1)]
    public int Name { get; set; }
    [Index(2)]
    [HeaderPrefix("First_")]
    public Range FirstRange { get; set; }
    [Index(3)]
    [HeaderPrefix("Second_")]
    public Range SecondRange { get; set; }
    [Index(4)]
    public string Comment { get; set; }
}

public class Range
{
    [Index(0)]
    public int From { get; set; }
    [Index(1)]
    public int To { get; set; }
}

// Using the types above
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (var csv = new CsvWriter(sw, CultureInfo.InvariantCulture))
{
    csv.WriteHeader(typeof(MainContent));
    csv.Flush();
}

Console.WriteLine(sb);

The column order I want to achieve is the following: Id, Name, First_From, First_To, Second_From,Second_To,Comment

But what I get is this Id,First_From,Second_From,Name,First_To,Second_To,Comment

I guess it's sort of expected, since we now have 3 columns with Index=0 (Id, First_From, Second_From) but it's

Describe the solution you'd like I can think of three possible solutions 1) Similar to [HeaderPrefix] - add a [IndexOffset] attribute that translates the local index of the nested object to unique value 2) Treat [Index] as class local value. 3) Add a new attribute [Order(n)], or [ExportIndex(n)] that is similar to [Index] that only controls ordering within the class during export.