使用CsvHelper编写标题? C# [英] Writing a Header using CsvHelper? C#

查看:153
本文介绍了使用CsvHelper编写标题? C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CsvHelper。要写入 .csv 文件,我需要基于类的标题。

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

我写了标题

我可以找到的所有文档都说要使用此表达式, writer.WriteHeader< CSVDataFormat>(); 但这是行不通的,因为它需要完成更多的工作。

All the documentation I can find says to use this expression, writer.WriteHeader<CSVDataFormat>(); but that isn't working because it needs more work done to it.

这里是该类

public class CSVDataFormat
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public float Wage { get; set; }
}

这是读写代码:

private void ReadCSV(string ogCsvFile)
{
        using (var streamReaederfileDir = new StreamReader(@ogCsvFile))
        {
            using (var streamWriterFileDir = new StreamWriter(Path.Combine(Path.GetDirectoryName(ogCsvFile), "New" + Path.GetFileName(ogCsvFile))))
            {
                var reader = new CsvReader(streamReaederfileDir);
                var writer = new CsvWriter(streamWriterFileDir);

                writer.WriteHeader<CSVDataFormat>();

                IEnumerable records = reader.GetRecords<CSVDataFormat>().ToList();

                foreach (CSVDataFormat record in records)
                {
                    record.Wage = record.Wage + (record.Wage / 10);
                    writer.WriteField(record.FirstName);
                    writer.WriteField(record.LastName);
                    writer.WriteField(record.Wage);
                    writer.NextRecord();
                }
            }
        }
}

更新

这是我在运行代码时遇到的错误:

This is the error I am getting when I run my code:


在CsvHelper.dll中发生了类型为'CsvHelper.CsvMissingFieldException'的未处理异常

An unhandled exception of type 'CsvHelper.CsvMissingFieldException' occurred in CsvHelper.dll

其他信息:CSV中不存在字段名字文件。

Additional information: Fields 'FirstName' do not exist in the CSV file.


推荐答案

您可能对CSVHelper的工作方式感到困惑。这段代码处理您的读入写出循环的写方面:

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 实现了 IDisposable ,因此我也将其放入了using块。

  • 工资调整略有简化

    • CSVWriter implements IDisposable, so I put it into a using block as well.
    • The wage adjustment is slightly streamlined
    • 结果:


      名字,姓氏,工资

      Ziggy,沃尔特斯,145.75

      Zoey,Strand,84.15

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

      Write标头仅写第一行-列/项目的名称。请注意,列出的工资与我用来创建每个工资的工资不同。

      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.

      对于您正在做的事情,我将读取一个类型化的对象来代替对 empList 。对于编辑中列出的错误,这意味着它无法在输入文件中找到该名称的列(可能是因为您没有使用Types重载)。类属性名称应与列名称完全匹配(您可能还需要配置CSVHelper)。

      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

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






      如果在传入的CSV它将不知道如何将数据映射到该类。您需要添加地图:

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

      矿藏在内部员工类。然后给CSVHelper映射:

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

      现在它知道如何将csv列映射到类中的属性

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

      这篇关于使用CsvHelper编写标题? C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