Adding Fields to DataTable in ASP.net MVC - asp.net

Users are uploading an Excel file to my site which I'm then going to write to the database. I'd like to add two additional columns (Email and TimeStamp). I'm not getting any specific error. Any suggestions on how to remedy? Code below:
public static class ExcelPackageExtensions
{
public static DataTable ToDataTable(this ExcelPackage package)
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.First();
DataTable dt = new DataTable();
dt.Columns.Add("Email");
dt.Columns.Add("TimeStamp");
foreach (var firstRowCell in worksheet.Cells[1,1,1,worksheet.Dimension.End.Column])
{
dt.Columns.Add(firstRowCell.Text);
}
for (var rownumber=2; rownumber <= worksheet.Dimension.End.Row; rownumber++)
{
var row = worksheet.Cells[rownumber, 1, rownumber, worksheet.Dimension.End.Column];
var newrow = dt.NewRow();
newrow["Email"] = System.Web.HttpContext.Current.User.Identity.GetUserId();
newrow["TimeStamp"] = DateTime.Now;
foreach (var cell in row)
{
newrow[cell.Start.Column - 1] = cell.Text;
}
dt.Rows.Add(newrow);
}
return dt;
}
}

Related

How to use Tempdata to display the list

I have did the excel upload in dotnet core .I had to use tempdata to retrieve the details of the excel in list.Instead in my below code i had used Static object to retrieve the list.My code works as like this ,when i click on upload button it will display the details in the excel sheet.and when click on save it will save it to database and i need to edit in grid view using ajax call also .Help me out
My Action in controller is
public async Task<IActionResult> ImportEmployeeDetails(IFormFile excelfile)
{
try
{
EmployeesViewModelList employeesListObject = new EmployeesViewModelList();
List<EmployeeModel> employeesViewModelList = new List<EmployeeModel>();
if (excelfile == null || excelfile.Length == 0)
{
return View(employeesListObject);
}
var supportedTypes = new[] { ".xls", ".xlsx" };
var ext = Path.GetExtension(excelfile.FileName);
if (!supportedTypes.Contains(ext))
{
return View(employeesListObject);
}
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot",
"EmployeeDetails.xlsx");
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
using (var stream = new FileStream(path, FileMode.Create))
{
await excelfile.CopyToAsync(stream);
}
FileInfo file = new FileInfo(path);
using (ExcelPackage package = new ExcelPackage(file))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
for (int i = 2; i <= rowCount; i++)
{
EmployeeModel emp = new EmployeeModel();
emp.EmployeeId = Convert.ToInt32(worksheet.Cells[i, 1].Value.ToString());
emp.EmpFirstName = worksheet.Cells[i, 2].Value.ToString();
employeesViewModelList.Add(emp);
}
employeesListObject.EmpModelList = employeesViewModelList;
return View(employeesListObject);
}
}
catch(Exception ex)
{
TempData["Message"] = "Opps! Something Went wrong!";
return RedirectToAction("ExcelPackage");
}
}
Try this, using your own list.
List<string> SomeList = new List<string>();
TempData["MyList"] = SomeList;
//then to get data just do
SomeList = TempData["MyList"] as List<string>; //This converts back to List<T>
Once you add the list to the TempData, you can retrive it from any Action or View in the same controller

Open XML generates only <NewDataSet /> tag from a full Excel file, but work for other files

I have an excel file full of data, and I'm trying to use Open XML SDK to convert this file into xml file.
I followed the documentation and other questions here on stackoverflow. However, the output of the xml file is always <NewDataSet />. Knowing that I tried other excel files and it worked fine.
Here is how my excel file looks like:
And here is my code "I tried two approaches":
The first approach is to use DataSet.GetXML(), it returned the same value as the next code does.
var xmlDS = new ConvertExcelToXml().GetXML(filePath);
string xmlPath = server.MapPath("~/UploadedFiles/XML/");
StreamWriter xmlFile = new StreamWriter(xmlPath + Path.GetFileNameWithoutExtension(fileName) + ".xml");
xmlDS.WriteXml(xmlFile);
//The used method to return the excel file dataset
public DataSet GetXML(string filename)
{
using (DataSet ds = new DataSet())
{
ds.Tables.Add(this.ReadExcelFile(filename));
return ds;
}
}
//This method used to return DataTable for previous method
private DataTable ReadExcelFile(string filename)
{
DataTable dt = new DataTable();
try
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filename, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
IEnumerable<Sheet> sheetcollection = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
string relationshipId = sheetcollection.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(relationshipId);
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
IEnumerable<Row> rowcollection = sheetData.Descendants<Row>();
if (rowcollection.Count() == 0)
{
return dt;
}
foreach (Cell cell in rowcollection.ElementAt(0))
{
dt.Columns.Add(GetValueOfCell(spreadsheetDocument, cell));
}
foreach (Row row in rowcollection)
{
DataRow temprow = dt.NewRow();
int columnIndex = 0;
foreach (Cell cell in row.Descendants<Cell>())
{
int cellColumnIndex = GetColumnIndex(GetColumnName(cell.CellReference));
if (columnIndex < cellColumnIndex)
{
do
{
temprow[columnIndex] = string.Empty;
columnIndex++;
}
while (columnIndex < cellColumnIndex);
}
temprow[columnIndex] = GetValueOfCell(spreadsheetDocument, cell);
columnIndex++;
}
dt.Rows.Add(temprow);
}
}
dt.Rows.RemoveAt(0);
return dt;
}
catch (IOException ex)
{
throw new IOException(ex.Message);
}
}

How to write data into Excel file and save it? EPPlus C#

