2011-05-23 80 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