How to fill dropdownlist in MVC-4 using dapper - asp.net-mvc

I filled Drop Down List in MVC which is working fine but now I want to do it using Dapper but got stuck.
DropDownList in MVC without Dapper
Controller
[HttpPost]
public ActionResult Create(User ur)
{
string str = #"Data Source=DEV_3\SQLEXPRESS;Initial Catalog=DB_Naved_Test;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
string query = "Insert into tblTest (Name,Email,MobileNo) values('" + ur.Name + "','" + ur.Email + "','" + ur.MobileNo + "')";
con.Open();
SqlCommand cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery();
con.Close();
TempData["msg"] = "<script>alert('Inserted Successfully');</script>";
ModelState.Clear();
FillCountry();
}
public void FillCountry()
{
string str = #"Data Source=DEV_3\SQLEXPRESS;Initial Catalog=DB_Naved_Test;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
string query = "select * from tbl_country ";
SqlCommand cmd = new SqlCommand(query, con);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
List<SelectListItem> li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Select", Value = "0" });
while (rdr.Read())
{
li.Add(new SelectListItem { Text = rdr[1].ToString(), Value = rdr[0].ToString() });
}
ViewData["country"] = li;
}
View
#{ Html.BeginForm("Create", "User", FormMethod.Post, new { enctype = "multipart/form-data" }); }
#Html.DropDownList("country", ViewData["country"] as List<SelectListItem>, new {onchange = "this.form.submit();" })
#{ Html.EndForm(); }
This is what I am trying to do now
DropDownList in MVC with Dapper
Model
public class Region
{
private int _CountryId;
private string _CountryName;
public int CountryId
{
get { return _CountryId; }
set { _CountryId = value; }
}
public string CountryName
{
get { return _CountryName; }
set { _CountryName = value; }
}
Controller
[HttpPost]
public ActionResult AddMobiles(TBMobileDetails MD, HttpPostedFileBase file)
{
FileUpload(file);
MobileMain MM = new MobileMain();
MM.AddMobiles(MD);
FillCountry();
return RedirectToAction("AllMobileList");
}
Stuck in this part how to fill it using dapper? How to populate my list?
public void FillCountry()
{
List<Region> li = new List<Region>();
var para = new DynamicParameters();
para.Add("#Type", 1);
var result = con.Query<Region>("Sp_MVCDapperDDl", para, commandType: CommandType.StoredProcedure);
}
View
#{ Html.BeginForm("AddMobiles", "AddMobile", FormMethod.Post, new { enctype = "multipart/form-data" }); }
#Html.DropDownList("country", ViewData["country"] as List<SelectListItem>, new { onchange = "this.form.submit();" })
#{ Html.EndForm(); }

You are passing in ViewData["country"] object of type IEnumerable<Region> while in View you are casting it to IEnumerable<SelectListItem> which won't work obviously in action change FillCountry() to make SelectList:
public void FillCountry()
{
List<Region> li = new List<Region>();
var para = new DynamicParameters();
para.Add("#Type", 1);
var result = con.Query<Region>("Sp_MVCDapperDDl", para, commandType: CommandType.StoredProcedure);
var list = new SelectList(result,"CountryId","CountryName");
}
and in View now cast it to SelectList:
#Html.DropDownList("country", ViewData["country"] as SelectList, new {onchange = "this.form.submit();" })
This will get you going.

Related

How to Populate DropDownList from the Database in MVC

I am new to ASP NET MVC
I need Populate a drop down list from values obtained from a database table using MySql database and view model, after checking if the current user is application enabled, using ASP NET MVC.
This is the tutorial
My code below return
Error: returns void, a return keyword must not be followed by an object expression
On this line
return items;
Any help really appreciated.
Controller
public ActionResult Recovery()
{
try
{
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (var connection =
new MySqlConnection(cs))
{
string commandText = " SELECT cCountry FROM `dotable_user` " +
" WHERE cName = #Username; ";
using (var command =
new MySqlCommand(commandText, connection))
{
if (!String.IsNullOrEmpty(HttpContext.User.Identity.Name.ToString()))
{
command.Parameters.AddWithValue("#Username", HttpContext.User.Identity.Name.ToString());
}
connection.Open();
string cCountry = (string)command.ExecuteScalar();
if (String.IsNullOrEmpty(cCountry))
{
TempData["Message"] = "No user.";
ViewBag.Message = String.Format("No user.");
}
List<SelectListItem> items = new List<SelectListItem>();
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM `dotable_countries` " +
" WHERE cCountry = '" + cCountry.ToString() + "' ";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
connection.Close();
}
}
return items;
}
}
}
catch (Exception ex)
{
TempData["Message"] = "Login failed.Error - " + ex.Message;
}
}
Update
I have tried with this code.
I have error
Error CS0103 The name 'cCountry' does not exist in the current context
public ActionResult Recovery()
{
try
{
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (var connection =
new MySqlConnection(cs))
{
string commandText = " SELECT cCountry FROM `dotable_user` " +
" WHERE cName = #Username; ";
using (var command =
new MySqlCommand(commandText, connection))
{
if (!String.IsNullOrEmpty(HttpContext.User.Identity.Name.ToString()))
{
command.Parameters.AddWithValue("#Username", HttpContext.User.Identity.Name.ToString());
}
connection.Open();
string cCountry = (string)command.ExecuteScalar();
if (String.IsNullOrEmpty(cCountry))
{
TempData["Message"] = "No user.";
ViewBag.Message = String.Format("No user.");
}
TempData["Dates"] = PopulateDates();
}
}
}
catch (Exception ex)
{
TempData["Message"] = "Login failed.Error - " + ex.Message;
}
}
private static List<SelectListItem> PopulateDates()
{
List<SelectListItem> items = new List<SelectListItem>();
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM `dotable_countries` " +
" WHERE cCountry = '" + cCountry.ToString() + "'; ";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
cmd.Connection.Close();
}
}
return items;
}
You are not passing cCountry value to populateDates.That's why you are getting this error. You can do something like below to get drop down populated. However it is not good idea to write Business Logic directly in controller. You should move it to model or Business layer.
private static List<SelectListItem> PopulateDates(string country)
{
List<SelectListItem> items = new List<SelectListItem>();
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM dotable_countries WHERE cCountry = #country";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Parameters.AddWithValue("#country",country);
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
cmd.Connection.Close();
}
}
return items;
}
and while calling this method in Action pass country value to it like below
TempData["Dates"] = PopulateDates(cCountry);

Populated on MVC form View the TextBox

I need populate on MVC form View the TextBox below
#Html.LabelFor(m => m.tDate)
#Html.TextBoxFor(m => m.tDate, "{0:dd/MM/yyyy}", new { #class = "Mytextarea2" })
#Html.ValidationMessageFor(m => m.tDate, "", new { #class = "text-danger" })
Whit value extract from controller (using MySql database) when I have planned this code
public DateTime JsonDateTimeToNormal(string jsonDateTime)
{
jsonDateTime= #"""" + jsonDateTime + #"""";
return Newtonsoft.Json.JsonConvert.DeserializeObject<DateTime>(jsonDateTime);
}
...
model.tDate = JsonDateTimeToNormal(GetDateHourById(value).ToString());
...
private static string GetDateHourById(string value)
{
string sql;
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = #String.Format(" SELECT ");
sql += String.Format(" tDate ");
sql += String.Format(" FROM `dotable` ");
sql += String.Format(" WHERE tID = #Id;");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Id", value);
con.Open();
string name = Convert.ToString(cmd.ExecuteScalar());
con.Close();
return name;
}
}
}
The value memorized on MySql database is
2020-03-19
But the TextBox is populed with this value
/Date(1605481200000)/
On the model
[Column(TypeName = "date")]
[Display(Name = "Your date")]
[Required]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime? tDate { get; set; }
Help me to do it.
Debug VS 2109
Solution
const d = new Date(response.tDate.match(/\d+/)[0] * 1);
const formattedDate = d.getFullYear()+'-'+("0"+(d.getMonth()+1)).slice(-2)+'-'+("0"+d.getDate()).slice(-2)
$('#tDate').val( formattedDate );
why don't you try to make this call with a jquery?
view:
#Html.TextBoxFor(m => m.tDate, "{0:dd/MM/yyyy}", new { #class = "Mytextarea2" })
$("#document").on("click", ".YouFormCall", function () {
var date = new Object();
date.tDate = $(this).closest('tr').find(".Mytextarea2").val();
controller:
yourModel date= new yourModel ()
{
tDate= date.tDate,
};
db.Entry(date).State = EntityState.Modified;
db.SaveChanges();
}

DevExpress GridView ExportToPdf doesn't export filtered data MVC

I have a webpage with gridview from Devexpress and i've implemented export to pdf. But somehow I don't get the current filter, order or group setting. I'm wondering if there is something wrong with how i set my setting in code or something since I've googled a lot at seems like those options should be handled automatically in ExportToPdf as long as you have rigth setting. My _GripPartial.cshtml:
#Html.DevExpress().GridView(TreeMenuTest.Controllers.LogViewController.GridViewSettings).Bind(TreeMenuTest.Controllers.LogViewController.DataSource).GetHtml()
_LogView.cshtml:
#using (Html.BeginForm("ExportToPDF", "LogView", FormMethod.Post))
{
<div id="buttonExport" class ="gridBtn">
<input type="submit" id ="ExportBtn" value="Export to pdf" />
</div>}
<div id="buttonReset" class ="gridBtn">
<input type="button" id ="ResetBtn" value="Reset Grid" onclick="javascript: ResetGrid()"/>
</div>
#Html.Action("Grid","LogView")
And finally LogViewController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using TreeMenuTest.Models;
using DevExpress.Web.Mvc;
using DevExpress.Web.ASPxGridView;
using System.Globalization;
using System.Web.UI.WebControls;
using DevExpress.Web.ASPxClasses;
using DevExpress.XtraPrinting;
using DevExpress.XtraPrintingLinks;
using System.IO;
using System.Drawing.Printing;
namespace TreeMenuTest.Controllers
{
public class LogViewController : Controller
{
//
// GET: /LogView/
public static List<LoggingEvent> DataSource;
static GridViewSettings exportGridViewSettings;
public static GridViewSettings GridViewSettings
{
get
{
if (exportGridViewSettings == null)
exportGridViewSettings = GetGridViewSettings();
return exportGridViewSettings;
}
}
static GridViewSettings GetGridViewSettings()
{
GridViewSettings settings = new GridViewSettings();
settings.Name = "GridView";
settings.CallbackRouteValues = new { Controller = "LogView", Action = "Grid" };
settings.Width = Unit.Percentage(100);
settings.Theme = "BlackGlass";
settings.KeyFieldName = "Id";
settings.SettingsPager.Visible = true;
settings.Settings.ShowGroupPanel = true;
settings.Settings.ShowFilterRow = true;
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsPager.PageSize = 25;
settings.SettingsBehavior.ColumnResizeMode = ColumnResizeMode.Control;
settings.Settings.ShowHeaderFilterButton = true;
settings.SettingsPopup.HeaderFilter.Height = 200;
settings.SettingsExport.Landscape = true;
settings.SettingsExport.TopMargin = 0;
settings.SettingsExport.LeftMargin = 0;
settings.SettingsExport.RightMargin = 0;
settings.SettingsExport.BottomMargin = 0;
settings.SettingsExport.PaperKind = PaperKind.A4;
settings.SettingsExport.RenderBrick = (sender, e) =>
{
if (e.RowType == GridViewRowType.Data && e.VisibleIndex % 2 == 0)
e.BrickStyle.BackColor = System.Drawing.Color.FromArgb(0xEE, 0xEE, 0xEE);
};
settings.Columns.Add("Id");
settings.Columns.Add(column =>
{
column.FieldName = "Ts";
column.Settings.AutoFilterCondition = AutoFilterCondition.Like;
});
settings.Columns.Add("LogLevelText").Caption = "Level";
settings.Columns.Add("LoggerName");
settings.Columns.Add("Message");
settings.Columns.Add("ThreadName").Caption = "Thread";
settings.Columns.Add("UserName");
settings.Columns.Add("Domain");
settings.Columns.Add("ClassName");
settings.Columns.Add("FileName");
settings.Columns.Add("MethodName").Caption = "Method";
settings.Columns.Add("LineNumber").Caption = "Line";
settings.Columns.Add("LocalIP");
settings.Columns.Add("MachineName").Caption = "Machine";
settings.Columns.Add("UnikeName");
settings.Settings.ShowPreview = true;
settings.PreviewFieldName = "ExceptionString";
return settings;
}
public ActionResult Index()
{
return PartialView("_LogView");
}
public ActionResult Grid()
{
if (DataSource == null)
{
DataSource = GetAllEventsLast24h();
}
return PartialView("_GridPartial");
}
public ActionResult EmptyGrid()
{
DataSource = null;
return PartialView("_GridPartial");
}
public List<LoggingEvent> GetAllEventsLast24h() {
return GetEventsWithCommand("where Ts > '" + DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd HH:mm:ss") + "';");
}
public List<LoggingEvent> GetEventsOnDateTime(DateTime fromDate, DateTime toDate)
{
return GetEventsWithCommand("where Ts > '" + fromDate.ToString("yyyy-MM-dd HH:mm:ss") + "' AND Ts < '" + toDate.ToString("yyyy-MM-dd HH:mm:ss") + "';");
}
public List<LoggingEvent> GetEventsWithCommand(string where)
{
List<LoggingEvent> events = new List<LoggingEvent>();
SqlConnection myConnection = new SqlConnection("Data Source=xxx;user id=xxx;password=xxx;connection timeout=30");
myConnection.Open();
SqlDataReader myReader = null;
SqlCommand command = new SqlCommand("SELECT Id,Ts,LogLevel,LoggerName,Message,ThreadName,UserName,ExceptionString,Domain,ClassName,FileName,MethodName,LineNumber,LocalIP,MachinName,UnikeName from dbo.LoggingEvent " + where);
command.Connection = myConnection;
myReader = command.ExecuteReader();
while (myReader.Read())
{
events.Add(LoggingEvent.ReadEntityFromDbReader(myReader));
}
myConnection.Close();
return events;
}
[HttpPost]
public ActionResult ReloadGrid(string fromDate, string toDate)
{
DateTime fromDateTime;
DateTime toDateTime;
if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate)) // todo
{
fromDateTime = ParseStringToDate(fromDate);
toDateTime = ParseStringToDate(toDate);
}
else// No dates specified = get last 24 hours
{
toDateTime = DateTime.Now;
fromDateTime = toDateTime.AddHours(-24);
}
if (fromDateTime.CompareTo(toDateTime) > 0)
{
// from date grater then todate, change places
DateTime temp = toDateTime;
toDateTime = fromDateTime;
fromDateTime = temp;
}
DataSource = GetEventsOnDateTime(fromDateTime, toDateTime);
return PartialView("_LogView");
}
public DateTime ParseStringToDate(string datetxt)// todo this is copy froim treemenuviewcontroller, create utilsclass
{
const string dateformat = "dd.MM.yyyy HH:mm"; // jquery datepicker
const string dateformat2 = "yyyy-MM-dd HH:mm";// chrome TODO different formats with different location setting?
DateTime dateTime;
try //todo error handling!
{
dateTime = DateTime.ParseExact(datetxt, dateformat, CultureInfo.InvariantCulture);
}
catch
{
dateTime = DateTime.ParseExact(datetxt, dateformat2, CultureInfo.InvariantCulture);
}
return dateTime;
}
public ActionResult ExportToPDF()
{
var printable = GridViewExtension.CreatePrintableObject(GridViewSettings, DataSource);
PrintingSystem ps = new PrintingSystem();
PrintableComponentLink link1 = new PrintableComponentLink(ps);
link1.Component = printable;
link1.PrintingSystem.Document.AutoFitToPagesWidth = 1;
link1.Landscape = true;
CompositeLink compositeLink = new CompositeLink(ps);
compositeLink.Links.Add(link1);
compositeLink.CreateDocument();
using (MemoryStream stream = new MemoryStream())
{
compositeLink.PrintingSystem.ExportToPdf(stream);
WriteToResponse("filename", true, "pdf", stream);
}
ps.Dispose();
return Index();
}
void WriteToResponse(string fileName, bool saveAsFile, string fileFormat, MemoryStream stream)
{
string disposition = saveAsFile ? "attachment" : "inline";
Response.Clear();
Response.Buffer = false;
Response.AppendHeader("Content-Type", string.Format("application/{0}", fileFormat));
Response.AppendHeader("Content-Transfer-Encoding", "binary");
Response.AppendHeader("Content-Disposition",
string.Format("{0}; filename={1}.{2}", disposition, fileName, fileFormat));
Response.BinaryWrite(stream.GetBuffer());
Response.End();
}
}
}
Any clues?
Ps. Asking me why I don't write to DevExpress support is not helpful, so please just don't comment at all.
Check the How to export GridView rows and keep end-user modifications (such as sorting, grouping, filtering, selection) KB Article and make sure if all the steps are implemented.
After help for #Mikhail i fix the issue by putting #Html.Action("Grid","LogView") in the Html.BeginForm in _Log.View.cshtml like that:
<div id="buttonReset" class ="gridBtn">
<input type="button" id ="ResetBtn" value="Reset Grid" onclick="javascript: ResetGrid()"/>
</div>
#using (Html.BeginForm("ExportToPDF", "LogView", FormMethod.Post))
{
<div id="buttonExport" class ="gridBtn">
<input type="submit" id ="ExportBtn" value="Export to pdf" />
</div>
#Html.Action("Grid","LogView")}

returning data from model to view

now how to get data back in View from model ?
my code:
View:
#using (Html.BeginForm("register","Home", FormMethod.Post, new {id="submitForm"}))
{
<div>
<i>#Html.Label("Name:")</i>
#Html.TextBox("txtboxName")
</div>
<div>
<i>#Html.Label("Email:")</i>
#Html.TextBox("txtboxEmail")
</div>
<div>
<i>#Html.Label("Password:")</i>
#Html.Password("txtboxPassword")
</div>
<div>
<button type="submit" id="btnSubmit" name="Command" value="Submit">Submit</button>
</div>
}
controller:
[HttpPost]
public ActionResult register(string command, FormCollection formData )
{
if (command == "Submit")
{
var name = formData["txtboxName"];
var email = formData["txtboxEmail"];
var pwd = formData["txtboxPassword"];
database db = new database();
db.connectDB(name, email, pwd);
ViewBag.Message = email;
}
return View();
}
}
}
Model:
namespace LoginSys.Models
{
public class database
{
public void connectDB(String name, String email, String pwd)
{
String conStr = "Data Source=HUNAIN-PC;Initial Catalog=registration;User ID=sa;Password=abc123!##";
sqlconnection sqlCon = new sqlconnection(conStr);
string comm = "insert into tblRegister values('"+name+"','"+email+"','"+pwd+"')";
sqlcommand sqlCom = new sqlcom(comm, con);
try
{
sqlCon.Open();
sqlCon.executeNonQuery();
}
catch(exception exc)
{
//code
}
finally
{
con.close();
}
}
}
}
now how to return NO OF ROWS EFFECTED BY EXECUTENONQUERY statement or suppose any thing to return ? simple words and please help me in this approach, will use advance techniques later.
If you want to return something, you can use SqlParameter ParameterDirection.Output like this:
SqlCommand cc = new SqlCommand(connStr); // connection string
cc.CommandText = "insert into tblRegister (Name, Email, Pwd) values (#name, #email, #pwd); select #result = ##identity";
cc.AddWithValue("#name", name);
cc.AddWithValue("#email", email);
cc.AddWithValue("#pwd", pwd);
cc.Parameters.Add("#result", SqlDbType.Int);
cc.Parameters["#result"].Direction = ParameterDirection.Output;
cc.ExecuteNonQuery();
// returs identity key
int id = (int)cc.Parameters["#result"].Value;
Then you can return this id from your function, but you have to modify it's prototype:
public int connectDB(String name, String email, String pwd) // changed void to int
{
// ...
return id;
}
Then you can simply put this value to ViewBag, or use other ways to pass it to your view:
database db = new database();
ViewBag.Id = db.connectDB(name, email, pwd);
ViewBag.Message = email;
If you use ViewBag, you can access it in your view with #ViewBag.Id

