Convert String to DataTable using ASP.NET MVC - c#

I am trying to convert string to DataTable using the ffollowing method , But It did"nt work
public static DataTable convertStringToDataTable(string data)
{
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach (string row in data.Split('\n'))
{
DataRow dataRow = dataTable.NewRow();
foreach (string cell in row.Split(','))
{
string[] keyValue = cell.Split('"');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(keyValue[0]);
dataTable.Columns.Add(dataColumn);
}
dataRow[keyValue[0]] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
Code that contains data string :
StringWriter sw = new StringWriter();
sw.WriteLine("\"NumClient\",\"Raisons Sociale\",\"DateDocument\",\"NumCommandeNAV\",\"Réference\",\"Designation\",\"QteCommandée\",\"QteLivrée\",\"QteAnnulée\",\"Reste à Livrer\",\"Type Disponibilite\",\"DateDisponibilite\"");
var EnTete =
db.AURES_GROS_EnTeteCommande.Where(e => e.NumCommandeNAV != " " && e.NumCommandeNAV != "_")
.OrderBy(x => x.CodeMagasin)
.ThenBy(s => s.NumClient)
.ThenBy(c => c.DateDocument)
.OrderByDescending(x => x.NumCommandeNAV)
.ToList();
foreach (var element in EnTete)
{
string statut = RecuperStatut(element.NumCommandeNAV);
if (statut == "A livrer")
{
Raison = context.Users.First(x => x.No_ == element.NumClient).RaisonSociale;
lignes = db.AURES_GROS_LigneCommande.Where(x => x.NumDocument == element.NumDocument).ToList();
foreach (var elt in lignes)
{
sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\",\"{10}\",\"{11}\"",
element.NumClient,
Raison,
element.DateDocument,
element.NumCommandeNAV,
elt.CodeArticle,
elt.Designation,
elt.Quantite,
0,
elt.QteANNULEE,
elt.Quantite,
element.Couleur,
elt.DateDisponibilite
));
}
}
}
DataTable t = convertStringToDataTable(sw.ToString());
Response.ClearContent();
Response.ClearHeaders();
Response.BufferOutput = true;
Response.ContentType = "text/excel";
Response.AddHeader("Content-Disposition", "attachment; filename=Reliquat" + DateTime.Now.ToString("yyyy_MM_dd") + ".csv");
Response.Write(t);
Response.Flush();
Response.Close();
//Response.End();
In this code I want I wnat to export data to Excel file
Any one have solutions
Thanks,

I think you want to create a DataTable from a string. So first split the "rows" and then the "columns". You are adding the DataColumns in the row-loop. You need that only once before the loop. Here is another implementation which handles this and other edge cases you haven't considered yet:
public static DataTable ConvertStringToDataTable(string data)
{
DataTable dataTable = new DataTable();
// extract all lines:
string[] lines = data.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
string header = lines.FirstOrDefault();
if (header == null)
return dataTable;
// first create the columns:
string[] columns = header.Split(','); // using commas as delimiter is brave ;)
foreach (string col in columns)
dataTable.Columns.Add(col.Trim());
foreach (string line in lines.Skip(1))
{
string[] fields = line.Split(',');
if(fields.Length != dataTable.Columns.Count)
continue; // should not happen
DataRow dataRow = dataTable.Rows.Add();
for (int i = 0; i < fields.Length; i++)
dataRow.SetField(i, fields[i]);
}
return dataTable;
}

