export a list of table to CSV file - c#

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();
}
}

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 export DataTable to excel but keep the formatting

I have 2 issues when converting DataTable to excel
The date format is messy, for example my original data is '2016-12-31', in excel it became '31-12-16'
Excel remove trailing zeroes, for example '01' become '1'
Here's the code
MemoryStream result = new MemoryStream();
StreamWriter writer = new StreamWriter(result);
CSVwriter csv = new CSVwriter();
string content = csv.GetFromTable(table);
writer.Write(content);
writer.Flush();
return result;
GetFromTable method
StringBuilder str = new StringBuilder();
StringBuilder rowstr = new StringBuilder();
string Encloser = "\""
foreach (DataRow row in table.Rows) {
rowstr.Length = 0;
foreach (DataColumn col in table.Columns) {
if (col.Ordinal > 0) {
rowstr.Append(",");
}
object obj = row(table.Columns.IndexOf(col));
rowstr.Append(Encloser + ToStr(obj) + Encloser);
}
if (rowstr.Length > 0) {
str.AppendLine(rowstr.ToString());
}
}
return str.ToString();
UPDATE:
str.ToString() result
"Date","Code"
"2016-01-31","01"
"2016-01-31","02"

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);
}
}
}

Convert String to DataTable using ASP.NET MVC

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.

SqlDataReader change column names when exporting to csv

I have a query that gets report data via a SqlDataReader and sends the SqlDataReader to a method that exports the content out to a .CSV file; however, the column names are showing up in the .CSV file the way that they appear in the database which is not ideal.
I do not want to alter the query itself (changing the names to have spaces) because this query is called in another location where it maps to an object and spaces would not work. I would prefer not to create a duplicate query because maintenance could be problematic. I also do not want to modify the method that writes out the .CSV as this is a method that is globally used.
Can I modify the column names after I fill the data reader but before I send it to the .CSV method? If so, how?
If I can't do it this way, could I do it if it was a DataTable instead?
Here is the general flow:
public static SqlDataReader RunMasterCSV(Search search)
{
SqlDataReader reader = null;
using (Network network = new Network())
{
using (SqlCommand cmd = new SqlCommand("dbo.MasterReport"))
{
cmd.CommandType = CommandType.StoredProcedure;
//Parameters here...
network.FillSqlReader(cmd, ref reader);
<-- Ideally would like to find a solution here -->
return reader;
}
}
}
public FileInfo CSVFileWriter(SqlDataReader reader)
{
DeleteOldFolders();
FileInfo file = null;
if (reader != null)
{
using (reader)
{
var WriteDirectory = GetExcelOutputDirectory();
double folderToSaveInto = Math.Ceiling((double)DateTime.Now.Hour / Folder_Age_Limit.TotalHours);
string uploadFolder = GetExcelOutputDirectory() + "\\" + DateTime.Now.ToString("ddMMyyyy") + "_" + folderToSaveInto.ToString();
//Add directory for today if one does not exist
if (!Directory.Exists(uploadFolder))
Directory.CreateDirectory(uploadFolder);
//Generate random GUID fileName
file = new FileInfo(uploadFolder + "\\" + Guid.NewGuid().ToString() + ".csv");
if (file.Exists)
file.Delete();
using (file.Create()) { /*kill the file stream immediately*/};
StringBuilder sb = new StringBuilder();
if (reader.Read())
{
//write the column names
for (int i = 0; i < reader.FieldCount; i++)
{
AppendValue(sb, reader.GetName(i), (i == reader.FieldCount - 1));
}
//write the column names
for (int i = 0; i < reader.FieldCount; i++)
{
AppendValue(sb, reader[i] == DBNull.Value ? "" : reader[i].ToString(), (i == reader.FieldCount - 1));
}
int rowcounter = 1;
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
AppendValue(sb, reader[i] == DBNull.Value ? "" : reader[i].ToString(), (i == reader.FieldCount - 1));
}
rowcounter++;
if (rowcounter == MaxRowChunk)
{
using (var sw = file.AppendText())
{
sw.Write(sb.ToString());
sw.Close();
sw.Dispose();
}
sb = new StringBuilder();
rowcounter = 0;
}
}
if (sb.Length > 0)
{
//write the last bit
using (var sw = file.AppendText())
{
sw.Write(sb.ToString());
sw.Close();
sw.Dispose();
sb = new StringBuilder();
}
}
}
}
}
return file;
}
I would try a refactoring of your CSVFileWriter.
First you should add a delegate declaration
public delegate string onColumnRename(string);
Then create an overload of your CSVFileWriter where you pass the delegate together with the reader
public FileInfo CSVFileWriter(SqlDataReader reader, onColumnRename renamer)
{
// Move here all the code of the old CSVFileWriter
.....
}
Move the code of the previous CSVFileWriter to the new method and, from the old one call the new one
public FileInfo CSVFileWriter(SqlDataReader reader)
{
// Pass null for the delegate to the new version of CSVFileWriter....
return this.CSVFileWriter(reader, null)
}
This will keep existing clients of the old method happy. For them nothing has changed.....
Inside the new version of CSVFileWriter you change the code that prepare the column names
for (int i = 0; i < reader.FieldCount; i++)
{
string colName = (renamer != null ? renamer(reader.GetName(i))
: reader.GetName(i))
AppendValue(sb, colName, (i == reader.FieldCount - 1));
}
Now it is just a matter to create the renamer function that translates your column names
private string myColumnRenamer(string columnName)
{
if(columnName == "yourNameWithoutSpaces")
return "your Name with Spaces";
else
return text;
}
This could be optimized with a static dictionary to remove the list of ifs
At this point your could call the new CSVFileWriter passing your function
FileInfo fi = CSVFileWrite(reader, myColumnRenamer);

Categories