Reputation: 1001
I am reading a csv file from the web and converting it to a DataTable. The 1st column is a string. 2nd, 3rd and 4th columns are numericals. I'd like to convert the 2nd, 3rd and 4th columns to double. I've written the method below to perform this task. However, when I do the conversion "Convert.ToDouble" and store it back to the data row it seems to keep it as a string object.
public static DataTable ConvertCSVtoDataTable(string strFilePath)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strFilePath);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string[] headers = sr.ReadLine().Split(',');
DataTable dt = new DataTable();
foreach (string header in headers)
{
dt.Columns.Add(header);
}
while (!sr.EndOfStream)
{
string[] rows = sr.ReadLine().Split(',');
DataRow dr = dt.NewRow();
for (int i = 0; i < headers.Length; i++)
{
switch (i)
{
//Convert columns 1,2, and 3 to double
case 1:
dr[i] = Convert.ToDouble(rows[i]);
break;
case 2:
dr[i] = Convert.ToDouble(rows[i]);
break;
case 3:
dr[i] = Convert.ToDouble(rows[i]);
break;
default:
dr[i] = rows[i];
break;
}
}
dt.Rows.Add(dr);
}
return dt;
}
Upvotes: 2
Views: 3099
Reputation: 27861
You need to specify the column type when you add the column. Change the code that creates the columns to something like this (based on which columns you want to have type double
):
foreach (string header in headers.Take(3))
{
dt.Columns.Add(header, typeof(double));
}
foreach (string header in headers.Skip(3))
{
dt.Columns.Add(header, typeof(string));
}
This code will create the first three columns with type double
and the rest of the columns with type string
.
Quoting from this MSDN reference:
By default, the DataType for the new column is string
If you don't specify a type, then you get a column with the default type which is string
.
Upvotes: 2
Reputation: 11
Instead of:
foreach (string header in headers)
{
dt.Columns.Add(header);
}
use
for (int i = 0; i < headers.Count(); i++ )
{
switch (i)
{
case 1: case 2: case 3:
dt.Columns.Add(headers[i], typeof(double));
break;
default:
dt.Columns.Add(headers[i], typeof(string));
break;
}
}
Upvotes: 1
Reputation: 14231
Replace foreach
loop to
for (int i = 0; i < headers.Length; i++)
{
if (i >= 1 && i <= 3)
dt.Columns.Add(headers[i], typeof(double));
else
dt.Columns.Add(headers[i]);
}
Upvotes: 1