2011-08-24 15 views
14

Ci sono molti esempi online su come riempire un DataSet da un file di testo, ma voglio fare il contrario. L'unica cosa che sono riuscito a trovare è this ma sembra ... incompleta?Esportare un DataSet C# in un file di testo

Voglio che sia in un formato leggibile, non solo delimitato da virgole, quindi una spaziatura non uguale tra le colonne su ogni riga se questo ha senso. Ecco un esempio di quello che voglio dire:

Column1   Column2   Column3 
Some info  Some more info Even more info 
Some stuff here Some more stuff Even more stuff 
Bits    and    bobs 

Nota: ho solo una DataTable nel mio DataSet quindi nessun bisogno di preoccuparsi di più DataTable.

MODIFICA: Quando ho detto "leggibile" intendevo l'umano leggibile.

Grazie in anticipo.

+0

Sai che si sta solo allineare con un carattere fisso, giusto? –

+0

Sì, lo so. – bobble14988

risposta

15

Questo dovrebbe distanziare il testo del carattere di lunghezza fissa bene, ma significa che elaborerà la piena DataTable due volte (passano 1: trovare il testo più lungo per colonna, passare 2: testo di output):

static void Write(DataTable dt, string outputFilePath) 
    { 
     int[] maxLengths = new int[dt.Columns.Count]; 

     for (int i = 0; i < dt.Columns.Count; i++) 
     { 
      maxLengths[i] = dt.Columns[i].ColumnName.Length; 

      foreach (DataRow row in dt.Rows) 
      { 
       if (!row.IsNull(i)) 
       { 
        int length = row[i].ToString().Length; 

        if (length > maxLengths[i]) 
        { 
         maxLengths[i] = length; 
        } 
       } 
      } 
     } 

     using (StreamWriter sw = new StreamWriter(outputFilePath, false)) 
     { 
      for (int i = 0; i < dt.Columns.Count; i++) 
      { 
       sw.Write(dt.Columns[i].ColumnName.PadRight(maxLengths[i] + 2)); 
      } 

      sw.WriteLine(); 

      foreach (DataRow row in dt.Rows) 
      { 
       for (int i = 0; i < dt.Columns.Count; i++) 
       { 
        if (!row.IsNull(i)) 
        { 
         sw.Write(row[i].ToString().PadRight(maxLengths[i] + 2)); 
        } 
        else 
        { 
         sw.Write(new string(' ', maxLengths[i] + 2)); 
        } 
       } 

       sw.WriteLine(); 
      } 

      sw.Close(); 
     } 
    } 
+0

Funziona come un fascino.Non mi interessa iterare due volte attraverso il set di dati in quanto è solo piccolo. Altri che considerano questa soluzione potrebbero voler prendere in considerazione alternative se si lavora con dataset di grandi dimensioni. Grazie, Roy! – bobble14988

+0

come è possibile formare più datatable in un dataset –

+0

@SwethaVijayan passare nel DataSet (ad esempio 'ds') come argomento invece di DataTable, quindi inserire la riga' foreach (DataTable dt in ds.Tables) 'sopra la riga che dice 'foreach (Riga DataRow in dt.Rows)' –

8

è meglio esportare i dati in formato xml.

set di dati ha un metodo per questo lavoro:

DataSet ds = new DataSet(); 
ds.WriteXml(fileName); 

si può leggere un xml e compilare i dati del set di dati come qui di seguito:

DataSet ds = new DataSet(); 
ds.ReadXml(fileName); 
0

Basta scorrere i file della tabella di dati e aggiungere linee al file, come nell'esempio fornito

foreach (DataRow row in dt.Rows)    
{  

    object[] array = row.ItemArray;       
    for (i = 0; i < array.Length - 1; i++)     
    {        
    sw.Write(array[i].ToString() + ";");      
    }  

    sw.Write(array[i].ToString()); 

    sw.WriteLine(); 

} 

Dove sw è uno StreamWrit er per archiviare dove vuoi salvare i dati. Dove si trova effettivamente un problema?

6

quello che vorrei fare è:

foreach (DataRow row in myDataSet.Tables[0].Rows) 
{ 
    foreach (object item in row.ItemArray) 
    { 
     myStreamWriter.Write((string)item + "\t"); 
    } 
    myStreamWriter.WriteLine(); 
} 

magari aggiungere i nomi di colonna prima i loop se si desidera che le intestazioni. Penso che, sebbene sia piuttosto semplice, dovrebbe fare il trucco.

2

E il sotto?

public static void Write(DataTable dt, string filePath) 
     { 
      int i = 0; 
      StreamWriter sw = null; 
       sw = new StreamWriter(filePath, false); 
       for (i = 0; i < dt.Columns.Count - 1; i++) 
       { 
        sw.Write(dt.Columns[i].ColumnName + " "); 
       } 
       sw.Write(dt.Columns[i].ColumnName); 
       sw.WriteLine(); 
       foreach (DataRow row in dt.Rows) 
       { 
        object[] array = row.ItemArray; 
        for (i = 0; i < array.Length - 1; i++) 
        { 
         sw.Write(array[i] + " "); 
        } 
        sw.Write(array[i].ToString()); 
        sw.WriteLine(); 
       } 
       sw.Close(); 
     } 
0

Sono un principiante nell'industria del software e sto solo cercando di aiutarti. Questa potrebbe non essere una soluzione definitiva al tuo problema.

Ho letto il link che hai mensionato. È vero che esporta solo in formato delimitato da virgole. Se vuoi esportare come te, devi fare qualche sforzo in più. LINQ ridurrà notevolmente il tuo lavoro. quello che devi fare è: 1) Calcolare la larghezza massima di ogni colonna nella tabella dati (usando LINQ questo può essere fatto in una stessa istruzione altrimenti devi prendere l'aiuto di foreach). 2) prima di scrivere il valore effettivo della cella nel file di testo, utilizzare String.Format per posizionare secondo la larghezza calcolata nel primo passaggio.

List<int> ColumnLengths = new List<int>(); 

     ds.Tables["TableName"].Columns.Cast<DataColumn>().All((x) => 
     { 
      { 
       ColumnLengths.Add(ds.Tables["TableName"].AsEnumerable().Select(y => y.Field<string>(x).Length).Max()); 
      } 
      return true; 
     }); 


     foreach (DataRow row in ds.Tables["TableName"].Rows) 
     { 
      for(int col=0;col<ds.Tables["TableName"].Columns.Count;col++) 
      { 
       SW.Write(row.Field<string>(ds.Tables["TableName"].Columns[col]).PadLeft(ColumnLengths[col] + (4 - (ColumnLengths[col] % 4)))); 
      } 
      SW.WriteLine(); 
     } 

Spero che troverai utile.