2011-08-24 14 views
14

Istnieje wiele przykładów w Internecie, w jaki sposób wypełnić DataSet z pliku tekstowego, ale chcę zrobić odwrotnie. Jedyne, co udało mi się znaleźć to this, ale wydaje się ... niekompletne?Export C# DataSet do pliku tekstowego

chcę być w czytelnej formie, a nie tylko rozdzielane przecinkami, więc nie równe odstępy między kolumnami w każdym wierszu, czy to ma sens. Oto przykład tego, co mam na myśli:

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

Uwaga: Mam tylko jeden DataTable wewnątrz więc mój DataSet nie trzeba się martwić o wielu DataTables.

EDIT: Kiedy powiedziałem „czytelny” miałem na myśli czytelny dla człowieka.

Z góry dziękuję.

+0

Wiesz, że to będzie pasować tylko do stałej czcionki, prawda? –

+0

Tak, wiem o tym. – bobble14988

Odpowiedz

15

Powinno to przestrzeń poza ustaloną długość tekstu czcionki ładnie, ale to nie znaczy, że będzie przetwarzać pełnej DataTable dwukrotnie (pass 1: znaleźć najdłuższy tekst na kolumnę, przechodzą 2: tekst wyjściowy):

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

Działa jak urok.Nie mam nic przeciwko iteracji dwa razy przez zbiór danych, ponieważ jest tylko mały. Inni rozważający to rozwiązanie mogą chcieć rozważyć alternatywy w przypadku pracy z dużymi zbiorami danych. Dzięki, Roy! – bobble14988

+0

jak to zrobić z wielu datatable w zestawie danych –

+0

@SwethaVijayan przekazać w DataSet (np. 'Ds') jako argument zamiast DataTable, a następnie wstawić linię' foreach (DataTable dt w ds.Tables) 'powyżej linii który mówi: foreach (wiersz DataRow w dt.Rows) ' –

8

to lepiej, że eksport danych do formatu XML.

zestaw danych mają metodę pracy:

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

można przeczytać xml i wypełnić dane zestawu danych jak poniżej:

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

Wystarczy iteracyjne nad wiersze tabeli danych i dodać linie do pliku, jak w przykładzie przewidzianego

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

} 

Gdzie sw jest StreamWrit er do pliku, w którym chcesz zapisać dane. Gdzie właściwie jest problem?

6

co chciałbym zrobić, to:

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

Może dodać nazwy kolumn przed pętlami jeśli chcesz nagłówki. Uważam, że chociaż jest raczej prosty, powinien załatwić sprawę.

2

co poniżej?

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

Jestem początkującym w branży oprogramowania i po prostu staram się pomóc. To nie może być ostateczne rozwiązanie twojego problemu.

Czytałem link ty mensioned. To prawda, że ​​jest to jedyny eksportowany format z delikcją przecinkową. Jeśli chcesz wyeksportować, jak chcesz, musisz podjąć dodatkowe wysiłki. LINQ znacznie ograniczy twoją pracę. co musisz zrobić, to: 1) Oblicz maksymalną szerokość każdej kolumny w tabeli danych (używając LINQ można to zrobić w jednej instrukcji, w przeciwnym razie musisz skorzystać z pomocy foreach). 2) przed wklejeniem rzeczywistej wartości komórki do pliku tekstowego użyj String.Format do ustawienia zgodnie z obliczoną szerokością w 1. kroku.

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(); 
     } 

Mam nadzieję, że okaże się to pomocne.