显示在模态对话框中即时创建的pdf

时间:2014-09-18 20:28:09

标签: javascript jquery html asp.net-mvc-3 pdf

*最后总结。

我在SO和其他网站上阅读了很多像我这样的问题来尝试解决我的问题,但我找不到解决方案的最后一点。

说明

我有一个表(jqGrid),我从数据库中显示一些数据,如下所示:

+------+-----+
| Name | Age |
+------------+
| test |  1  |
+------+-----+

我有一个生成PDF的按钮,其中包含当前所选行的信息。

要做到这一点,当用户点击“PDF”按钮时,我会创建一个带有隐藏输入的表单并设置它们的值:

//create a form
$("<form>").attr({
   "id" : "invform",
   "method" : "post",
   "action" : "Home/generatePdf"
 });

然后我创建输入并隐藏它们并将表单提交给服务器......

//Id of selected row
var selectedRowId = $("#grid").jqGrid('getGridParam', 'selrow');
//Value of column Name of selected row
var cellValue = $("#grid").jqGrid('getCell', selectedRowId, 'name');

$("#invform")
.append($("<input>").attr({"name" : "Name", "type" : "text", "value" : cellValue}))

//hide all inputs
$("#invform input").attr({"hidden" : "true"});

//submit form
$("#invform").submit();

然后将表单发送到我的控制器并使用所有数据填充obj:

public FileStreamResult generatePdf(Model obj)
{
 PDF myPdf = <code for generating the pdf>;

 byte[] byteArr = myPdf.toByteArray();

 MemoryStream ms = new MemoryStream();
 ms.Write(byteArr, 0, byteArr.Length);

 HttpContext.Response.AddHeader("content-disposition",
 "inline; filename=" + randomName + ".pdf"); //random name is just a string based on time etc

 return new FileStreamResult(ms, "application/pdf");
}

这一切都很完美。

问题:

在表单上调用submit()后,将调用控制器并返回pdf并显示在同一选项卡上。我需要在我拥有的模态窗口上显示此表单。

HTML:

<div id="pdfdiv" style="display:none">
    <iframe id="pdfframe" style="width:100%; height:100%;">
    </iframe>
</div>

JS:

$("#pdfdiv").dialog({
  height: ($(window).height() * 0.95),
  width: ($(window).width() * 0.45),
  position: {
    my: "center bottom",
    at: "center top",
    of: $(window)
  }
});

我不知道在iframe的“src”属性上放什么来使pdf显示在那里而不是在sabe浏览器选项卡上。 我觉得这很容易做,而且我错过了一些东西,因为我是网络开发的新手。

总结:我从控制器返回的pdf显示在同一个浏览器选项卡上,我需要让它出现在jquery对话框中,但是我不知道在iframe src属性中放什么,因为pdf是在af之后生成的表格已提交。

2 个答案:

答案 0 :(得分:0)

请勿创建表单并将其命名为submit()方法。

在按钮的点击事件中使用jQuery $ .post()函数:

$.post("Home/generatePdf", {
   "id" : "invform", 
   "name" : "Name", 
   "type" : "text", 
   "value" : cellValue,

function( resp ) {
    //Success function
    //Reply with a JSON string from server indicating the PDF URL in the url property

    resp.url;   //this should cointain the URL to your generated PDF

},

"json"

});

这样可以避免将PDF从服务器下载到浏览器。

在&#34;成功功能&#34;上,打开模式并显示PDF。 您可以使用pdf.js库(https://github.com/mozilla/pdf.js/)在模式中显示PDF,请记住,如果您不使用此库(或类似文件),除非PDF阅读器扩展名,否则PDF不会显示在浏览器上已安装在浏览器中。

我假设这些PDF是在服务器上生成的,可以在以后下载,否则您只需将URL传递给点击按钮处理程序中的pdf.js,而不是执行$ .post()。

另外,Google文档查看器可以替代显示PDF(生成并存储在服务器上或通过URL动态传输),如果PDF不包含敏感,只需在模态窗口中使用它,但是请注意,PDF要传输到Google文档才能呈现,PDF URL也必须是公开的(不需要访问用户/密码):

<iframe src="http://docs.google.com/viewer?url=your-pdf-url.com/doc.pdf&embedded=true" width="600" height="780" style="border: none;"></iframe>

答案 1 :(得分:0)

我解决了我的问题。 这里的想法是没有办法捕获表单(属性动作)调用的方法/动作的返回。相反,我必须做的是从我的对话框中的iframe调用控制器动作。我使用该表单是因为它是将数据作为复杂对象传递给控制器​​的最简单方法,但是要从iframe执行此操作,我必须使用对象的参数组装URL并在控制器中读取它们。我用我需要的参数构建了url(name = ..&amp; age = ...)并在按钮后动态设置iform src以显示模式窗口被单击,导致操作返回到iframe并显示我的PDF。