I have the code to execute multiple stored procedures from SQl. However, I am having an issue on how to write the data from the stored procedures into the Excel file. After writing the data into the excel file, I would like to save the Excel workbook. How can I achieve this? Any help is very much appreciated.
This is what I have so far:
public static void ExecuteStoredProcedures()
{
using (SqlConnection connection = new SqlConnection("Data Source=the connection goes here.."))
{
SqlTransaction transaction;
connection.Open();
transaction = connection.BeginTransaction();
try
{
SqlCommand cmdOne = new SqlCommand("exec ", connection);
SqlCommand cmdTwo = new SqlCommand("exec", connection);
SqlCommand cmdThree = new SqlCommand("exec", connection);
cmdOne.ExecuteNonQuery();
cmdTwo.ExecuteNonQuery();
cmdThree.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
connection.Close();
}
}
}
public static void SaveExcelFile()
{
string SheetLocation = ConfigurationManager.AppSettings["SheetLocation"];
if (!System.IO.Directory.Exists(SheetLocation))
{
System.IO.Directory.CreateDirectory(SheetLocation);
}
ExecuteStoredProcedures(); //Should I call the method to load the data that comes from the stored procedures? Or what should I do to write the data into the file?
var newFile = new FileInfo(#"C:\Users\");
using (ExcelPackage xlPackage = new ExcelPackage(newFile))
{
xlPackage.Save();
}
}
Get data from stored procedures in the form of a Dataset or DataTables.
Create worksheet:
using (ExcelPackage xlPackage = new ExcelPackage(newFile))
{
ExcelWorksheet ws = xlPackage.Workbook.Worksheets.Add(AnyName);
}
Loop in Datatable rows and columns like a 2d array and create cells in the worksheet and add data in the created cells:
int rowIndex = 0
foreach (DataRow DataTableRow in dt.Rows)
{
int colIndex = 1;
rowIndex++;
foreach (DataColumn DataTableColumn in dt.Columns)
{
var cell = ws.Cells[rowIndex, colIndex];
cell.Value = DataTableRow[DataTableColumn.ColumnName];
colIndex++;
}
}

Import CSV file into Grid View in Asp.net

How to load the CSV file dynamically inside Grid View in C# Asp.net without hard coded values?
if (File.Exists(myFileUpload.PostedFile.FileName))
{
string[] data = File.ReadAllLines(myFileUpload.PostedFile.FileName);
DataTable dt = new DataTable();
string[] col = data[0].Split(',');
foreach (string s in col)
{
dt.Columns.Add(s, typeof(string));
}
for (int i = 0; i < data.Length; i++)
{
string[] row = data[i].Split(',');
dt.Rows.Add(row);
}
myGridView.DataSource = dt;
myGridView.DataBind();
}

Losing first record and the values keep changing when loading reader to datatable

I load reader to my table like this
connection.Open();
sqlCmd = new SqlCommand(sqlCmd.CommandText, connection);
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
DataTable dt = new DataTable();
sqlReader.Read();
dt.Load(sqlReader);
But it looks like I cannot retrieve the first record of fetch data.
The second problem is when I call the reader several times after that:
string comName = dt.Rows[0]["companyName"].ToString();
//To get address
sqlCmd.CommandText = addr;
sqlCmd.Parameters.AddWithValue("companyName", comName);
using (var addressReader = sqlCmd.ExecuteReader())
{
if (addressReader.Read())
{
Label1.Text = Label1.Text + " " + addressReader["address"].ToString();
}
}
//To get keyProcesses
sqlCmd.Parameters.Clear();
sqlCmd.CommandText = keyProcesses;
sqlCmd.Parameters.AddWithValue("companyName", comName);
using (var keyProcessesReader = sqlCmd.ExecuteReader())
{
if (keyProcessesReader.Read())
{
Label1.Text = Label1.Text + " " + keyProcessesReader.GetString(0);
}
}
But I find out that these reading also may changes the value of my datatable dt above! How could I only load data to dt at the first reading and keep it there without changing any more ?
Ps: In attempt to overcome the second problem, I am trying to store dt values in list
public class CompanyModel
{
public string compnName { get; set; }
public string compnAddress { get; set; }
public string compnKeyProcesses { get; set; }
public string compnStandards { get; set; }
}
then
List<CompanyModel> companies = new List<CompanyModel>();
for(int i = 0; i < dt.Rows.Count; i++)
{
companies.Add(new CompanyModel
{
compnName = dt.Rows[i]["companyName"].ToString(),
compnAddress = dt.Rows[i]["address"].ToString()
});
}
companyRepeater.DataSource = companies;
companyRepeater.DataBind();
Now, how do I access each company name in the list to make query on that name value accordingly, then input the new result to the list?
I tried:
foreach(List<Component> compnName in companies.Contains("companyName")
{
sqlCmd.CommandText = getKey;
sqlCmd.Parameters.AddWithValue("companyName", compnName);
using (var keyReader = sqlCmd.ExecuteReader())
{
if (keyReader.Read())
{
companies.Add(new CompanyModel compnKeyProcesses = keyReader.GetString("key"));
}
}
sqlCmd.CommandText = getstandard;
sqlCmd.Parameters.AddWithValue("companyName", compnName);
using (var standardReader = sqlCmd.ExecuteReader())
{
if (standardReader.Read())
{
companies.Add(new CompanyModel compnStandards = keyReader.GetString("standards"));
}
}
Try this for your first problem
SqlDataAdapter sdr = new SqlDataAdapter(sqlCmd.CommandText, connection);
DataTable dt=new DataTable();
sdr.Fill(dt);
you can display this whole data as a matter of confirmation by taking a datagridview
dataGridView1.DataSource=dt;

Resources