You can convert your column foreach to a for loop.
public static DataTable convertStringToDataTable(string data)
{
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach (string row in data.Split('\n'))
{
DataRow dataRow = dataTable.NewRow();
string[] cell = row.Split(',');
for (int i = 0; i < cell.Length; i++)
{
string[] keyValue = cell[i].Split('"');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn();
dataTable.Columns.Add(dataColumn);
}
dataRow[i] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
However if your split string[] keyValue = cell.Split('"'); is not returning what you are expecting you may need to investigate further.

Related

GridView (Aspx)(CSV) Data is not displayed correctly in the rows

The data is not displayed correctly in the columns.
The CSV consists of 7 columns. Rows are of different length.
I can not upload a picture.(https://ibb.co/0fnfLW7)
DataTable tblcsv = new DataTable();
tblcsv.Columns.Add("Vorname");
tblcsv.Columns.Add("Nachname");
tblcsv.Columns.Add("RFID");
string csvData = File.ReadAllText(csvPath);
//spliting row after new line
foreach (string csvRow in csvData.Split(';'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
tblcsv.Rows.Add();
int count = 0;
foreach (string FileRec in csvRow.Split(';'))
{
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
count++;
for(var x=0; x<7; x++)
{
//tblcsv[x][count] = FileRec;
}
count++;
}
}
//Calling Bind Grid Functions
BindgridStaffImport(tblcsv);
}
You split code is using ";", and should it not be "," if a csv?
The code will look much like this:
foreach (string csvRow in csvData.Split(';'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
DataRow MyNewRow = tblcsv.NewRow();
int count = 0;
foreach (string FileRec in csvRow.Split(','))
{
MyNewRow[count] = FileRec;
count++;
}
tblcsv.Rows.Add(MyNewRow);
}
//Calling Bind Grid Functions
BindgridStaffImport(tblcsv);
So, use the "newRow" method to create a new blank row based on the table. Set the column values, and then add this new row to the rows collection of the table.
And even better is to use the TextFieldParser class.
So,
using Microsoft.VisualBasic.FileIO;
And then you can even assume say the first row has the colum names.
This:
We assume you read the csv file into stirng sFileLocal
// process csv file
TextFieldParser MyParse = new TextFieldParser(sFileLocal);
MyParse.TextFieldType = FieldType.Delimited;
MyParse.SetDelimiters(new string[] { "," });
MyParse.HasFieldsEnclosedInQuotes = true;
// add colums to table.
DataTable rstData = new DataTable();
foreach (string cCol in MyParse.ReadFields())
{
rstData.Columns.Add(cCol);
}
while (!MyParse.EndOfData)
{
string[] OneRow = MyParse.ReadFields();
rstData.Rows.Add(OneRow);
}
// Now display results in a grid
GridView1.DataSource = rstData;
GridView1.DataBind();
Quite much all above is you need.
Thank you very much for the support.
I now have a working variant.
However, the goal is to skip the first line, the header.
Are there any ideas how I can implement this.
List<string> headercolumns = new List<string> { "Vorname", "Nachname", };
DataTable dt = new DataTable();
foreach (string header in headercolumns)
{
dt.Columns.Add(header);
}
List<string> StaffList = new List<string>();
using (StreamReader filereader = new StreamReader(StaffFileUpload.FileContent))
{
string readline = string.Empty;
while ((readline = filereader.ReadLine()) != null)
{
StaffList.Add(readline);
}
if (StaffList != null && StaffList.Count > 0)
{
foreach (string info in StaffList)
{
DataRow row = dt.NewRow();
string[] mitarbeiter = info.Split(';');
for (int i = 0; i < mitarbeiter.Length; i++)
{
row[i] = mitarbeiter[i];
}
dt.Rows.Add(row);
}
}
}

how to make readfield read next field

My csv file contains 8 columns and 300k rows.Here is an example of my csv file
"0195153448";"Classical Mythology";"Mark P. O. Morford";"2002";"Oxford University Press";"http://images.amazon.com/images/P/0195153448.01.THUMBZZZ.jpg";"http://images.amazon.com/images/P/0195153448.01.MZZZZZZZ.jpg";"http://images.amazon.com/images/P/0195153448.01.LZZZZZZZ.jpg"
"0002005018";"Clara Callan";"Richard Bruce Wright";"2001";"HarperFlamingo Canada";"http://images.amazon.com/images/P/0002005018.01.THUMBZZZ.jpg";"http://images.amazon.com/images/P/0002005018.01.MZZZZZZZ.jpg";"http://images.amazon.com/images/P/0002005018.01.LZZZZZZZ.jpg"
Now i have this code for reading
string path = #"C:\Users\SEMRUK\Desktop\exceller\kitaplik.csv";
public DataTable GetDataTabletFromCSVFile(string PathFile)
{
DataTable csvData = new DataTable();
TextFieldParser csvReader = new TextFieldParser(PathFile);
csvReader.SetDelimiters(new string[] {";"});
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
string[] fieldData = csvReader.ReadFields();
while (!csvReader.EndOfData)
{
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
MessageBox.Show(fieldData[i]);
}
csvData.Rows.Add(fieldData);
}
return csvData;
}
This way i can read the first 8 rows.But i can't read anything after that.It just reads first 8.How can i tell the code that it should read after tab too.I tried adding \t to the setdelimiters but didn't work.Any suggestions?
static void Main(string[] args)
{
string path = "your_file_path";
string text = System.IO.File.ReadAllText(path);
string[] parsedText= text.Split(';');
foreach (var item in parsedText)
{
//do some
}
}

How to add a column checkbox in a datagriview with data of csv file using c#

I want to add a new column with checkbox, my data is from a csv file and showed it in a datagridview with this code:
DataTable dtDataSource = new DataTable();
string[] fileContent = File.ReadAllLines(\data.csv);
if (fileContent.Count() > 0)
{
//Create data table columns
dtDataSource.Columns.Add("ID);
dtDataSource.Columns.Add("Data 1");
dtDataSource.Columns.Add("Data 2");
dtDataSource.Columns.Add("Status");
//Add row data dynamically
for (int i = 1; i < fileContent.Count(); i++)
{
string[] rowData = fileContent[i].Split(',');
dtDataSource.Rows.Add(rowData);
}
if (dtDataSource != null)
{
dataGridView1.DataSource = dtDataSource;
}
}
But also I need to validate if checkbox is checked, the column ¨Status¨, their value must be changed by 1 or if is it unchecked the value must be 0 in every row of datagridview.
Example:
ID,Data1,Data2,Status,checkbox
1,aaa,bbb,0,✓
2,ccc,ddd,1,(unchecked)
3,eee,fff,1,(unchecked)
When you click the save button, the csv file should looks like this:
ID,Data1,Data2,Status
1,aaa,bbb,1
2,ccc,ddd,0
3,eee,fff,0
What I should do? Any ideas? CSV file is a little difficult for me.
Thank you!
I resolved this, thanks anyway..
This is the code:
string id;
for (int i = 0; i < dataGridView1.RowCount; i++) {
String path = "\\registros.csv";
List<String> lines = new List<String>();
if (File.Exists(path))
{
using (StreamReader reader = new StreamReader(path))
{
String line;
while ((line = reader.ReadLine()) != null)
{
id = (string)dataGridView1.Rows[i].Cells[2].Value;
if (line.Contains(","))
{
String[] split = line.Split(',');
if (split[1].Equals(id) && (bool)dataGridView1.Rows[i].Cells[0].FormattedValue == true)
{
split[10] = "" + 1;
line = String.Join(",", split);
}
if (split[1].Equals(id) && (bool)dataGridView1.Rows[i].Cells[0].FormattedValue == false)
{
split[10] = "" + 0;
line = String.Join(",", split);
}
}
lines.Add(line);
}
}
using (StreamWriter writer = new StreamWriter(path, false))
{
foreach (String line in lines)
writer.WriteLine(line);
}
}
}

Object reference on array with regex.replace()

I am using the below function to import a csv file into a datatable object csvData, however i face an oject reference issue that i'd like to understand more while using Regex.Replace to remove quote marks from the data:
private static DataTable Gettabledata(string cpath)
{
DataTable csvData = new DataTable();
try
{
using (TextFieldParser csvReader = new TextFieldParser(cpath))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
string pattern="\""; % remove quotation mark "
string replacement=""; % replace by empty.(eg "a", a)
Regex rgx = new Regex(pattern);
for (int i = 0; i < fieldData.Length; i++)
fieldData[i] = Regex.Replace(fieldData[i],pattern, replacement); %object reference issue
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
The fieldData[i] = Regex.Replace(fieldData[i],pattern, replacement); is outside the {...} block. It should be inside it.
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
else
{
fieldData[i] = Regex.Replace(fieldData[i],pattern, replacement);
}
}

export a list of table to CSV file

I am trying to export a list of table to comma-separated value(CSV) .but not getting the correct output .output coming from this code is in the form of html table.
Here is my code,Help Me ....
Thanks
public void ExportToCsv()
{
DataClassesDataContext db = new DataClassesDataContext();
var employee = db.Employees.ToList();
var grid = new System.Web.UI.WebControls.GridView();
grid.DataSource = employee;
grid.DataBind();
StringBuilder strbldr = new StringBuilder();
for (int i = 0; i < grid.Columns.Count; i++)
{
strbldr.Append(grid.Columns[i].HeaderText + ',');
}
for (int j = 0; j < grid.Rows.Count; j++)
{
for (int k = 0; k < grid.Columns.Count; k++)
{
//separating gridview columns with comma
strbldr.Append(grid.Rows[j].Cells[k].Text + ',');
}
//appending new line for gridview rows
strbldr.Append("\n");
}
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=YourFileName.csv");
Response.ContentType = "text/csv";
StringWriter sa = new StringWriter(strbldr);
HtmlTextWriter ht = new HtmlTextWriter(sa);
grid.RenderControl(ht);
Response.Write(sa.ToString());
Response.End();
}
I think First you convert your list to datatable by using below code
public static DataTable ToDataTable<T>(List<T> l_oItems)
{
DataTable oReturn = new DataTable(typeof(T).Name);
object[] a_oValues;
int i;
//#### Collect the a_oProperties for the passed T
PropertyInfo[] a_oProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
//#### Traverse each oProperty, .Add'ing each .Name/.BaseType into our oReturn value
//#### NOTE: The call to .BaseType is required as DataTables/DataSets do not support nullable types, so it's non-nullable counterpart Type is required in the .Column definition
foreach (PropertyInfo oProperty in a_oProperties)
{
oReturn.Columns.Add(oProperty.Name, BaseType(oProperty.PropertyType));
}
//#### Traverse the l_oItems
foreach (T oItem in l_oItems)
{
//#### Collect the a_oValues for this loop
a_oValues = new object[a_oProperties.Length];
//#### Traverse the a_oProperties, populating each a_oValues as we go
for (i = 0; i < a_oProperties.Length; i++)
{
a_oValues[i] = a_oProperties[i].GetValue(oItem, null);
}
//#### .Add the .Row that represents the current a_oValues into our oReturn value
oReturn.Rows.Add(a_oValues);
}
//#### Return the above determined oReturn value to the caller
return oReturn;
}
private static Type BaseType(Type oType)
{
//#### If the passed oType is valid, .IsValueType and is logicially nullable, .Get(its)UnderlyingType
if (oType != null && oType.IsValueType &&
oType.IsGenericType && oType.GetGenericTypeDefinition() == typeof(Nullable<>)
)
{
return Nullable.GetUnderlyingType(oType);
}
//#### Else the passed oType was null or was not logicially nullable, so simply return the passed oType
else
{
return oType;
}
}
Then Use below code for export datatable to csv..
public static string ToCSV(DataTable dataTable)
{
//create the stringbuilder that would hold the data
StringBuilder sb = new StringBuilder();
//check if there are columns in the datatable
if (dataTable.Columns.Count != 0)
{
//loop thru each of the columns for headers
foreach (DataColumn column in dataTable.Columns)
{
//append the column name followed by the separator
sb.Append(column.ColumnName + ",");
}
//append a carriage return
sb.Append("\r\n");
//loop thru each row of the datatable
foreach (DataRow row in dataTable.Rows)
{
//loop thru each column in the datatable
foreach (DataColumn column in dataTable.Columns)
{
//get the value for the row on the specified column
// and append the separator
sb.Append("\"" + row[column].ToString() + "\"" + ",");
}
//append a carriage return
sb.Append("\r\n");
}
}
return (sb.ToString());
}
Main Function is : This
DataTable dt = GeneralFunctions.ToDataTable(HereputyourlistforcovertToDataTable);
if (dt != null)
{
if (dt.Rows.Count > 0)
{
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "text/CSV";
Response.AddHeader("content-disposition", "attachment; filename=ReceivingLog.csv");
Response.Write(ToCSV(dt));
Response.End();
}
}

Categories