2015-04-10 3 views
7

मैं एक एसक्यूएलडेटाडर से एक सीएसवी फ़ाइल उत्पन्न कर रहा हूं, हालांकि यह कॉलम नाम नहीं लिख रहा है, मैं इसे कैसे लिख सकता हूं?कॉलर नामों के साथ सीएसवी के लिए डेटा रीडर

SqlConnection conn = new SqlConnection(myconn); 
SqlCommand cmd = new SqlCommand("dbo.test", conn); 
cmd.CommandType = CommandType.StoredProcedure; 
conn.Open(); 
SqlDataReader reader = cmd.ExecuteReader(); 

StringBuilder sb = new StringBuilder(); 
StreamWriter sw = new StreamWriter(myfilePath + "testfile.csv"); 
while (reader.Read()) 
{ 
    for (int i = 0; i < reader.FieldCount; i++) 
    { 
     string value = reader[i].ToString(); 
     if (value.Contains(",")) 
      value = "\"" + value + "\""; 

     sb.Append(value.Replace(Environment.NewLine, " ") + ","); 
    } 
    sb.Length--; // Remove the last comma 
    sb.AppendLine(); 
} 
conn.Close(); 
sw.Write(sb.ToString()); 
sw.Close(); 
+0

की संभावित डुप्लिकेट http://stackoverflow.com/questions/681653/can-you -get-the-column-names-from-a-sqldatareader – Sybren

उत्तर

5

सभी कॉलम नामों में पढ़ें और से संलग्न कोड मैं उपयोग कर रहा हूँ इस प्रकार है sb फिर पुनरावृत्त पाठक।

SqlDataReader reader = cmd.ExecuteReader(); 
StringBuilder sb = new StringBuilder(); 

//Get All column 
var columnNames = Enumerable.Range(0, reader.FieldCount) 
         .Select(reader.GetName) //OR .Select("\""+ reader.GetName"\"") 
         .ToList(); 

//Create headers 
sb.Append(string.Join(",", columnNames)); 

//Append Line 
sb.AppendLine(); 

while (reader.Read()) 
.... 
+0

ठीक है, आपने मुझे इसे हराया, धन्यवाद। – User0

0

आप इस तरह, SqlDataReader.GetName विधि का उपयोग एक स्तंभ का नाम पाने के लिए कर सकते हैं::

for(int i = 0; i < reader.FieldCount; i++) 
{ 
    string columnName = reader.GetName(i); 
} 
0

आप SqlDataReader.GetName उपयोग कर सकते हैं स्तंभ नाम

for (int i = 0; i < reader.FieldCount; i++) 
{ 
    string columnName = reader.GetName(i); 
} 

इसके अलावा, आप नीचे की तरह एक विस्तार विधि बना सकते हैं पाने के लिए:

public static List<string> ToCSV(this IDataReader dataReader, bool includeHeaderAsFirstRow, string separator) 
{ 
    List<string> csvRows = new List<string>(); 
    StringBuilder sb = null; 

    if (includeHeaderAsFirstRow) 
    { 
     sb = new StringBuilder(); 
     for (int index = 0; index < dataReader.FieldCount; index++) 
     { 
      if (dataReader.GetName(index) != null) 
       sb.Append(dataReader.GetName(index)); 

      if (index < dataReader.FieldCount - 1) 
       sb.Append(separator); 
     } 
     csvRows.Add(sb.ToString()); 
    } 

    while (dataReader.Read()) 
    { 
     sb = new StringBuilder(); 
     for (int index = 0; index < dataReader.FieldCount - 1; index++) 
     { 
      if (!dataReader.IsDBNull(index)) 
      { 
       string value = dataReader.GetValue(index).ToString(); 
       if (dataReader.GetFieldType(index) == typeof(String)) 
       { 
        //If double quotes are used in value, ensure each are replaced but 2. 
        if (value.IndexOf("\"") >= 0) 
         value = value.Replace("\"", "\"\""); 

        //If separtor are is in value, ensure it is put in double quotes. 
        if (value.IndexOf(separator) >= 0) 
         value = "\"" + value + "\""; 
       } 
       sb.Append(value); 
      } 

      if (index < dataReader.FieldCount - 1) 
       sb.Append(separator); 
     } 

     if (!dataReader.IsDBNull(dataReader.FieldCount - 1)) 
      sb.Append(dataReader.GetValue(dataReader.FieldCount - 1).ToString().Replace(separator, " ")); 

     csvRows.Add(sb.ToString()); 
    } 
    dataReader.Close(); 
    sb = null; 
    return csvRows; 
} 

