EPPlus LoadFromCollection无法使用传递的上下文参数

时间:2016-11-19 16:12:53

标签: c# asp.net-mvc-4 epplus

经过几天的样本,演示,教程,演练等,...... 我根据我学到的东西创建了下面的代码。 当使用实体进行硬编码时,它的工作原理非常完美(如广告商数据库表中最常评论的2行所示)。 它创建excel文件,然后通过浏览器将其提供给用户。

但是,我想让它成为在我的数据库中创建和下载其他实体的通用实用程序。 我从原始方法重构了这个: 通过替换所有“广告客户”来解决问题。使用传入的参数' listTitle'进行引用。 然后,我用传入的参数' context'替换了var adv。在var ctx。

[更新]

我计划用我从代码的其他区域创建的集合列表调用此方法(类似于我使用var adv的方式,注释(即context = db.Publisher.OrderBy(p => p。名称).ToList())) 并将其作为方法调用中的context参数传递。

(例如,ExportExcelList(" Publishers",context))。

现在,我使用LoadFromCollection获得红色波浪线,并且它不能正确构建我的代码。

所以我的问题是: 我怎样才能让它发挥作用? 有没有办法让这个工作没有包含匿名对象类型和GUID的代码块(如其他帖子中所述)? 我只是错过了使用声明吗? 或者上下文参数的类型是否应该不同?

目前,对于EPPlus使用声明,我使用:使用OfficeOpenXml; 我已经通过Nuget安装了EPPlus。

这是我的代码:

    [HttpPost]
    public ActionResult ExportExcelList(string listTitle, ApplicationDbContext context)
    {
        ////create the list of advertisers [ HARD CODED HERE ]
        //var adv = db.Advertisers.OrderBy(a => a.Name).ToList();

        var ctx = context;

        //create the path and filename to use for the excel file and check for file exists/delete here.
        //here xfile is the name of the excel file without the directory path.
        ....

        file = new FileInfo(filename);  //this is the file object used for creating the new excel file.

        //create the excel file
        using (ExcelPackage ep = new ExcelPackage(file))
        {
            ep.Workbook.Worksheets.Add(listTitle);
            var worksheet = ep.Workbook.Worksheets[1];

            worksheet.Cells[1, 1].LoadFromCollection(ctx, true);    //this line barks at the ctx usage, it wants explicit type declaration.

            ep.Save();

        }

        //download the excel file to the user
        using (ExcelPackage ep = new ExcelPackage(file))
        {
            //Write it back to the client
            Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            Response.AddHeader("content-disposition", "attachment;  filename=" + xfile);
            Response.BinaryWrite(ep.GetAsByteArray());
        }

        //end this process
        return null;
    }

我还没有找到一个可以让我做我想做的解决方案。

非常感谢@CodingYoshi的见解。

以下是我的临时解决方案。目前我正在使用切换案例场景。 对它不太满意,但它现在仍然有用,尽管有其局限性。

希望SO的某个人能够找到更好的解决方案。我希望。

[更新代码]

            //since I can't pass the context in by parameter when calling this method, I've decided to use a switch case scenario and just pass in the listTitle
            switch(listTitle)
            {
                case "Advertisers":
                    worksheet.Cells[1, 1].LoadFromCollection(
                        db.Advertisers.OrderBy(a => a.Name).ToList(),
                        true);
                    break;
                case "Publishers":
                    worksheet.Cells[1, 1].LoadFromCollection(
                        db.Publishers.OrderBy(a => a.Name).ToList(),
                        true);
                    break;
            }
            ep.Save();

2 个答案:

答案 0 :(得分:0)

该行中断,因为它期望IEnumerable但您传递的是ApplicationDbContext。如果你想做你想做的事情,你需要以某种方式找出一种方法来枚举ApplicationDbContext中的所有dbset,并将它们逐个传递给LoadFromCollection方法。

我知道DbContext有一个允许你这样做的属性:<p>,不确定ApplicationDbContext是否有类似的东西。这将把你的所有表格都放到Excel中。

您需要担心的下一件事是过滤器和排序代码。例如,您可能希望按特定字段排序(按照广告客户的名称排序),或者您希望过滤它们。通常,这将使用谓词传递,但由于您正在从浏览器访问操作方法,因此这不是一个选项。因此,您可以创建多个有意义的操作,例如ExportAdvertisersSortedByName,ExportTopAdvertisers,ExportSomeOtherEntity等。对于这些操作,您将像上面那样对实体进行硬编码,然后epplus导出的公共代码可以使用另一种方法。

通过这种方式,您可以导出整个数据库或特定项目以满足特定需求。

答案 1 :(得分:0)

您需要使用反射动态传递集合名称。

所以喜欢这个

https://graph.microsoft.com/v1.0/users/{other user's id}/drive/root/children

并查看更多详情here

if Rails.env.production?
  # your omniauth stuff
end