2010-10-20 8 views
45

C'è un attributo di campo incorporato nella libreria FileHelper che aggiungerà una riga di intestazione nel CSV generato finale?Intestazioni di colonne in CSV utilizzando la libreria fileHelpers?

Ho cercato su Google e non ho trovato molte informazioni su di esso. Attualmente ho questo:

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

Funziona, ma senza intestazione.

Sto pensando di avere un attributo come FieldTitleAttribute e utilizzarlo come intestazione di colonna.

Quindi, la mia domanda è: a che punto devo controllare l'attributo e inserire le colonne di intestazione? Qualcuno ha mai fatto qualcosa di simile prima?

vorrei ottenere le intestazioni inseriti e utilizzare il testo personalizzato diverso dal nome del campo effettivo soltanto con un attributo su ogni membro dell'oggetto:

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

e magari la possibilità di dire al motore inserisci l'intestazione quando viene generata.

Così quando viene chiamato WriteStream o WriteString, la riga di intestazione verrà inserita con titoli personalizzati.

Ho trovato un paio di eventi per DelimitedFileEngine, ma non è il modo migliore per rilevare se il record corrente è la prima riga e come inserire una riga prima di questo.

risposta

29

ecco qualche codice che farò: https://gist.github.com/1391429

di usarlo , è necessario decorare i campi con [FieldOrder] (una buona pratica FileHelpers comunque). Utilizzo:

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

Tuttavia, il supporto per questo deve essere aggiunto all'interno di FileHelpers stesso. Posso pensare a qualche domanda di progettazione che potrebbe essere soddisfatta prima che potesse essere implementata:

  • Cosa succede quando si legge un file? Afaik FileHelpers è attualmente tutto basato sulla posizione della colonna ordinale e ignora i nomi delle colonne ... ma se ora abbiamo gli attributi [FieldHeader] ovunque, dovremmo provare anche ad associare le proprietà con i nomi delle colonne nel file? Dovresti lanciare un'eccezione se non corrispondono?Cosa succede se la posizione ordinale non è in accordo con il nome della colonna?
  • Durante la lettura come tabella di dati, si dovrebbe utilizzare A) il nome del campo (design corrente) o B) il nome della colonna del file di origine o C) l'attributo FieldTitle?
+0

grazie per la condivisione e buon lavoro lì. vuoi aggiungere nella classe 'FieldOrderAttribute' per l'amor di completezza? – Heinnge

+2

@Heinnge La classe FieldOrderAttribute si trova nella libreria File 9.0.9.0 di FileHelpers. –

+0

In che modo risponde alla domanda dato che FieldOrder non aggiunge un'intestazione di colonna? –

23

Non so se è ancora necessario, ma ecco come funziona FileHelper: Per includere intestazioni di colonne, è necessario definire una stringa con intestazioni delimitate allo stesso modo del file. Ad esempio con '|' come delimitatore:

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

Poi, quando si chiama il vostro motore:

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

Se non si desidera scrivere le intestazioni, semplicemente non impostare l'attributo HeaderText sul motore.

+0

grazie Saaman. Finisco per scrivere un attributo personalizzato per questo e altri metodi di estensione che hanno generato la colonna di intestazione. – Heinnge

+0

@Heinnge, hai pubblicato il codice per questo ovunque? – CDeutsch

+1

@CDeutsc Non ho più il codice con me. Ma ho creato un semplice attributo [FieldTitleAttribute ("Titolo personalizzato")], disabilitato le intestazioni di build e ricreato l'intestazione con il titolo personalizzato (se presente) altrimenti con i nomi di campo predefiniti. – Heinnge

1

Ho scoperto che è possibile utilizzare FileHelperAsyncEngine per ottenere ciò. Assumendo i dati è una lista denominata "uscita" di tipo "OutputData", quindi è possibile scrivere codice che assomiglia a questo:

 FileHelperAsyncEngine outEngine = new FileHelperAsyncEngine(typeof(outputData)); 
     outEngine.HeaderText = "Header1, Header2, Header3"; 
     outEngine.BeginWriteFile(outputfile); 
     foreach (outputData line in output){ 
      outEngine.WriteNext(line); 
     } 
     outEngine.Close(); 
4
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); 
+2

Un costrutto un po 'più semplice per ottenere i nomi dei campi: var headerText = String.Join (",", typeof (MyClass) .GetFields(). Select (f => f.Name) .ToList()); Motore FileHelperEngine = nuovo FileHelperEngine () {HeaderText = headerText}; –

35

So che questa è una vecchia questione, ma qui è una risposta che lavora per v2.9.9

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

È anche l'approccio consigliato nelle domande frequenti: http://www.filehelpers.net/mustread/ in "Voglio scrivere un file con intestazioni" – Colin

+0

correlati: http://stackoverflow.com/a/8833322/109941 –

+2

Questa dovrebbe essere la risposta selezionata. – Jaxidian