简体   繁体   中英

Most efficient way of converting a DataTable to CSV

I'm working with DataTable's and I need to convert them to a CSV file format. Most of the tables I am working with have over 50,000 records so I'm trying to minimize the time it takes to convert them.

Here is my current method:

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

Is there any way I can improve the efficiency of this method? I'm welcome to any modifications and ideas that you have!

Use a System.Text.StringBuilder for huge strings - that's pretty fast. I implemented this one:

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

Here's a method I have in my Utility class. Works well for what I'm doing.

 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
        }
    }

I have used this method which copies object array to an Excel cell range rather than copying row by row and then column by column & it proved to be quite efficient way

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM