我在C#中有一个方法,该方法基本上会生成CSV文件形式的字符串,如下所示:
[HttpPost]
[ActionName("ExportFolder")]
[ValidateAntiForgeryToken]
public string ExportFolder(int? folderId)
{
if (folderId != null)
{
using (var ctx = new myContextEntities())
{
var uid = Convert.ToInt32(User.Identity.Name);
var itemsToExport = ctx.Items.Where(y => y.MyListId == folderId && y.UserId == uid).ToList();
var sw = new StringWriter();
sw.WriteLine("\"Title1\",\"Title2 \",\"Title3\",\"Title4\",\"Title5\"");
foreach (var item in itemsToExport)
{
sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"",
item.Title1,
item.Title2,
item.Title3,
item.Title4,
item.Title5
));
}
return sw.ToString();
}
}
return "error";
}
基本上,这应该是准备就绪的“ CSV”文件,一旦完成POST,即可下载。
jQuery部分如下所示:
$(document).on("click", ".exportFolder", function () {
$.post("/ItemManagement/ExportFolder", { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]', '#__AjaxAntiForgeryForm').val(), folderId: $(this).attr("ID") }).done(function (data) {
// Now I should here download the file...
});
});
但是我现在不确定如何触发下载部分吗?有人可以帮我吗?
答案 0 :(得分:0)
假设您有一个占位符元素,其中将包含用于调用控制器操作的锚链接,以下载这样的文件:
<div id="dlink">
</div>
然后,您可以将生成的字符串存储在TempData
或Session
变量中,并返回CSV文件名作为JSON响应:
[HttpPost]
[ActionName("ExportFolder")]
[ValidateAntiForgeryToken]
public JsonResult ExportFolder(int? folderId)
{
if (folderId != null)
{
using (var ctx = new myContextEntities())
{
var uid = Convert.ToInt32(User.Identity.Name);
var itemsToExport = ctx.Items.Where(y => y.MyListId == folderId && y.UserId == uid).ToList();
var sw = new StringWriter();
sw.WriteLine("\"Title1\",\"Title2 \",\"Title3\",\"Title4\",\"Title5\"");
foreach (var item in itemsToExport)
{
sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"",
item.Title1,
item.Title2,
item.Title3,
item.Title4,
item.Title5
));
}
TempData["Contents"] = sw.ToString();
return Json("FileName");
}
}
return Json("error");
}
然后,根据FileResult
/ TempData
的内容,使用GET方法创建一个控制器动作以返回Session
,该事件将在单击锚链接时触发文件下载:
[HttpGet]
public ActionResult DownloadCsv(string fileName)
{
string csv = TempData["Contents"] as string;
string fileNameWithExt = fileName + ".csv";
// check if the CSV content exists
if (!string.IsNullOrEmpty(csv))
{
return File(new System.Text.UTF8Encoding.GetBytes(csv), "text/csv", fileNameWithExt);
}
else
{
return new EmptyResult();
}
}
最后通过将锚标记附加到done()
的{{1}}函数中来创建下载链接:
jQuery.post()
请注意,您不能直接从$(document).on("click", ".exportFolder", function () {
$.post("/ItemManagement/ExportFolder", { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]', '#__AjaxAntiForgeryForm').val(), folderId: $(this).attr("ID") }).done(function (data) {
if (data == "error") {
alert(data); // show error message
}
else {
var placeholder = $('#dlink');
// remove existing anchor links inside placeholder
placeholder.empty();
// generate new anchor link
$('<a href="@Url.Action("DownloadCsv", "ControllerName")' + '&fileName=' + data + '">Click here to download CSV file</a>').appendTo(placeholder);
}
});
});
响应下载CSV文件,因为AJAX响应旨在保留在同一页面上,因此必须使用另一个GET方法进行控制器操作,以提供由生成的定位链接触发的下载功能。
PS:这里的占位符元素只是一个示例,您可以根据需要进行修改。
参考文献: