最近有一個(2)類似的情況,並發現沒有真正的烘焙方式通過ajax做到這一點。好消息:這其實很簡單,你不需要ajax電話。
你可以做的是提交一個表單POST請求,並在你的控制器動作後,你可以在內存中生成的文件,並使用「返回文件()」泵的文件恢復到視圖沒有視圖重裝。
下面是使用iTextSharp的一個例子:
範例模型:
public class TestM
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Number { get; set; }
}
視圖(基本自動生成的創建)
@model DeleteMeWeb45.Models.TestM
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TestM</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Number, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
控制器:
public ActionResult Index()
{
TestM t = new TestM();
return View(t);
}
[HttpPost]
public ActionResult Index(TestM t)
{
if(ModelState.IsValid)
{
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30);
byte[] pdfBytes;
BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
Font timesBold = new Font(bfTimes, 12, Font.BOLD);
using (var mem = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, mem);
doc.SetMargins(20, 20, 20, 60);
doc.Open();
var orderInfoTable = new PdfPTable(2);
orderInfoTable.AddCell(new Phrase("First Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold));
orderInfoTable.AddCell(new Phrase("Last Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.LastName, timesBold));
orderInfoTable.AddCell(new Phrase("Number:", timesBold));
orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold));
doc.Add(orderInfoTable);
doc.Close();
pdfBytes = mem.ToArray();
}
return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf");
}
else
{
return View(t);
}
}
在EV
景觀:
變化1,你要保持你的表單提交按鈕是(這樣可以節省或做什麼),並希望有一個額外的按鈕,只是下載,那麼你將修改上面的例子,例如耳鼻喉科,給形式的ID:
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "transferForm" }))
變化2.添加一個按鈕和JS在備用位置提交表單:
<div class="row">
<div class="btn btn-primaryDark btn-sm" id="btnRunReport" style="min-width:120px;">Run Report</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function() {
$("#btnRunReport").click(function() {
$('#transferForm').attr('action', "/Home/JSFUN").submit();
});
});
</script>
}
控制器改變: 1.創建一個新的控制器動作來處理POST請求:
[HttpPost]
public ActionResult JSFUN(TestM t)
{
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30);
byte[] pdfBytes;
BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
Font timesBold = new Font(bfTimes, 12, Font.BOLD);
using (var mem = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, mem);
doc.SetMargins(20, 20, 20, 60);
doc.Open();
var orderInfoTable = new PdfPTable(2);
orderInfoTable.AddCell(new Phrase("First Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold));
orderInfoTable.AddCell(new Phrase("Last Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.LastName, timesBold));
orderInfoTable.AddCell(new Phrase("Number:", timesBold));
orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold));
doc.Add(orderInfoTable);
doc.Close();
pdfBytes = mem.ToArray();
}
return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf");
}
這樣,你的用戶可以使用的形式提交按鈕,併爲不同目的的導出按鈕。
不可能通過AJAX直接提供下載。 – SLaks
爲什麼你認爲你需要通過AJAX調用來做到這一點?只需將用戶引導至該網址即可。如果文件下載,顯示的頁面不會改變。 – DavidG
有沒有另一個實現,我想在沒有AJAX的情況下完成?到目前爲止,AJAX一直是我可以將自定義對象傳遞給c#控制器的唯一方法 – slugibihl