jqgrid + EF + MVC:是否有可能导出在Excel中,总是使用相同的控制器操作?

我正在使用jqgrid(标准)与EF 4 + MVC3 。 我想实现Excel导出,如果可能的话使用相同的动作控制器来填充网格。 例如,我想知道是否可以/合乎逻辑地传递一个附加参数。 你会build议我哪种方法? 我问这个问题,因为我仍然接近实现Excel导出,我想优化/重用代码,如果可能的话。

为了生成excel, 我想使用Stephen Walther博士提供的这个库 ,它有三种types的输出并允许定义头文件。 请告诉我,如果你觉得它对我的目的有效。

关于jqgrid代码,我发现奥列格这个有趣的答案 ,但我不明白是否可以应用于我的需求。

不幸的是,到目前为止,我只findEF MVC的excel导出解决scheme的一部分,但没有解决scheme或完整的例子…

这里是包含我的jqgrid的_Index部分视图

<table id="mygrid"></table> <div id="pager2"></div> jQuery("#mygrid").jqGrid({ url:'controller/jqIndex', datatype: "json", colNames:['id','field1', ...], colModel:[ {name:'id',index:'id', width:55}, {name:'field1',index:'field1', width:90}, ... ], rowNum:10, rowList:[10,20,30], pager: '#pager2', sortname: 'id', viewrecords: true, sortorder: "desc", caption:"modal jquery + jqgrid test"}); jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false}); //TODO ??? ...some code to call the controller action with the `excel` parameter set `true` 

控制器(基于OLEG的实施 )

  public ActionResult jqIndex(string sidx, string sord, int page, int rows, bool _search, string filters, bool excel) // note the excel parameter << { var context = new TManagerContext(); var objectContext = context.ObjectContext(); var set = objectContext.CreateObjectSet<Ticket>(); var serializer = new JavaScriptSerializer(); Filters f = (!_search || string.IsNullOrEmpty(filters)) ? null : serializer.Deserialize<Filters>(filters); ObjectQuery<Ticket> filteredQuery = (f == null ? (set) : f.FilterObjectSet(set)); filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data int totalRecords = filteredQuery.Count(); var pagedQuery = filteredQuery.Skip("it." + sidx + " " + sord, "@skip", new ObjectParameter("skip", (page - 1) * rows)) .Top("@limit", new ObjectParameter("limit", rows)); int pageIndex = Convert.ToInt32(page) - 1; int pageSize = rows; int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize); var queryDetails = (from e in pagedQuery select new { e.TicketID, e.field1, ... }).ToList(); var result = new { total = totalPages, page = page, records = totalRecords, rows = (from e in queryDetails select new { id = e.TicketID, cell = new string[] { e.field1, ... } }).ToArray() }; if (excel) { ExportExcel(result); // if possible, pass filter parameters too, column order, etc... } return Json(result, JsonRequestBehavior.AllowGet); } 

如果这个问题可能很愚蠢,那么请抱歉,我只是一个(爱好者)初学者。

感谢您宝贵的帮助! 最好的祝福

拉里 – 一些评论。

  1. 你不应该在你的控制器中做这么多的逻辑。 将所有业务逻辑移到另一个类/服务。 那么你的行动方法将只是几行。 一个简单的例子

 public JsonResult jqIndex(string sidx, string sord, int page, int rows, bool _search, string filters){ return JSON(this.GridQueryService.GetJQGrid(sidx,sord,page,rows,_search,filters), JsosnRequestBehavior.AllowGet); } 

2.我知道你不想重复代码(这点有帮助),但是这里有很多参数和事情,根本不适用于Excel(页面,行)。

3.通过布尔参数来改变事物的function可以快速地变得混乱。 让我们假设你现在需要将更多/更less的数据传递给Excel文件,现在你已经遍布了各种各样的嵌套条件,unit testing只会是蹩脚的。

4.一个excel动作方法应该有一个FileResult返回types,而不是JSON结果(我猜他们都是动作结果,但是这会让你的意图在你的代码中变得更加清晰,你的定义应该是类似于


 public FileResult GetExcelFile(string sidx, string sord, bool _search, string filters){ //do stuff to return Excel } 

如果你在第一点创build你的服务,你有两个方法返回不同的项目,但共享一个通用的查询/search基础function,那么你真的保持干燥,同时遵循单一责任原则。 这个服务的例子可能是(非常粗略的例子,应该给你一些想法):

 public class GridQueryService{ public YourViewModel GetJQGrid(sidx, page, row, _search, filters){ //Get the base data var myData = this.GetGridData(sidx, _search, filters); //Create your view model and return it back to controller } public StreamWriter GetExcelFIle(sidx, _search, filters){ //Get the base data var myData = this.GetGridData(sidx, _search, filters); //Create your Excel file and return it to the controller } private ObjectQuery<Ticket> GetGridData(string sidx, bool _search, string filters){ //do your data grabbing here - you never return the raw data back to anything outside //of this service, so it should be ok to make private } }