2015-02-13 11 views
9

Tôi đang làm việc với DataTable và tôi cần phải chuyển đổi chúng sang định dạng tệp CSV. Hầu hết các bảng tôi đang làm việc có hơn 50.000 hồ sơ vì vậy tôi đang cố gắng giảm thiểu thời gian cần thiết để chuyển đổi chúng.Cách hiệu quả nhất để chuyển đổi một DataTable thành CSV

Đây là phương pháp hiện tại của tôi:

public static string table_to_csv(DataTable table) 
    { 
     string file = ""; 

     foreach (DataColumn col in table.Columns) 
      file = string.Concat(file, col.ColumnName, ","); 

     file = file.Remove(file.LastIndexOf(','), 1); 
     file = string.Concat(file, "\r\n"); 

     foreach (DataRow row in table.Rows) 
     { 
      foreach (object item in row.ItemArray) 
       file = string.Concat(file, item.ToString(), ","); 

      file = file.Remove(file.LastIndexOf(','), 1); 
      file = string.Concat(file, "\r\n"); 
     } 

     return file; 
    } 

Có cách nào tôi có thể nâng cao hiệu quả của phương pháp này? Tôi hoan nghênh mọi thay đổi và ý tưởng mà bạn có!

+2

Vì mã của bạn đang hoạt động và bạn không gặp phải vấn đề với nó, có thể [Code Review] (http://codereview.stackexchange.com/) là nơi tốt hơn cho câu hỏi của bạn hơn StackOverflow. –

+0

Tại sao bạn tải quá nhiều hàng ở địa điểm đầu tiên? Sẽ dễ dàng hơn khi sử dụng các công cụ của cơ sở dữ liệu (như SSIS trong SQL Server) để xuất dữ liệu sang CSV. Hoặc sử dụng DataReader để đọc dữ liệu ở chế độ firehose và ghi chúng vào một tệp. Tạo toàn bộ chuỗi trong bộ nhớ là * không * hiệu quả - hoặc sử dụng Write và WriteLine để viết chúng ra một tập tin. Hơn nữa, bạn có thể thay thế các kết nối lặp đi lặp lại với String.Join, mặc dù sử dụng 'Write' làm cho nó thừa một chút cũng như –

+0

có thể trùng lặp của [Chuyển đổi DataTable thành luồng CSV] (http://stackoverflow.com/questions/888181/convert- datatable-to-csv-stream) –

Trả lời

12

có, sử dụng System.Text.StringBuilder cho các chuỗi lớn. Tôi thực hiện điều này một:

public static string DataTableToCSV(this DataTable datatable, char seperator) 
{ 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < datatable.Columns.Count; i++) 
    { 
     sb.Append(datatable.Columns[i]); 
     if (i < datatable.Columns.Count - 1) 
      sb.Append(seperator); 
    } 
    sb.AppendLine(); 
    foreach (DataRow dr in datatable.Rows) 
    { 
     for (int i = 0; i < datatable.Columns.Count; i++) 
     { 
      sb.Append(dr[i].ToString()); 

      if (i < datatable.Columns.Count - 1) 
       sb.Append(seperator); 
     } 
     sb.AppendLine(); 
    } 
    return sb.ToString(); 
} 
+0

Câu trả lời này đáp ứng các yêu cầu của tôi, một DataTable có chứa hơn 30 nghìn bản ghi được sử dụng để mất vài phút, hiện mất dưới 1 giây. Cảm ơn. –

+1

làm cách nào để chuyển đổi tập dữ liệu thành csv? –

+0

@AkhilJain nếu bạn có nhiều Bảng trong Tập dữ liệu của mình - bạn không thể. Nếu bạn có một Table thì 'string result = DataTableToCSV (myDataSet.Tables [0], ',');' – fubo

2

Tôi đã sử dụng phương pháp này mà các bản sao mảng đối tượng đến một dãy ô Excel chứ không phải sao chép từng hàng và sau đó cột theo cột & nó được chứng minh là khá hiệu quả cách

public void ExportToExcel(DataTable dataTable, String pathToSave) 
    { 
     // Create the Excel Application object 
     var excelApp = new ApplicationClass(); 

     // Create a new Excel Workbook 
     Workbook excelWorkbook = excelApp.Workbooks.Add(Type.Missing); 

     int sheetIndex = 0; 

     // Copy the DataTable to an object array 
     var rawData = new object[dataTable.Rows.Count + 1, dataTable.Columns.Count]; 

     // Copy the column names to the first row of the object array 
     for (var col = 0; col < dataTable.Columns.Count; col++) 
     { 
      rawData[0, col] = dataTable.Columns[col].ColumnName; 
     } 

     // Copy the values to the object array 
     for (var col = 0; col < dataTable.Columns.Count; col++) 
     { 
      for (int row = 0; row < dataTable.Rows.Count; row++) 
      { 
       rawData[row + 1, col] = dataTable.Rows[row].ItemArray[col]; 
      } 
     } 

     // Calculate the final column letter 
     string finalColLetter = string.Empty; 
     const string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     int colCharsetLen = colCharset.Length; 

     if (dataTable.Columns.Count > colCharsetLen) 
     { 
      finalColLetter = colCharset.Substring(
       (dataTable.Columns.Count - 1)/colCharsetLen - 1, 1); 
     } 

     finalColLetter += colCharset.Substring((dataTable.Columns.Count - 1) % colCharsetLen, 1); 

     // Create a new Sheet 
     var excelSheet = (Worksheet)excelWorkbook.Sheets.Add(excelWorkbook.Sheets.Item[++sheetIndex], Type.Missing, 1, XlSheetType.xlWorksheet); 
     excelSheet.Name = dataTable.TableName; 

     // Fast data export to Excel 
     var excelRange = string.Format("A1:{0}{1}", finalColLetter, dataTable.Rows.Count + 1); 
     excelSheet.Range[excelRange, Type.Missing].Value2 = rawData; 

     // Mark the first row as BOLD and BLUE 
     var headerColumnRange = (Range)excelSheet.Rows[1, Type.Missing]; 
     headerColumnRange.Font.Bold = true; 
     headerColumnRange.Font.Color = 0xFF0000; 
     headerColumnRange.EntireColumn.AutoFit(); 

     // Save and Close the Workbook 
     excelWorkbook.SaveAs(pathToSave, XlFileFormat.xlWorkbookNormal, Type.Missing, 
      Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, 
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 
     excelWorkbook.Close(true, Type.Missing, Type.Missing); 
     excelWorkbook = null; 

     // Release the Application object 
     excelApp.Quit(); 
     excelApp = null; 

     // Collect the unreferenced objects 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
    } 
5

Đây là phương pháp tôi có trong lớp Tiện ích của tôi. Hoạt động tốt cho những gì tôi đang làm.

public static void GenerateCSV(DataTable dt) 
    { 
     StringBuilder sb = new StringBuilder(); 
     try 
     { 
      int count = 1; 
      int totalColumns = dt.Columns.Count; 
      foreach (DataColumn dr in dt.Columns) 
      { 
       sb.Append(dr.ColumnName); 

       if (count != totalColumns) 
       { 
        sb.Append(","); 
       } 

       count++; 
      } 

      sb.AppendLine(); 

      string value = String.Empty; 
      foreach (DataRow dr in dt.Rows) 
      { 
       for (int x = 0; x < totalColumns; x++) 
       { 
        value = dr[x].ToString(); 

        if (value.Contains(",") || value.Contains("\"")) 
        { 
         value = '"' + value.Replace("\"", "\"\"") + '"'; 
        } 

        sb.Append(value); 

        if (x != (totalColumns - 1)) 
        { 
         sb.Append(","); 
        } 
       } 

       sb.AppendLine(); 
      } 
     } 
     catch (Exception ex) 
     { 
      // Do something 
     } 
    } 
+1

Up bình chọn là giải pháp này cũng kiểm tra và thoát khỏi các chuỗi khi cần thiết. – Roberto

Các vấn đề liên quan