使用 fileHelpers 库的 CSV 中的列标题?

发布于 2024-09-27 21:55:33 字数 720 浏览 8 评论 0原文

FileHelper 库中是否有内置字段属性,它将在最终生成的 CSV 中添加标题行?

我用谷歌搜索并没有找到太多相关信息。目前我有这个:

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

它可以工作,但没有标题。

我正在考虑拥有像 FieldTitleAttribute 这样的属性,并将其用作列标题。

所以,我的问题是在什么时候检查属性并插入标题列?以前有人做过类似的事情吗?

我想插入标题并使用与实际字段名称不同的自定义文本,只需在对象的每个成员上添加一个属性:

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

也许还有一个选项可以告诉引擎在生成标题时插入标题。

因此,当调用 WriteStreamWriteString 时,标题行将插入自定义标题。

我找到了 DelimitedFileEngine 的几个事件,但没有找到检测当前记录是否是第一行以及如何在此之前插入行的最佳方法。

Is there a built-in field attribute in the FileHelper library which will add a header row in the final generated CSV?

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.

I'm thinking of having an attribute like FieldTitleAttribute and using this as a column header.

So, my question is at which point do I check the attribute and insert header columns? 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:

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

and maybe an option to tell the engine to insert the header when it's generated.

So when WriteStream or WriteString is called, the header row will be inserted with custom titles.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

天赋异禀 2024-10-04 21:55:34

这适用于 v2.9.9:

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

This works for v2.9.9:

FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
engine.HeaderText = engine.GetFileHeader();
浮华 2024-10-04 21:55:34

这里有一些代码可以做到这一点: https://gist.github.com/1391429

要使用它,您必须装饰您的带有 [FieldOrder] 的字段(无论如何,这是一个很好的 FileHelpers 实践)。用法:

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

但是对此的支持确实需要在 FileHelpers 本身中添加。我可以立即想到一些在实现之前需要回答的设计问题:

  • 读取文件时会发生什么? Afaik FileHelpers 目前全部基于序数列位置并忽略列名称...但是如果我们现在到处都有 [FieldHeader] 属性,那么我们是否还应该尝试将属性与文件中的列名称匹配?如果它们不匹配,您应该抛出异常吗?如果序数位置与列名称不一致会发生什么?
  • 当读取数据表时,您应该使用 A) 字段名称(当前设计),还是 B) 源文件列名称,还是 C) FieldTitle 属性?

Here's some code that'll do it: https://gist.github.com/1391429

To use it, you must decorate your fields with [FieldOrder] (a good FileHelpers practice anyway). 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. 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? 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?
北笙凉宸 2024-10-04 21:55:34

以下是 FileHelper 的工作方式:
要包含列标题,您需要定义一个字符串,其中标题的分隔方式与文件相同。

例如用“|”作为分隔符:

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

然后,在调用引擎时:

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

如果您不想编写标头,则不要在引擎上设置 HeaderText 属性。

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.

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.

深海里的那抹蓝 2024-10-04 21:55:34
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);
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);
你的背包 2024-10-04 21:55:34

只是为了包含一个更完整的示例,这会为我节省一些时间,对于 FileHelpers NuGet 包的版本 3.4.1....

给定

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

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

   public int Age { get; set; }
}

和这段代码来创建它

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

你得到这个

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

Just to include a more complete example, which would have saved me some time, for version 3.4.1 of the FileHelpers NuGet package....

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
紫罗兰の梦幻 2024-10-04 21:55:34

我发现您可以使用 FileHelperAsyncEngine 来完成此任务。假设您的数据是一个名为“output”、类型为“outputData”的列表,那么您可以编写如下代码:

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

I found that you can use the FileHelperAsyncEngine to accomplish this. Assuming your data is a list called "output" of type "outputData", then you can write code that looks like this:

        FileHelperAsyncEngine outEngine = new FileHelperAsyncEngine(typeof(outputData));
        outEngine.HeaderText = "Header1, Header2, Header3";
        outEngine.BeginWriteFile(outputfile);
        foreach (outputData line in output){
            outEngine.WriteNext(line);
        }
        outEngine.Close();
你与清晨阳光 2024-10-04 21:55:34

您可以简单地使用基类中的 FileHelper 的 GetFileHeader 函数

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

You can simply use FileHelper's GetFileHeader function from base class

 var engine = new FileHelperEngine<ExportType>();
 engine.HeaderText = engine.GetFileHeader();                             
                            
 engine.WriteFile(exportFile, exportData);
山有枢 2024-10-04 21:55:34
        bool includeHeader = false;

        var attributes = classType.GetCustomAttributes(typeof(IgnoreFirstAttribute), false);
        if (attributes.Length > 0)
        {
            IgnoreFirstAttribute myAttribute = (IgnoreFirstAttribute)attributes[0];
            includeHeader = myAttribute.NumberOfLines > 0;
        }

        FileHelperEngine engine = new FileHelperEngine(classType);

        if (includeHeader)
            engine.HeaderText = engine.GetFileHeader();

        var fileContent = engine.WriteString(obj);
        bool includeHeader = false;

        var attributes = classType.GetCustomAttributes(typeof(IgnoreFirstAttribute), false);
        if (attributes.Length > 0)
        {
            IgnoreFirstAttribute myAttribute = (IgnoreFirstAttribute)attributes[0];
            includeHeader = myAttribute.NumberOfLines > 0;
        }

        FileHelperEngine engine = new FileHelperEngine(classType);

        if (includeHeader)
            engine.HeaderText = engine.GetFileHeader();

        var fileContent = engine.WriteString(obj);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文