Dynamically create a CSV file with FileHelpers
Asked Answered
H

2

6

FileHelpers supports a feature called "RunTime Records" which lets you read a CSV file into a DataTable when you don't know the layout until runtime.

Is it possible to use FileHelpers to create a CSV file at runtime in the same manner?

Based on some user input, the CSV file that must be created will have different fields that can only be known at runtime. I can create the needed Type for the FileHelper engine as described in their reading section, but I can't figure out what format my data needs to be in to be written.

var engine = new FileHelpers.FileHelperEngine(GenerateCsvType());

engine.WriteStream(context.Response.Output, dontKnow);

EDIT

Alternatively, can anyone suggest a good CSV library that can create a CSV file without knowing its fields until runtime? For example, create a CSV file from a DataTable.

Hexateuch answered 21/1, 2010 at 21:8 Comment(0)
S
8

In fact the library only allows now to read runtime records but for writing purpouses you can use the DataTableToCsv method like this:

CsvEngine.DataTableToCsv(dt, filename);

Let me known if that helps.

Seldon answered 21/1, 2010 at 21:18 Comment(9)
Fantastic :) This is a great solution, but is there any way to write to a stream instead? That's not a deal breaker, but it would save some steps. Either way, thank you!Hexateuch
Not at the moment but send me an email we are actively working in the next version of the library and would be very easy to add an overloaded version of the method to write streams :)Seldon
@Marcos: is the next version going to support the generic lists (List<Customer>) as return type (instead of just arrays) from the FileEngine? :-)Osseous
Wow, I didn't realize you were that Marcos Meli. Thanks for the support, I really appreciate your tool. I'll send you an email in a few minutes.Hexateuch
@marc_s: In fact internally is using a List<> in the next version, but we don't expose it to avoid manipulation of the result. You can try with an extension method ToList() that return new List<T>(soureArray) in what scenarios u think would be cool to get List<> ?Seldon
@Marcos: I just find List<T> (or IList<T>) easier to work with than an array - precisely when I need to manipulate the results, e.g. toss out a few entries.Osseous
@Osseous @MarcosMeli That sounds like an excellent place for IEnumerable<> rather than IList<> or List<>Bridie
what is CsvEngine ?Garret
@MarcosMeli did you add an overloaded version of the method to write streams for DataTableToCsv? I don't see it in documentation :/Phelia
N
1

I know this is an old question, but I ran into same issue myself and spent some time looking for solution, so I decided to share my findings.

If you are using FileHelpers RunTime Records to create your definition you can populate same definition using reflection.

For example if you create a definition

        DelimitedClassBuilder cb = new DelimitedClassBuilder("Customers", ",");
        cb.AddField("StringField", "string");

        Type t = cb.CreateRecordClass();
        FileHelperEngine engine = new FileHelperEngine(t); 

Now you can use same type created by FileHelpers to populate your values as follows:

        object customClass = Activator.CreateInstance(t);
        System.Reflection.FieldInfo field = customClass.GetType().GetField("StringField", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
        if (field != null)
        {
            field.SetValue(customClass, "StringValue");
        }

And then write it to file or string:

        string line = engine.WriteString(new object[] { customClass });
Naoise answered 23/4, 2015 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.