简体   繁体   English

CSV 中的列标题使用 fileHelpers 库?

[英]Column headers in CSV using fileHelpers library?

Is there a built-in field attribute in the FileHelper library which will add a header row in the final generated CSV? FileHelper 库中是否有内置字段属性,它将在最终生成的 CSV 中添加 header 行?

I have Googled and didn't find much info on it.我用谷歌搜索并没有找到太多关于它的信息。 Currently I have this:目前我有这个:

DelimitedFileEngine _engine = new DelimitedFileEngine(T);
_engine.WriteStream
        (HttpContext.Current.Response.Output, dataSource, int.MaxValue);

It works, but without a header.它可以工作,但没有 header。

I'm thinking of having an attribute like FieldTitleAttribute and using this as a column header.我正在考虑使用像FieldTitleAttribute这样的属性并将其用作列 header。

So, my question is at which point do I check the attribute and insert header columns?所以,我的问题是在什么时候检查属性并插入 header 列? Has anyone done something similar before?有没有人做过类似的事情?

I would like to get the headers inserted and use custom text different from the actual field name just by having an attribute on each member of the object:我想插入标题并使用与实际字段名称不同的自定义文本,只需在 object 的每个成员上都有一个属性:

[FieldTitleAttribute("Custom Title")]
private string Name

and maybe an option to tell the engine to insert the header when it's generated.并且也许可以选择告诉引擎在生成 header 时插入它。

So when WriteStream or WriteString is called, the header row will be inserted with custom titles.因此,当调用WriteStreamWriteString时,header 行将插入自定义标题。

I have found a couple of Events for DelimitedFileEngine, but not what's the best way to detect if the current record is the first row and how to insert a row before this.我为 DelimitedFileEngine 找到了几个事件,但不是检测当前记录是否是第一行以及如何在此之前插入一行的最佳方法。

I know this is an old question, but here is an answer that works for v2.9.9我知道这是一个老问题,但这里有一个适用于 v2.9.9 的答案

FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
engine.HeaderText = engine.GetFileHeader();

Here's some code that'll do it: https://gist.github.com/1391429这是一些可以做到的代码: https : //gist.github.com/1391429

To use it, you must decorate your fields with [FieldOrder] (a good FileHelpers practice anyway).要使用它,您必须用[FieldOrder]装饰您的字段(无论如何都是一个很好的 FileHelpers 实践)。 Usage:用法:

[DelimitedRecord(","), IgnoreFirst(1)]
public class Person
{
    // Must specify FieldOrder too
    [FieldOrder(1), FieldTitle("Name")]
    string name;

    [FieldOrder(2), FieldTitle("Age")]
    int age;
}

...

var engine = new FileHelperEngine<Person>
{
    HeaderText = typeof(Person).GetCsvHeader()
};

...

engine.WriteFile(@"C:\people.csv", people);

But support for this really needs to be added within FileHelpers itself.但是确实需要在 FileHelpers 本身中添加对此的支持。 I can think of a few design questions off the top of my head that would need answering before it could be implemented:我可以想到一些在实施之前需要回答的设计问题:

  • What happens when reading a file?读取文件时会发生什么? Afaik FileHelpers is currently all based on ordinal column position and ignores column names... but if we now have [FieldHeader] attributes everywhere then should we also try matching properties with column names in the file? Afaik FileHelpers 目前全部基于序号列位置并忽略列名......但是如果我们现在到处都有[FieldHeader]属性,那么我们还应该尝试将属性与文件中的列名匹配吗? Should you throw an exception if they don't match?如果它们不匹配,是否应该抛出异常? What happens if the ordinal position doesn't agree with the column name?如果序数位置与列名不一致会发生什么?
  • When reading as a data table, should you use A) the field name (current design), or B) the source file column name, or C) the FieldTitle attribute?当作为数据表读取时,您应该使用 A)字段名称(当前设计),还是 B)源文件列名称,或 C)FieldTitle 属性?

I don't know if you still need this, but here is the way FileHelper is working : To include headers of columns, you need to define a string with headers delimited the same way as your file.我不知道您是否仍然需要这个,但 FileHelper 的工作方式是这样的:要包含列标题,您需要定义一个字符串,其中标题的分隔方式与您的文件相同。 For example with '|'例如用“|” as delimiter :作为分隔符:

 public const string HeaderLine = @"COLUMN1|COLUMN2|COLUMN3|...";

Then, when calling your engine :然后,在调用引擎时:

DelimitedFileEngine _engine = new DelimitedFileEngine<T> { HeaderText = HeaderLine };

If you don't want to write the headers, just don't set the HeaderText attribute on the engine.如果您不想编写标题,请不要在引擎上设置HeaderText属性。

List<MyClass> myList = new List<MyClass>();
FileHelperEngine engine = new FileHelperEngine(typeof(MyClass));
String[] fieldNames = Array.ConvertAll<FieldInfo, String>(typeof(MyClass).GetFields(), delegate(FieldInfo fo) { return fo.Name; });
engine.HeaderText = String.Join(";", fieldNames);
engine.WriteFile(MapPath("MyClass.csv"), myList);

Just to include a more complete example, which would have saved me some time, for version 3.4.1 of the FileHelpers NuGet package....只是为了包含一个更完整的示例,它可以为我节省一些时间,用于 FileHelpers NuGet 包的 3.4.1 版......

Given给定的

[DelimitedRecord(",")]
public class Person
{
   [FieldCaption("First")]
   public string FirstName { get; set; }

   [FieldCaption("Last")]
   public string LastName { get; set; }

   public int Age { get; set; }
}

and this code to create it和这个代码来创建它

static void Main(string[] args)
{
    var people = new List<Person>();
    people.Add(new Person() { FirstName = "James", LastName = "Bond", Age = 38 });
    people.Add(new Person() { FirstName = "George", LastName = "Washington", Age = 43 });
    people.Add(new Person() { FirstName = "Robert", LastName = "Redford", Age = 28 });

    CreatePeopleFile(people);
}

private static void CreatePeopleFile(List<Person> people)
{
    var engine = new FileHelperEngine<Person>();

    using (var fs = File.Create(@"c:\temp\people.csv"))
    using (var sw = new StreamWriter(fs))
    {
        engine.HeaderText = engine.GetFileHeader();
        engine.WriteStream(sw, people);
        sw.Flush();
    }
}

You get this你得到这个

First,Last,Age
James,Bond,38
George,Washington,43
Robert,Redford,28

I found that you can use the FileHelperAsyncEngine to accomplish this.我发现您可以使用 FileHelperAsyncEngine 来完成此操作。 Assuming your data is a list called "output" of type "outputData", then you can write code that looks like this:假设您的数据是一个类型为“outputData”的名为“output”的列表,那么您可以编写如下所示的代码:

        FileHelperAsyncEngine outEngine = new FileHelperAsyncEngine(typeof(outputData));
        outEngine.HeaderText = "Header1, Header2, Header3";
        outEngine.BeginWriteFile(outputfile);
        foreach (outputData line in output){
            outEngine.WriteNext(line);
        }
        outEngine.Close();

You can simply use FileHelper's GetFileHeader function from base class您可以简单地使用来自基础 class 的 FileHelper 的 GetFileHeader function

 var engine = new FileHelperEngine<ExportType>();
 engine.HeaderText = engine.GetFileHeader();                             
                            
 engine.WriteFile(exportFile, exportData);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM