Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

export large datatable data to .csv file in c# windows applications

Tags:

c#

mysql

winforms

I need to export large DataTable(> 50 lacs( 5M ) DataRows ) to a .csv file

I am using the below code, but its taking long time.

public void CreateCSVFile(DataTable dtDataTablesList, string strFilePath)
{
    // Create the CSV file to which grid data will be exported.
    StreamWriter sw = new StreamWriter(strFilePath, false);
    //First we will write the headers.
    int iColCount = dtDataTablesList.Columns.Count;
    for (int i = 0; i < iColCount; i++)
    {
        sw.Write(dtDataTablesList.Columns[i]);
        if (i < iColCount - 1)
        {
            sw.Write("", "");
        }
    }
    sw.Write(sw.NewLine);

    // Now write all the rows.
    foreach (DataRow dr in dtDataTablesList.Rows)
    {
        for (int i = 0; i < iColCount; i++)
        {
            if (!Convert.IsDBNull(dr[i]))
            {
                sw.Write(dr[i].ToString());
            }
            if (i < iColCount - 1)
            {
                sw.Write("", "");
            }
        }
        sw.Write(sw.NewLine);
    }
    sw.Close();
}

Kindly let me know any another way of doing quickly.

like image 784
kishore Avatar asked Sep 07 '12 07:09

kishore


People also ask

Is CSV used for large data transfer?

CSV files are most commonly used to transfer huge data between systems.

How do I create a CSV file in C sharp?

ToString(); string csv = string. Format("{0},{1}\n", first, second); File. WriteAllText(filePath, csv); The whole function runs inside a loop, and every row should be written to the csv file.


1 Answers

Instead of call StreamWriter.Write(..) all the time you may consider using a StringBuilder. Append all strings to Builder and only write once on the disk!

string filePath = @"e:\temp\test.csv";
string delimiter = ",";

#region init DataTable
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("a", typeof(string)));
dt.Columns.Add(new DataColumn("b", typeof(string)));
dt.Columns.Add(new DataColumn("c", typeof(string)));
dt.Columns.Add(new DataColumn("d", typeof(string)));
dt.Columns.Add(new DataColumn("e", typeof(string)));
dt.Columns.Add(new DataColumn("f", typeof(string)));
dt.Columns.Add(new DataColumn("g", typeof(string)));
dt.Columns.Add(new DataColumn("h", typeof(string)));
dt.Columns.Add(new DataColumn("i", typeof(string)));
dt.Columns.Add(new DataColumn("j", typeof(string)));
dt.Columns.Add(new DataColumn("k", typeof(string)));
dt.Columns.Add(new DataColumn("l", typeof(string)));
dt.Columns.Add(new DataColumn("m", typeof(string)));
dt.Columns.Add(new DataColumn("n", typeof(string)));
dt.Columns.Add(new DataColumn("o", typeof(string)));
dt.Columns.Add(new DataColumn("p", typeof(string)));

for (int i = 0; i < 100000; i++)
{
    DataRow dr = dt.NewRow();
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        dr[j] = "test" + i + " " + j;
    }
    dt.Rows.Add(dr);
}
#endregion

Stopwatch sw = new Stopwatch();
sw.Start();
StringBuilder sb = new StringBuilder();
foreach (DataRow dr in dt.Rows)
{
    sb.AppendLine(string.Join(delimiter, dr.ItemArray));
}
File.WriteAllText(filePath, sb.ToString());
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadLine();

EDIT

100000 rows took me 271 ms and created a file of around 18 MB

As @aiodintsov pointed out, there may/will be problems with using StringBuilder if there are several MBs of data. So I created an example according to his comment. Worked fine for me. Exported 1 000 000 rows within 2685 ms.

Stopwatch sw = new Stopwatch();
sw.Start();
using (StreamWriter swr = 
         new StreamWriter(File.Open(filePath, FileMode.CreateNew), Encoding.Default, 1000000))
         // change buffer size and Encoding to your needs
{
    foreach (DataRow dr in dt.Rows)
    {
        swr.WriteLine(string.Join(delimiter, dr.ItemArray));
    }
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
like image 166
Pilgerstorfer Franz Avatar answered Sep 20 '22 12:09

Pilgerstorfer Franz