【问题标题】:jqgrid + EF + MVC: Is it possible to export in excel, using always the same controller action?jqgrid + EF + MVC:是否可以在 excel 中导出,始终使用相同的控制器操作?
【发布时间】:2012-03-09 04:16:19
【问题描述】:

我正在使用 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`

控制器(基于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);
    }

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

感谢您的宝贵帮助! 最好的问候

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 excel jqgrid export


    【解决方案1】:

    拉里 - 几个厘米。

    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.我知道您不想重复代码(第 1 点有帮助),但这里有许多参数和内容根本不适用于 Excel(页面、行)。

    3. 传递布尔参数来改变事情的运作方式可能会很快变得混乱。假设您现在需要向 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
    }
    
    }
    

    【讨论】:

    • 汤米,非常感谢您的回答!我发现它真的专注于主要问题。你给我建议了正确的方法,你给我的解决方案看起来非常明智、理性和优雅。我将根据您的宝贵建议更改代码。至于如何导出到excel,我要开一个更具体的问题,这个实际的文本有点超出了最初的对象。再次感谢!最好的问候,L
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    相关资源
    最近更新 更多