2011-05-23 60 views
3

我有一個鏈接如下。使用JSON和MVC將PDF返回給瀏覽器?

@Html.ActionLink("Create Report", "Screenreport", "Reports", null, new { @class = "subNavA AddBorderTop", id = "screenReport", title = "Create Report" }) 

一旦鏈接被點擊,我有一個下面的jQuery代碼,它創建一個JSON對象併發布信息。

$().ready(function() { 

    // Create Report fron the screen data 
    $("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); }); 

}) /* end document.ready() */ 

function GenerateScreenReport(clikedtag, event) { 

    var table = $(".EvrakTable").html(); 
    var screendata = tableParser(table); 
    var Screentable = { Screenlist: screendata }; 

    var myurl = $(clikedtag).attr("href"); 
    var title = $(clikedtag).attr("title"); 


    $.ajax({ 
     url: myurl, 
     type: 'POST', 
     data: JSON.stringify(Screentable), 
     dataType: 'json', 
     contentType: 'application/json', 
     success: function() { alert("Got it"); } 
    }); 

}; 

處理JSON我有以下兩個類。實現了在同一個命名空間

namespace MyProject.ViewModels 
{ 
    public class Screenrecord 
    { 
     public string Fname{ get; set; } 
     public string LName { get; set; } 
     public string Age { get; set; } 
     public string DOB { get; set; } 
    } 


    public class Screentable 
    { 
     public List<Screenrecord> Screenlist { get; set; } 
    } 
} 

,並在我的控制器兩班,我有以下代碼:

[HttpPost] 
    public FileStreamResult Screenreport(Screentable screendata) 
    { 
     MemoryStream outputStream = new MemoryStream(); 
     MemoryStream workStream = new MemoryStream(); 
     Document document = new Document(); 
     PdfWriter.GetInstance(document, workStream); 
     document.Open(); 
     document.Add(new Paragraph("Hello World")); 
     document.Add(new Paragraph(DateTime.Now.ToString())); 
     document.Close(); 

     byte[] byteInfo = workStream.ToArray(); 
     outputStream.Write(byteInfo, 0, byteInfo.Length); 
     outputStream.Position = 0; 

     return new FileStreamResult(outputStream, "application/pdf"); 

    } 

此代碼應該GERATE PDF。 如果我離開[HttpPost],它不會生成PDF,它會進入/ Screenreport頁面,但是我看到我的JSON正確傳遞給控制器​​。 (screendata填充正確 - 在控制器中)

但是,如果我註釋掉[HttpPost],它會生成一個PDF,但screendata(在控制器中)爲空。

有人可以請解釋什麼是怎麼回事,並幫助我弄清楚。提前致謝。

+0

難道不是有勇敢的靈魂來幫助我嗎?我被困在這裏。它看起來像一個技術問題而不是實現。 – user762912 2011-05-24 16:42:47

回答

1

我覺得有義務發佈我的答案,因爲我沒有收到任何人的消息。我最終創建了一個包含隱藏輸入的表單,然後將我的json對象保存在隱藏的輸入中,然後提交表單。這次我會以字符串形式輸入,而不是json或xml。

var $hidInput = $("#dataToReport"); 
$hidInput.val(JSON.stringify(Screentable)); 
$('#frmScreenreport').submit(); 

感謝所有反正。

4

您不能使用AJAX下載文件,因爲JavaScript不允許保存下載的內容。 要解決此問題,您需要採取兩個步驟

第一個:發出HTTP Post請求,並且在控制器操作中我們會將文件內容存儲在內存流中。 二:成功撥打另一個電話被window.location的設置爲下載操作方法

在你的控制器創建此二項行動:

public ActionResult GenerateFile() 
    { 
     MemoryStream fileStream = new MemoryStream { Position = 0 }; 
     //position = 0 is important 

     var fName = string.Format("File-{0}.xlsx", DateTime.Now.ToString("s")); 
     Session[fName] = fileStream; 
     return Json(new { success = true, fName }, JsonRequestBehavior.AllowGet); 
    } 
    public ActionResult DownloadFile(string fName) 
    { 
     var ms = Session[fName] as MemoryStream; 
     if (ms == null) 
      return new EmptyResult(); 
     Session[fName] = null; 
     return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fName); 
    } 

在你的JavaScript:

$('#Donwload-button').click(function() { 
    data = JSON.stringify(YOURDATA); 
    $.ajax({ 
     contentType: 'application/json; charset=utf-8', 
     dataType: 'json', 
     type: 'POST', 
     url: "/YOURCONTROLLER/GenerateFile", 
     data: data, 
     success: function (d) { 
      if (d.success) { 
       window.location = "/YOURCONTROLLER/DownloadFile" + "?fName=" + d.fName; 
      } 
     }, 
     error: function() { 
      alert("Error"); 
     } 
    }); 

}); 
+0

非常好的解決方案!我用它來創建背景報告需要一些時間。 – 2016-02-18 16:15:48

+0

我會嘗試不使用會話來存儲PDF內容...如果您的PDF下載量很大,則會佔用服務器內存。 – Gwasshoppa 2016-11-07 02:28:00

+0

終於!這使我陷入了一年多的時間,我編寫了一些非常荒謬的黑客來從AJAX調用下載PDF文件。感謝您提供有效的解決方法。 – 2017-10-31 00:06:29

相關問題