2013-04-16 12 views
10

Używam CsvHelper do odczytu i zapisu plików CSV i jest świetny, ale nie rozumiem, jak pisać tylko wybrane pola typów.Jak napisać tylko wybrane pola klas do pliku CSV za pomocą CsvHelper?

powiedzieć, że mieliśmy:

using CsvHelper.Configuration; 

namespace Project 
{ 
    public class DataView 
    { 
     [CsvField(Name = "N")] 
     public string ElementId { get; private set; } 

     [CsvField(Name = "Quantity")] 
     public double ResultQuantity { get; private set; } 

     public DataView(string id, double result) 
     { 
      ElementId = id; 
      ResultQuantity = result; 
     } 
    } 
} 

i chcieliśmy, aby wykluczyć „Ilość” CsvField z wynikowego pliku CSV, które generują obecnie przez coś podobnego:

using (var myStream = saveFileDialog1.OpenFile()) 
{ 
    using (var writer = new CsvWriter(new StreamWriter(myStream))) 
    { 
     writer.Configuration.Delimiter = '\t'; 
     writer.WriteHeader(typeof(ResultView)); 
     _researchResults.ForEach(writer.WriteRecord); 
    } 
} 

Co mógłbym wykorzystać do dynamicznie wykluczyć pole typu z pliku CSV?

Jeśli zajdzie taka potrzeba, możemy przetworzyć wynikowy plik, ale nie wiem, jak usunąć całą kolumnę CSV z CsvHelper.

Odpowiedz

4

Można to zrobić:

using (var myStream = saveFileDialog1.OpenFile()) 
{ 
    using (var writer = new CsvWriter(new StreamWriter(myStream))) 
    { 
     writer.Configuration.AttributeMapping(typeof(DataView)); // Creates the CSV property mapping 
     writer.Configuration.Properties.RemoveAt(1); // Removes the property at the position 1 
     writer.Configuration.Delimiter = "\t"; 
     writer.WriteHeader(typeof(DataView)); 
     _researchResults.ForEach(writer.WriteRecord); 
    } 
} 

Jesteśmy zmuszając tworzenie mapowania atrybutów, a następnie modyfikując go, usuwając kolumny dynamicznie.

+4

Czy jest to stara wersja CsvHelper? "AttributeMapping" i "Właściwości" nie istnieją, gdy przechodzę do 'writer.configuration'? –

2

Zaznacz pole tak:

[CsvField(Ignore = true)] 
public double ResultQuantity { get; private set; } 

Aktualizacja: Nevermind. Widzę, że chcesz to zrobić w czasie wykonywania, zamiast kompilować czas. Zostawię to jako czerwoną flagę dla każdego, kto może popełnić ten sam błąd.

+2

I 'CsvFieldAttribute' został usunięty w wersji 2.0. – Wally

12

Niedawno musiałem osiągnąć podobny wynik, określając, które pola mają być uwzględnione w czasie wykonywania. To było moje podejście:

  1. Utwórz plik mapowania do mapowania pól, które muszę w czasie wykonywania przez przechodzącą w enum do konstruktora klasy

    public sealed class MyClassMap : CsvClassMap<MyClass> 
    { 
        public MyClassMap(ClassType type) 
        { 
         switch (type) 
         { 
          case ClassType.TypeOdd 
           Map(m => m.Field1); 
           Map(m => m.Field3); 
           Map(m => m.Field5);     
           break; 
          case ClassType.TypeEven: 
           Map(m => m.Field2); 
           Map(m => m.Field4); 
           Map(m => m.Field6);     
           break; 
          case ClassType.TypeAll: 
           Map(m => m.Field1); 
           Map(m => m.Field2); 
           Map(m => m.Field3); 
           Map(m => m.Field4); 
           Map(m => m.Field5); 
           Map(m => m.Field6);     
           break; 
         } 
        } 
    } 
    
  2. Wypisz rejestrów wykorzystując konfigurację odwzorowania

    using (var memoryStream = new MemoryStream()) 
    using (var streamWriter = new StreamWriter(memoryStream)) 
    using (var csvWriter = new CsvWriter(streamWriter)) 
    { 
        csvWriter.Configuration.RegisterClassMap(new MyClassMap(ClassType.TypeOdd)); 
        csvWriter.WriteRecords(records); 
        streamWriter.Flush(); 
        return memoryStream.ToArray(); 
    } 
    
+1

Jest to poprawny sposób na najnowsze (stan na grudzień 2015). – Ted

+0

najlepsza metoda zapisu wybranych pól w pliku CSV. – Nirman

Powiązane problemy