How can I load a CSV file into a System.Data.DataTable
, creating the datatable based on the CSV file?
Does the regular ADO.net functionality allow this?
Very basic answer: if you don't have a complex csv that can use a simple split function this will work well for importing (note this imports as strings, i do datatype conversions later if i need to)
private DataTable csvToDataTable(string fileName, char splitCharacter)
{
StreamReader sr = new StreamReader(fileName);
string myStringRow = sr.ReadLine();
var rows = myStringRow.Split(splitCharacter);
DataTable CsvData = new DataTable();
foreach (string column in rows)
{
//creates the columns of new datatable based on first row of csv
CsvData.Columns.Add(column);
}
myStringRow = sr.ReadLine();
while (myStringRow != null)
{
//runs until string reader returns null and adds rows to dt
rows = myStringRow.Split(splitCharacter);
CsvData.Rows.Add(rows);
myStringRow = sr.ReadLine();
}
sr.Close();
sr.Dispose();
return CsvData;
}
My method if I am importing a table with a string[] separater and handles the issue where the current line i am reading may have went to the next line in the csv or text file <- IN which case i want to loop until I get to the total number of lines in the first row (columns)
public static DataTable ImportCSV(string fullPath, string[] sepString)
{
DataTable dt = new DataTable();
using (StreamReader sr = new StreamReader(fullPath))
{
//stream uses using statement because it implements iDisposable
string firstLine = sr.ReadLine();
var headers = firstLine.Split(sepString, StringSplitOptions.None);
foreach (var header in headers)
{
//create column headers
dt.Columns.Add(header);
}
int columnInterval = headers.Count();
string newLine = sr.ReadLine();
while (newLine != null)
{
//loop adds each row to the datatable
var fields = newLine.Split(sepString, StringSplitOptions.None); // csv delimiter
var currentLength = fields.Count();
if (currentLength < columnInterval)
{
while (currentLength < columnInterval)
{
//if the count of items in the row is less than the column row go to next line until count matches column number total
newLine += sr.ReadLine();
currentLength = newLine.Split(sepString, StringSplitOptions.None).Count();
}
fields = newLine.Split(sepString, StringSplitOptions.None);
}
if (currentLength > columnInterval)
{
//ideally never executes - but if csv row has too many separators, line is skipped
newLine = sr.ReadLine();
continue;
}
dt.Rows.Add(fields);
newLine = sr.ReadLine();
}
sr.Close();
}
return dt;
}