我正在使用 jqgrid(标准)和EF 4 + MVC3 。我想实现excel导出,如果可能的话,使用相同的动作控制器来填充网格。 我想知道是否有可能/合理地传递一个额外的参数,例如。你建议我使用哪种方法? 我问这个问题是因为我还在接近实施excel导出,如果可能的话,我想优化/重用代码。
要生成excel,我希望使用Stephen Walther博士的this library,它有三种类型的输出,并允许定义标题。如果您发现它对我的目的有效,请告诉我。
关于jqgrid代码,我找到了Oleg的this interesting answer,但我不明白是否可以应用于我的需求。
不幸的是,到目前为止我只发现了使用EF MVC进行excel导出的部分解决方案,但没有解决方案或完整的示例......
这是包含我的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`
CONTROLLER(基于OLEG'S IMPLEMENTATION)
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);
}
如果问题可能很愚蠢,请抱歉。我只是一个(爱好者)初学者。
感谢您的宝贵帮助! 最诚挚的问候
答案 0 :(得分:2)
拉里 - 一些评论。
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.我知道你不想重复代码(第1点有帮助),但这里有很多参数和东西,不适用于Excel(页面,行)。
3.Passing布尔参数来改变函数如何快速变得混乱。让我们假设你现在需要将更多/更少的数据传递给Excel文件,现在你已经遍布整个地方嵌套条件,单元测试就会变得很糟糕。
4.一个excel动作方法应该有一个FileResult返回类型,而不是一个 JSON结果(我猜他们都是行动结果,但是这会使你的意图在你的代码中更清晰。你的定义应该像
public FileResult GetExcelFile(string sidx, string sord, bool _search,
string filters){
//do stuff to return Excel
}
如果您在第一点创建服务,使得您有两种方法返回不同的项目,但共享一个共同的查询/搜索基础功能,那么您在遵循单一责任原则时确实处于干燥状态。这个服务的一个例子可能是(非常粗略的例子,应该给你一些思考的东西):
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
}
}