问题描述
我正在尝试使用 EPPlus Export()功能添加到我的MVC5代码优先应用程序中>图书馆.在我的视图上,我有一个MultiSelectList,其中包含我的主要Model属性的所有值:
I'm attempting to add an Export()
functionality to my MVC5 Code-First application using the EPPlus library. On my View I have a MultiSelectList with all the values for my main Model properties:
@Html.ListBox("PropertyList", typeof(InventoryTracker.Models.INV_Assets).GetProperties().Select(p => new SelectListItem { Text = p.Name, Value = p.Name, Selected = false }), new { @Id = "exportListBox" })
这将呈现以下HTML:
This renders the following HTML:
<select Id="exportListBox" id="PropertyList" multiple="multiple" name="PropertyList"><option value="Id">Id</option>
<option value="Model_Id">Model_Id</option>
<option value="Model">Model</option>
<option value="Manufacturer_Id">Manufacturer_Id</option>
<option value="Manufacturer">Manufacturer</option>
<option value="Type_Id">Type_Id</option>
<option value="Type">Type</option>
<option value="Location_Id">Location_Id</option>
<option value="Location">Location</option>
<option value="Vendor_Id">Vendor_Id</option>
<option value="Vendor">Vendor</option>
<option value="Status_Id">Status_Id</option>
<option value="Status">Status</option>
<option value="ip_address">ip_address</option>
<option value="mac_address">mac_address</option>
<option value="note">note</option>
<option value="owner">owner</option>
<option value="cost">cost</option>
<option value="po_number">po_number</option>
<option value="description">description</option>
<option value="invoice_number">invoice_number</option>
<option value="serial_number">serial_number</option>
<option value="asset_tag_number">asset_tag_number</option>
<option value="acquired_date">acquired_date</option>
<option value="disposed_date">disposed_date</option>
<option value="verified_date">verified_date</option>
<option value="created_date">created_date</option>
<option value="created_by">created_by</option>
<option value="modified_date">modified_date</option>
<option value="modified_by">modified_by</option>
</select>
这是我的[Export]
按钮(超链接)的设置:
This is the setup for my [Export]
button (hyperlink):
@*<a href="/Export/ExportUsingEPPlus" class="btn btn-default btn-sm noDecoration exportBtn"><span class="glyphicon glyphicon-export"> Export - EPPlus</span></a>*@
<a href="#" class="btn btn-default btn-sm noDecoration exportBtn"><span class="glyphicon glyphicon-export"> Export - EPPlus</span></a>
我现在不知道的是如何在MultiSelectList中获取所有选定值,并将它们传递给我的控制器,以决定应将哪些字段导出到Excel.
What I can't figure out now is how to get all of the selected values in the MultiSelectList and pass them to my Controller to dictate what fields should be exported to Excel.
@section Scripts {
<script type="text/javascript">
$(document).ready(function () {
$("a.exportBtn").on("click", function (e) {
e.preventDefault();
alert("Export button clicked!");
exportSelectedAssets();
});
function exportSelectedAssets() {
}
});
</script>
}
到目前为止,这是我使用EPPlus库在Controller中拥有的内容.当前,它仅在[A1]
单元格中创建一个具有一个值的.xlsx
.将MultiSelectList中的值传递到此控制器后,我想遍历Table中所选字段的每个值并输出它们:
This is what I have so far in my Controller using the EPPlus library. Currently it simply creates an .xlsx
with one value in the [A1]
cell. Once I pass the values from MultiSelectList into this controller, I want to loop through each value of the selected fields in my Table and output them:
public ActionResult ExportUsingEPPlus()
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
ws.Cells["A1"].Value = "Sample Export 1";
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
我正在考虑使用JSON将所有选择的值发布到我的Controller,但是我不确定这是否是这种情况的最佳途径吗?可以给有更多经验的人加分吗?
I was considering JSON for posting all selected values to my Controller, but I'm not sure if this is the best route for this situation? Can someone with more experience weigh in on this?
编辑:
尝试达伍德的建议,我创建了ViewModel
-ExportAssetsViewModel
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace InventoryTracker.Models
{
public class ExportAssetsViewModel
{
public Dictionary<int, string> ListOfExportFields { get; set; }
public int[] SelectedFields { get; set; }
public ExportAssetsViewModel() {
ListOfExportFields = new Dictionary<int, string>() {
{1, "Model"},
{2, "Manufacturer"},
{3, "Type"},
{4, "Location"},
{5, "Vendor"},
{6, "Status"},
{7, "ip_address"},
{8, "mac_address"},
{9, "note"},
{10, "owner"},
{11, "cost"},
{12, "po_number"},
{13, "description"},
{14, "invoice_number"},
{15, "serial_number"},
{16, "asset_tag_number"},
{17, "acquired_date"},
{18, "disposed_date"},
{19, "verified_date"},
{20, "created_date"},
{21, "created_by"},
{22, "modified_date"},
{23, "modified_by"},
};
}
}
}
然后我将MultiSelectList
放置在HTML.BeginForm()
中的ExportController - Index
视图中:
I then placed my MultiSelectList
on my ExportController - Index
View within an HTML.BeginForm()
:
@using (Html.BeginForm())
{
@Html.ListBox("PropertyList", typeof(InventoryTracker.Models.INV_Assets).GetProperties().Select(p => new SelectListItem { Text = p.Name, Value = p.Name, Selected = false }), new { @Id = "exportListBox" })
<input type="submit" value="ExportUsingEPPlus" />
}
并在我的ExportUsingEPPlus()
动作中对其进行了修改,如下所示:
and on my ExportUsingEPPlus()
Action modified it as demonstrated:
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
ws.Cells["A1"].Value = "Sample Export 1";
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
但是,当我单击表单输入按钮时,是否未按下ExportUsingEPPlus()
Controller Action开头的断点?发生的一切是页面似乎刷新并且我的选择从MultiSelectList
...?
When I click my form input button however, my break point at the start of ExportUsingEPPlus()
Controller Action is not being hit? All that occurs is the page appears to refresh and my selects get cleared out from the MultiSelectList
...?
EDIT2 :
将我的Index
视图中的@model
从InventoryTracker.Models.INV_Assets
更改为InventoryTracker.Models.ExportAssetsViewModel
,但是我的ListBoxFor()
中的m.SelectedFields
和Model.ListOfExportFields
被标记为不包含定义的模型吗? /p>
Changed the @model
on my Index
View from InventoryTracker.Models.INV_Assets
to InventoryTracker.Models.ExportAssetsViewModel
, but m.SelectedFields
and Model.ListOfExportFields
in my ListBoxFor()
are getting flagged for the model not containing a definiton for them?
@using GridMvc.Html
@using System.Collections.Generic
@using System.Web.Mvc
@using MvcCheckBoxList.Model
@model InventoryTracker.Models.ExportAssetsViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Export</h2>
@using (Html.BeginForm("ExportUsingEPPlus", "Export", FormMethod.Post))
{
@Html.ListBoxFor(m => m.SelectedFields, new MultiSelectList(Model.LisOfExportFields, "Key", "Value"), new { @class = "form-control", style = "height: 250px;" })
<input type="submit" value="ExportUsingEPPlus" />
}
EDIT3 :
当我将鼠标悬停在ListBoxFor()
中的m => m
上时,我注意到我的View似乎认为它仍在使用模型INV_Assets
,即使我将@model
重新定义为InventoryTracker.Models.ExportAssetsViewModel
.我重新输入了@model
的定义,现在m
只是显示为(parameter) TModel m
...?
I noticed when hovering over the m => m
in my ListBoxFor()
that my View seemed to think it was still using the model INV_Assets
even though I had redefined my @model
as InventoryTracker.Models.ExportAssetsViewModel
. I retyped my @model
definition and now m
simply shows as (parameter) TModel m
...?
由于我之前尝试使用ExportController
创建了ExportAssetsViewModel
,并希望通过JS/AJAX传递选定的值,所以我认为我会基于ExportAssetsViewModel
制作一个新的控制器.尝试执行此操作会导致以下错误:
Since I created the ExportAssetsViewModel
after my previous attempts using the ExportController
with the idea of passing selected values via JS/AJAX, I thought I would make a new controller based upon ExportAssetsViewModel
. Attempting this though led to the following error:
现在@Html.ListBoxFor(m => m.SelectedFields, new MultiSelectList(Model.ListOfExportFields, "Key", "Value"), new { @class = "form-control", style = "height: 250px;" })
标记为:"The type arguments for method 'System.Web.Mvc.Html.SelectExtensions.ListBoxFor<.....> cannot be inferred from the usage. Try specifying the type arguments explicitly."
任何人都可以帮忙吗?
EDIT4 :
忽略EDIT3.我没有将ExportAssetsViewModel
传递给View
.在下面固定:
Disregard EDIT3. I wasn't passing ExportAssetsViewModel
to the View
. Fixed below:
控制器-索引操作:
public ActionResult Index()
{
//var assetList = _db.INV_Assets.ToList();
//return View(assetList);
ExportAssetsViewModel expViewMod = new ExportAssetsViewModel();
return View(expViewMod);
}
索引视图:
@using System.Collections.Generic
@using System.Web.Mvc
@model InventoryTracker.Models.ExportAssetsViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Export</h2>
<p>Please select which Asset fields to Export to Excel:</p>
@using (Html.BeginForm("ExportUsingEPPlus", "Export", FormMethod.Post))
{
@Html.ListBoxFor(m => m.SelectedFields, new MultiSelectList(Model.ListOfExportFields, "Key", "Value"), new { @class = "form-control", style = "height: 250px;" })
<input type="submit" value="ExportUsingEPPlus" />
}
推荐答案
如果您不使用Ajax,请执行以下操作:
If you are not using Ajax do this:
创建一个ViewModel(具有一个字段列表,以及一个用于存储所选字段的数组):
Create a ViewModel (With a List Of fields, and an array to store the selected fields):
public class ViewModel
{
public Dictionary<int, string> LisOfFields { get; set; }
public int[] SelectedFields { get; set; }
public ViewModel()
{
LisOfFields = new Dictionary<int, string>()
{
{1, "Field1"},
{2, "Field2"},
{3, "Field3"},
};
}
}
然后创建一个视图,用户可以在其中选择字段
Then Create a View where user can select fields
@using (Html.BeginForm())
{
@Html.ListBoxFor(m => m.SelectedFields, new MultiSelectList(Model.LisOfFields, "Key", "Value"), new { @class = "form-control", style = "height: 250px;" })
<input type="submit" value="Export" />
}
在POST
控制器中:(请注意以下方法存在语法错误)
In the POST
Controller: (Note following method has syntax errors)
[HttpPost]
public ActionResult Export(ViewModel model){
var exportFields = new List<string>();
foreach(var selectedfield in model.SelectedFields)
{
exportFields.Add(model.LisOfFields.First(s=> s.Key == selectedField).Value)
}
// EXPORT ALL in exportFields
}
将您的表格更改为此:
Change your FORM to this:
@using (Html.BeginForm("ExportUsingEPPlus","Export", FormMethod.Post))
{
@Html.ListBoxFor(m => m.SelectedFields, new MultiSelectList(Model.LisOfFields, "Key", "Value"), new { @class = "form-control", style = "height: 250px;" })
<input type="submit" value="ExportUsingEPPlus" />
}
这篇关于将所有选定的MultiSelectList值传递到MVC Controller,以将EPPlus导出到Excel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!