经过几天的样本,演示,教程,演练等,...... 我根据我学到的东西创建了下面的代码。 当使用实体进行硬编码时,它的工作原理非常完美(如广告商数据库表中最常评论的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();
答案 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