Writing a Header using CsvHelper? C#

后端 未结 2 1760
一生所求
一生所求 2020-12-03 22:09

I\'m using CsvHelper. To write to a .csv file, I need a header based off of a class.

I write the header manually and it works, but I need to be done aut

相关标签:
2条回答
  • 2020-12-03 22:48

    You may be confused how CSVHelper works. This code handles the write aspect of your read in-write out loop:

    List<Employee> empList = new List<Employee>();
    
    empList.Add(new Employee { FirstName = "Ziggy", LastName = "Walters", Wage = 132.50F });
    empList.Add(new Employee { FirstName = "Zoey", LastName = "Strand", Wage = 76.50F });
    
    using (StreamWriter sw = new StreamWriter(@"C:\Temp\emp.csv"))
    using (CsvWriter cw = new CsvWriter(sw))
    {
        cw.WriteHeader<Employee>();
    
        foreach (Employee emp in empList)
        {
            emp.Wage *= 1.1F;
            cw.WriteRecord<Employee>(emp);
        }
    }
    
    • CSVWriter implements IDisposable, so I put it into a using block as well.
    • The wage adjustment is slightly streamlined

    Result:

    FirstName,LastName,Wage
    Ziggy,Walters,145.75
    Zoey,Strand,84.15

    Write header just writes the first line - the names of the columns/items. Notice that the wages listed are different than what I used to create each one.

    For what you are doing, I would read in a typed object in place of iterating the empList. For the error listed in the edit, that means that it could not find a column by that name in the input file (probably because you didnt use the Types overload). The class property names should match the column names exactly (you may also want to configure CSVHelper).


    The full in-out loop is only slightly more complex:

    using (StreamReader sr = new StreamReader(@"C:\Temp\empIN.csv"))
    using (StreamWriter sw = new StreamWriter(@"C:\Temp\empOUT.csv"))
    using (CsvWriter cw = new CsvWriter(sw))
    using (CsvReader cr = new CsvReader(sr))
    {
        cw.WriteHeader<Employee>();
        var records = cr.GetRecords<Employee>();
    
        foreach (Employee emp in records)
        {
            emp.Wage *= 1.1F;
            cw.WriteRecord<Employee>(emp);
        }
    
    }
    

    Results using the output from the first loop as input:

    FirstName,LastName,Wage
    Ziggy,Walters,160.325
    Zoey,Strand,92.565


    If there is no header record in the incoming CSV it wont know how to map data to the class. You need to add a map:

    public class EmployeeMap :  CsvHelper.Configuration.CsvClassMap<Employee>
    {
        public EmployeeMap()
        {
            Map(m => m.FirstName).Index(0);
            Map(m => m.LastName).Index(1);
            Map(m => m.Wage).Index(2);
        }
    }
    

    Mine is nested inside the Employee class. Then give CSVHelper that map:

    ... before your try to read from the incoming CSV:
    cr.Configuration.RegisterClassMap<Employee.EmployeeMap>();
    
    cw.WriteHeader<Employee>();
    ...
    

    Now it knows how to map csv columns to the properties in your class.

    0 讨论(0)
  • 2020-12-03 22:59

    I believe this exception is from the CsvReader and not the CsvWriter. Default CsvConfiguration expects a header and uses AutoMap to generate a PropertyName_to_Index mapping.

    From the documentation you may need to define a map see mapping

    0 讨论(0)
提交回复
热议问题