Question Moyen le plus efficace de convertir un DataTable en CSV


Je travaille avec DataTable et je dois les convertir au format de fichier CSV. La plupart des tables sur lesquelles je travaille ont plus de 50 000 enregistrements, alors j'essaie de minimiser le temps nécessaire pour les convertir.

Voici ma méthode actuelle:

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

Y a-t-il un moyen d'améliorer l'efficacité de cette méthode? Je vous souhaite la bienvenue à toutes les modifications et idées que vous avez!


10
2018-02-13 15:51


origine


Réponses:


oui, utilisez un System.Text.StringBuilder pour les énormes cordes. J'ai implémenté celui-ci:

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

15
2018-02-13 15:54



Voici une méthode que j'ai dans ma classe Utility. Fonctionne bien pour ce que je fais.

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

6
2018-02-13 16:38



J'ai utilisé cette méthode qui copie un tableau d'objets dans une plage de cellules Excel plutôt que de copier ligne par ligne et colonne par colonne, ce qui s'est avéré très efficace

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

2
2018-02-13 16:00