उदाहरण:

List<string> rows = null; 
using (SqlDataReader dataReader = command.ExecuteReader()) 
    { 
     rows = dataReader.ToCSV(includeHeadersAsFirstRow, separator); 
     dataReader.Close(); 
    } 
0

इस solution का उपयोग करके मैंने एक एक्सटेंशन बनाया।

/// <summary> 
/// 
/// </summary> 
/// <param name="reader"></param> 
/// <param name="filename"></param> 
/// <param name="path">if null/empty will use IO.Path.GetTempPath()</param> 
/// <param name="extension">will use csv by default</param> 
public static void ToCsv(this IDataReader reader, string filename, string path = null, string extension = "csv") 
{ 
    int nextResult = 0; 
    do 
    { 
     var filePath = Path.Combine(string.IsNullOrEmpty(path) ? Path.GetTempPath() : path, string.Format("{0}.{1}", filename, extension)); 
     using (StreamWriter writer = new StreamWriter(filePath)) 
     { 
      writer.WriteLine(string.Join(",", Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList())); 
      int count = 0; 
      while (reader.Read()) 
      { 
       writer.WriteLine(string.Join(",", Enumerable.Range(0, reader.FieldCount).Select(reader.GetValue).ToList())); 
       if (++count % 100 == 0) 
       { 
        writer.Flush(); 
       } 
      } 
     } 

     filename = string.Format("{0}-{1}", filename, ++nextResult); 
    } 
    while (reader.NextResult()); 
} 
3

मैं निम्नलिखित विकसित उच्च प्रदर्शन विस्तार

static void Main(string[] args) 
     { 
      SqlConnection sqlCon = new SqlConnection("Removed"); 
      sqlCon.Open(); 
      SqlCommand sqlCmd = new SqlCommand("Select * from Table", sqlCon); 
      SqlDataReader reader = sqlCmd.ExecuteReader(); 
      string csv=reader.ToCSVHighPerformance(true); 
      File.WriteAllText("Test.CSV", csv); 
      reader.Close(); 
      sqlCon.Close(); 
     } 

Extention:

public static string ToCSVHighPerformance(this IDataReader dataReader, bool includeHeaderAsFirstRow = true, 
      string separator = ",") 
     { 
      DataTable dataTable = new DataTable(); 
      StringBuilder csvRows = new StringBuilder(); 
      string row = ""; 
      int columns ; 
      try 
      { 
       dataTable.Load(dataReader); 
       columns= dataTable.Columns.Count; 
       //Create Header 
       if (includeHeaderAsFirstRow) 
       { 
        for (int index = 0; index < columns; index++) 
        { 
         row += (dataTable.Columns[index]); 
         if (index < columns - 1) 
          row += (separator); 
        } 
        row += (Environment.NewLine); 
       } 
       csvRows.Append(row); 

       //Create Rows 
       for (int rowIndex = 0; rowIndex < dataTable.Rows.Count; rowIndex++) 
       { 
        row = ""; 
        //Row 
        for (int index = 0; index < columns - 1; index++) 
        { 
         string value = dataTable.Rows[rowIndex][index].ToString(); 

         //If type of field is string 
         if (dataTable.Rows[rowIndex][index] is string) 
         { 
          //If double quotes are used in value, ensure each are replaced by double quotes. 
          if (value.IndexOf("\"") >= 0) 
           value = value.Replace("\"", "\"\""); 

          //If separtor are is in value, ensure it is put in double quotes. 
          if (value.IndexOf(separator) >= 0) 
           value = "\"" + value + "\""; 

          //If string contain new line character 
          while (value.Contains("\r")) 
          { 
           value = value.Replace("\r", ""); 
          } 
          while (value.Contains("\n")) 
          { 
           value = value.Replace("\n", ""); 
          } 
         } 
         row += value; 
         if (index < columns - 1) 
          row += separator; 
        } 
        dataTable.Rows[rowIndex][columns - 1].ToString().ToString().Replace(separator, " "); 
        row += Environment.NewLine; 
        csvRows.Append(row); 
       } 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
      return csvRows.ToString(); 
     } 
+0

जब आप उनके माध्यम से पुनरावृत्त करते हैं तो आप अंतिम कॉलम खो रहे हैं। 'के लिए' int (int index = 0; अनुक्रमणिका <कॉलम; अनुक्रमणिका ++) 'के लिए होना चाहिए (int index = 0; अनुक्रमणिका <कॉलम - 1; अनुक्रमणिका ++) ' –

संबंधित मुद्दे