I have this block of code which reads a text file [Tab delimited] and return a data table. But the problem is that it treat the first line of the file or record as the header and display the remaining lines as records which subtract the number of record by - 1
so now i want the code to read all the content of the file as records.
here is the code:
streamReader reader = new streamReader (filePath);
string line = reader.readLine();
Datatable dt = new Datatable ();
DataRow row;
string[] value = line.Split('\t');
foreach(string dc in value)
{
dt.columns.add(New DataColumn(dc));
}
while(!reader.endofStream)
{
value = reader.ReadLine().split('\t');
if (value.Length == dt.Columns.Count)
{
row = dt.NewRow();
row.ItemArray = value;
dt.Rows.Add(row);
}
}
return dt;
When i try to remove
foreach(string dc in value)
{
dt.columns.add(New DataColumn(dc));
}
and all lines code that depend on it , the dt return nothing.
how can i solve it ?
If you know that the there's no header, i assume that you don't know the name of the columns neither, do you? Then you need to add "anonymous" columns instead:
DataTable dt = new DataTable();
while (reader.Peek() >= 0)
{
string line = reader.ReadLine();
string[] fields = line.Split('\t');
if (dt.Columns.Count == 0)
{
foreach (string field in fields)
{
// will add default names like "Column1", "Column2", and so on
dt.Columns.Add();
}
}
dt.Rows.Add(fields);
}
DataTable dt = new DataTable();
var lines = File.ReadAllLines(strPath).ToList();
dt.Columns.AddRange(lines.First().Split(new char[] { '\t' }).Select(col => new DataColumn(col)).ToArray());
lines.RemoveAt(0);
lines.Select(x => x.Split(new char[] { '\t' })).ToList().ForEach(row => dt.Rows.Add(row));
Use this for test data
List<string> lines = new List<string>();
lines.Add("Col1\tCol2\tCol3");
lines.Add("aaa\tbbb\tccc");
Related
This is the button which I press in order the csv-s to be imported:
private void btnOpen_Click_1(object sender, EventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
// string[] files = Directory.GetFiles(fbd.SelectedPath);
string[] csvFiles = Directory.GetFiles(#"D:\CSV", "*.csv");
foreach (string filePath1 in csvFiles)
{
BindData(filePath1);
}
}
}
}
This is the method that is called for each csv. The problem is that it makes the datagridview each time the last csv is imported. I want a way that adds all the records not only my last imported csv:
private void BindData(string filePath)
{
DataTable dt = new DataTable();
using (TextFieldParser parser = new TextFieldParser(filePath))
{
// configure your parser to your needs
parser.TextFieldType = FieldType.Delimited;
parser.Delimiters = new string[] { ";" };
parser.HasFieldsEnclosedInQuotes = false; // no messy code if your data comes with quotes: ...;"text value";"another";...
// read the first line with your headers
string[] fields = parser.ReadFields();
// add the desired headers with the desired data type
dt.Columns.Add(fields[0], typeof(string));
dt.Columns.Add(fields[1], typeof(string));
dt.Columns.Add(fields[6], typeof(float));
dt.Columns.Add(fields[7], typeof(float));
dt.Columns.Add(fields[8], typeof(string));
dt.Columns.Add(fields[9], typeof(string));
// read the rest of the lines from your file
while (!parser.EndOfData)
{
// all fields from one line
string[] line = parser.ReadFields();
// create a new row
DataRow row = dt.NewRow();
// put data values; cast if needed - this example uses string type columns
row[0] = line[0];
row[1] = line[1];
row[2] = line[6];
row[3] = line[7];
row[4] = line[8];
row[5] = line[9];
// add the newly created and filled row
dt.Rows.Add(row);
}
}
this.dataGridView1.DataSource = dt;
// asign to DGV
}
Change this line
DataTable dt = new DataTable();
So it says:
DataTable dt = (this.dataGridView1.DataSource as DataTable) ?? new DataTable();
So that you either reuse your existing data source or make a new one if it is not set
I want code C# to import txt.file into datagridview
file txt.file me
code me datagridview show one columns
I have done this on button click event.
private void button1_Click(object sender, EventArgs e)
{
System.IO.StreamReader file = new System.IO.StreamReader("D:\\test.txt");
string[] columnnames = file.ReadLine().Split(' ');
DataTable dt = new DataTable();
foreach (string c in columnnames)
{
dt.Columns.Add(c);
}
string newline;
while ((newline = file.ReadLine()) != null)
{
DataRow dr = dt.NewRow();
string[] values = newline.Split(' ');
for (int i = 0; i < values.Length; i++)
{
dr[i] = values[i];
}
dt.Rows.Add(dr);
}
file.Close();
dataGridView1.DataSource = dt;
}
Here is text file :
And here is output :
Just update according to your need. Define Column name in text file or default in grid view
First of all replace Split(' ') with Split(',').
If the separator is tabulation use:
Split(new string[] { "\\tab" }, StringSplitOptions.None)
I've got a project that has to do a bulk import to SQL from a CSV file. Creating the data columns has been a success, however, I'm running into a problem with the rows. A comma is used as the delimiter to separate the columns which work great in the column names, but not in the rows of data. Some data has a comma to split name and surnames. Together with this, only every second field(column) is enclosed in double quotes. Using all this is breaking the rows in many more columns than it should. I have suggested changing the delimiter to a semicolon which actually works great and everything works fine, except this is not accepted by the customer as they don't want to change anything.
This is what I've done:
private static DataTable ImportFordEmailList(string csvFilePath)
{
DataTable csvData = new DataTable();
DataTable dt = new DataTable();
dt.Columns.Add("ColumnName");
dt.Rows.Clear();
try
{
using (TextFieldParser csvReader = new TextFieldParser(csvFilePath))
{
// csvReader.TextFieldType = FieldType.Delimited;
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = false;
csvReader.TrimWhiteSpace = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
if (dt.Rows.Count > 0)
{
string newColumn = Regex.Replace(column, "[^A-Za-z0-9]", "");
string findColum = "ColumnName = '" + newColumn.Trim() + "'";
DataRow[] foundRows = dt.Select(findColum);
if (foundRows.Length == 0)
{
DataRow dr = dt.NewRow();
dr["ColumnName"] = newColumn.Trim();
dt.Rows.Add(dr);
}
else
{
DataRow dr = dt.NewRow();
dr["ColumnName"] = newColumn.Trim() + "1";
dt.Rows.Add(dr);
}
}
else
{
string newColumn = column.Replace("'", "");
newColumn = newColumn.Replace(" ", "");
string clean = Regex.Replace(newColumn, "[^A-Za-z0-9 ]", "");
DataRow dr = dt.NewRow();
dr["ColumnName"] = clean.Trim();
dt.Rows.Add(dr);
}
}
foreach (DataRow row in dt.Rows)
{
string colName = Regex.Replace(row["ColumnName"].ToString().Trim(), "/^[ A-Za-z0-9]*$/", "");
DataColumn datecolumn = new DataColumn(colName);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
foreach (string s in fieldData)
{
s.Replace("\"","");
Regex.Replace(s, "/^[ A-Za-z0-9 '#.()]", "");
string a = s;
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
This is an example of how the data looks like:
Is there a way that I can work around this and make this work?
----- EDIT, Add data sample as text --------
Name,Name,Email,Manager Level1,Level 1 manager's email,Manager Level2,Level 2 manager's email
Adams, D. (Deon) ,"Adams, Deon. (D) ",username#email.com,"Masete, Thabo (B.T.)",username#email.com,"Fraser, Mervyn (M.)",username#email.com
Akaramunkongwanit, S. (Sirapra) ,"Akaramunkongwanit, Sirapra (S.)",username#email.com> ,"Naraphirom, Suphajitphat (Pin.)",username#email.com,"Jeeradeepalung, Jirawat (Jee.)",username#email.com
Angel, L. (Dave) ,"Angel, Dave (L.) ",username#email.com,"Causton, Keith (K.H.) ",username#email.com,"White, Chris- Manf Eng (C.F.) ",username#email.com
Apairat, J. (Janjira),"Apairat, Janjira (J.) "username#email.com,"Choksiriwanna, Phatthar (Patsy.)",username#email.com,"Phusitpoykai, Rachawan (R.) ",username#email.com
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I would like to extract data from a txt file and put it into a DataTable. The content in the txt file is in the following format:
sometext1:sometext2:sometext3 sometext4:sometext5:sometext6
sometext7:sometext8:sometext9 ...
Each line represents a row and every column is separated with ":" character.
I tried doing this:
DataTable tbl = new DataTable();
using (StreamWriter sw = File.CreateText(path))
{
string[] rows = content.Split('\n');
foreach (string s in rows)
{
string[] columns = s.Split(':');
foreach (string t in columns)
{
sw.WriteLine(t);
}
}
}
How can I read this file and add it to DataTable?
This is a simple method to do your job
public DataTable ConvertToDataTable (string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for(int col =0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col+1).ToString()));
string[] lines = System.IO.File.ReadAllLines(filePath);
foreach(string line in lines)
{
var cols = line.Split(':');
DataRow dr = tbl.NewRow();
for(int cIndex=0; cIndex < 3; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
Here's an excellent class that will copy CSV data into a datatable using the structure of the data to create the DataTable:
http://www.codeproject.com/Articles/11698/A-Portable-and-Efficient-Generic-Parser-for-Flat-F
This topic has also been discussed here:
How to read a CSV file into a .NET Datatable
However, if you are willing to write the code yourself, there is an example:
Dim csvFileFolder As String = "C:\YourFileFolder"
Dim csvFileName As String = "YourFile.csv"
'Note that the folder is specified in the connection string,
'not the file. That's specified in the SELECT query, later.
Dim connString As String = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" _
& csvFileFolder & ";Extended Properties=""Text;HDR=No;FMT=Delimited"""
Dim conn As New Odbc.OdbcConnection(connString)
'Open a data adapter, specifying the file name to load
Dim da As New Odbc.OdbcDataAdapter("SELECT * FROM [" & csvFileName & "]", conn)
'Then fill a data table, which can be bound to a grid
Dim dt As New DataTableda.Fill(dt)
It's in VB.NET, if you can't translate it to C# let me know.
Regards.
Well, you presumably have your data right here:
string[] rows = content.Split('\n');
foreach (string s in rows)
{
string[] columns = s.Split(':');
foreach (string t in columns)
{
// each data element
}
}
If you have a DataTable defined, you can add rows to it with a very similar construct. I don't know the structure of your table, but essentially you can do this:
string[] rows = content.Split('\n');
foreach (string s in rows)
{
string[] columns = s.Split(':');
var dataRow = someDataTable.NewRow();
dataRow["someColumnName"] = columns[0];
dataRow["anotherColumnName"] = columns[1];
dataRow["someOtherColumnName"] = columns[2];
// and so on...
someDataTable.Rows.Add(dataRow);
}
If the DataTable's columns aren't strongly named, you can also add items by index:
dataRow.Item[0] = columns[0];
dataRow.Item[1] = columns[1];
// and so on...
The below will execute the entire process as you outlined.
var table = new DataTable();
var fileContents = File.ReadAllLines("yourFile");
var splitFileContents = (from f in fileContents select f.Split(':')).ToArray();
int maxLength = (from s in splitFileContents select s.Count()).Max();
for (int i = 0; i < maxLength; i++)
{
table.Columns.Add();
}
foreach (var line in splitFileContents)
{
DataRow row = table.NewRow();
row.ItemArray = (object[])line;
table.Rows.Add(row);
}
I'm trying to export data in multiple files to a single datatable. I was able to add data to the dataset but it doesn't provide the output that I need. I guess it should be an error in my loop and I tried in different ways but failed to get the correct output. Given below the output that I receive:
And this is the output I need:
Please refer the coding that I used, and please help me to find where I'm going wrong. Thanks in advance.
OpenFileDialog thisDialog = new OpenFileDialog();
thisDialog.Multiselect = true;
DataTable dt = new DataTable();
if (thisDialog.ShowDialog() == DialogResult.OK)
{
foreach (string files in thisDialog.FileNames)
{
//each file generates two columns
DataColumn column1 = new DataColumn();
dt.Columns.Add(column1);
DataColumn column2 = new DataColumn();
dt.Columns.Add(column2);
using (System.IO.StreamReader file = new System.IO.StreamReader(files))
{
string line;
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
string dataLine = line.ToString();
string[] split = dataLine.Split(',');
int result = split.Length;
DataRow row = dt.NewRow();
dt.Rows.Add(split[2], split[3]);
}
}
}
}
dataGridView1.DataSource = dt;
}
You are adding a new row for each DISKXFER line in each file, with only the first two columns populated - dt.rows.add does this.
You should fill in more of the columns in dr, then add dr to the table.