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.

Michael La Voie
  • 27,772
  • 14
  • 72
  • 92

2 Answers2

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.

Marcos Meli
  • 3,468
  • 24
  • 29
  • 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! – Michael La Voie Jan 21 '10 at 21:21
  • 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 :) – Marcos Meli Jan 21 '10 at 21:28
  • @Marcos: is the next version going to support the generic lists (`List`) as return type (instead of just arrays) from the FileEngine? :-) – marc_s Jan 21 '10 at 21:38
  • 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. – Michael La Voie Jan 21 '10 at 21:44
  • @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(soureArray) in what scenarios u think would be cool to get List<> ? – Marcos Meli Jan 21 '10 at 21:54
  • @Marcos: I just find List (or IList) easier to work with than an array - precisely when I need to manipulate the results, e.g. toss out a few entries. – marc_s Jan 22 '10 at 06:10
  • 1
    @marc_s @MarcosMeli That sounds like an excellent place for `IEnumerable<>` rather than `IList<>` or `List<>` – cofiem Jan 03 '12 at 11:09
  • what is CsvEngine ? – Kiquenet Apr 28 '20 at 13:03
  • @MarcosMeli did you add an overloaded version of the method to write streams for DataTableToCsv? I don't see it in documentation :/ – kociuba1997 Jan 28 '21 at 14:18
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 });