Export data to Excel file with ASP.NET MVC 4 C# is rendering into view

I am having trouble exporting data to Excel. The following seems to render the gridview into my View, instead of prompting the user to open with Excel, which I have installed on my machine.
Public ActionResult ExportToExcel()
{
var products = this.Repository.Products.ToList();
var grid = new GridView();
grid.DataSource = from p in products
select new
{
Id = p.Id,
Name = p.Name
};
grid.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
grid.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return View("MyView");
}
What am I doing wrong?
I have tried your code and it works just fine.
The file is being created without any problem, this is the code I used (it's your code, I just changed the datasource for testing):
public ActionResult ExportToExcel()
{
var products = new System.Data.DataTable("teste");
products.Columns.Add("col1", typeof(int));
products.Columns.Add("col2", typeof(string));
products.Rows.Add(1, "product 1");
products.Rows.Add(2, "product 2");
products.Rows.Add(3, "product 3");
products.Rows.Add(4, "product 4");
products.Rows.Add(5, "product 5");
products.Rows.Add(6, "product 6");
products.Rows.Add(7, "product 7");
var grid = new GridView();
grid.DataSource = products;
grid.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
grid.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return View("MyView");
}
You can call helper class in any controller
//view
#Html.ActionLink("Export to Excel", "Excel")
//controller Action
public void Excel()
{
var model = db.GetModel()
Export export = new Export();
export.ToExcel(Response, model);
}
//helper class
public class Export
{ public void ToExcel(HttpResponseBase Response, object clientsList)
{
var grid = new System.Web.UI.WebControls.GridView();
grid.DataSource = clientsList;
grid.DataBind();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=FileName.xls");
Response.ContentType = "application/excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
grid.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
}
Step 1: View page code
<input type="button" id="btnExport" value="Export" class="btn btn-primary" />
<script>
$(document).ready(function () {
$('#btnExport').click(function () {
window.location = '/Inventory/ExportInventory';
});
});
</script>
Step 2: Controller Code
public ActionResult ExportInventory()
{
//Load Data
var dataInventory = _inventoryService.InventoryListByPharmacyId(pId);
string xml=String.Empty;
XmlDocument xmlDoc = new XmlDocument();
XmlSerializer xmlSerializer = new XmlSerializer(dataInventory.GetType());
using (MemoryStream xmlStream = new MemoryStream())
{
xmlSerializer.Serialize(xmlStream, dataInventory);
xmlStream.Position = 0;
xmlDoc.Load(xmlStream);
xml = xmlDoc.InnerXml;
}
var fName = string.Format("Inventory-{0}", DateTime.Now.ToString("s"));
byte[] fileContents = Encoding.UTF8.GetBytes(xml);
return File(fileContents, "application/vnd.ms-excel", fName);
}
using (MemoryStream mem = new MemoryStream())
{
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// Add a row to the cell table.
Row row;
row = new Row() { RowIndex = 1 };
sheetData.Append(row);
// In the new row, find the column location to insert a cell in A1.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, "A1", true) > 0)
{
refCell = cell;
break;
}
}
// Add the cell to the cell table at A1.
Cell newCell = new Cell() { CellReference = "A1" };
row.InsertBefore(newCell, refCell);
// Set the cell value to be a numeric value of 100.
newCell.CellValue = new CellValue("100");
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheet"
};
sheets.Append(sheet);
workbookpart.Workbook.Save();
spreadsheetDocument.Close();
return File(mem.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "text.xlsx");
}
I have done this before, I think you need to remove the ActionResult. Make it a void and remove the return View(MyView). this is the solution
I used a list in my controller class to set data into grid view. The code works fine for me:
public ActionResult ExpExcl()
{
List<PersonModel> person= new List<PersonModel>
{
new PersonModel() {FirstName= "Jenny", LastName="Mathew", Age= 23},
new PersonModel() {FirstName= "Paul", LastName="Meehan", Age=25}
};
var grid= new GridView();
grid.DataSource= person;
grid.DataBind();
Response.ClearContent();
Response.AddHeader("content-disposition","attachement; filename=data.xls");
Response.ContentType="application/excel";
StringWriter sw= new StringWriter();
HtmlTextWriter htw= new HtmlTextWriter(sw);
grid.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return View();
}
The modest way to export excel in MVC is using Microsoft CloseXml. I wrote a simple function for exporting my query result as excel sheet:
using ClosedXML.Excel;
...
public ActionResult ToExcel(List<Dictionary<string, string>> data, Dictionary<string, string> columnMap, string fileName, string sheetName)
{
var dtDataBuffer = new System.Data.DataTable("buffer");
foreach (string col in columnMap.Values)
{
dtDataBuffer.Columns.Add(col, typeof(string));
}
foreach (var row in data)
{
List<string> rowData = new List<string> { };
foreach (string col in columnMap.Keys)
{
rowData.Add(row[col]);
}
dtDataBuffer.Rows.Add(rowData.ToArray());
}
var memoryStream = new MemoryStream();
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add(dtDataBuffer, sheetName);
worksheet.Rows().Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
worksheet.Rows().Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
worksheet.Columns().AdjustToContents();
workbook.SaveAs(memoryStream);
}
return File(memoryStream.ToArray(), "application/vnd.ms-excel", fileName);
}
And this is a usage example (in practice I use my own class to run query and generate data. You can find it here for Oracle and SQL Server):
public ActionResult myReportExport(){
var data=List<Dictionary<string, string>>(){
{{"Column1_Index","Column1_Value"},{"Column2_Index","Column2_Value"},...}
...
};
return ToExcel(data, new Dictionary<string, string> {
{ "Column1_Index", "Column1 Title" } ,
{ "Column2_Index", "Column2 Title" } ,
...
},
"myFileName.xlsx",
"my sheet name"
);
}

Resources