从通过 jQuery AJAX 调用的控制器返回 PDF

Posted

技术标签:

【中文标题】从通过 jQuery AJAX 调用的控制器返回 PDF【英文标题】:Return PDF from Controller called via jQuery AJAX 【发布时间】:2017-04-02 21:55:38 【问题描述】:

我找到了一些关于使用控制器从 EvoPDF 创建 PDF 的答案,但似乎没有一个答案可以处理通过 jQuery AJAX 调用的控制器。

我有一个简单的 jQuery 函数,可以像我的应用程序中的许多其他函数一样将数据发送到控制器:

$.ajax(
    url: "/AnnualFees/showStatement",
    cache: false,
    data: 
        authKey: memberData.authKey,
        entityId: memberData.entityId,
        barNumber: memberData.barNumber,
        statementhtml: encodeURIComponent($("#statementBody").html())
    ,
    method: "POST",
    success: function (data) 
    ,
);

我遵循了所有示例并拥有此代码。我可以更改它以保存 PDF 并确认正在生成 PDF。

public ActionResult getStatementPDF(string statementHTML)

    //initialize the PdfConvert object
    PdfConverter pdfConverter = new PdfConverter();

    // set the license key - required
    pdfConverter.LicenseKey = "uzUmNCcnNCYsIjQgOiQ0JyU6JSY6LS0tLQ==";

    StringBuilder PDFBody = new StringBuilder();
    PDFBody.Append("<!DOCTYPE html>");
    PDFBody.Append("<html lang=\"en\">");
    PDFBody.Append("<head>");
    PDFBody.Append("    <meta charset=\"utf - 8\">");
    PDFBody.Append("    <title>Statement</title>");
    PDFBody.Append("</head>");
    PDFBody.Append("");
    PDFBody.Append("<body>");
    PDFBody.Append("Hello world.");
    PDFBody.Append("</body>");
    PDFBody.Append("</html>");

    byte[] outPdfBuffer = pdfConverter.GetPdfBytesFromHtmlString(PDFBody.ToString());

    // Send the PDF file to browser
    FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
    fileResult.FileDownloadName = "Statement.pdf";

    return fileResult;

我可以确认它们没有错误,并且使用正确的应用程序/pdf 类型返回 200 成功,并且大小与磁盘上的大小大致相同。但是,没有出现任何 PDF,浏览器中也没有打开任何内容。

【问题讨论】:

什么都没有发生,因为回调没有响应 AJAX 请求。 Plus 文件下载不适用于 ajax。您想要的是在服务器上生成并保存 PDF 文件并返回指向该文件的 URL,以便可以在回调中重定向浏览器。 我想不惜一切代价避免保存 PDF,因为在这个阶段,PDF 是最终文档的草稿副本。我看到将 PDF 流式传输到浏览器的示例代码,但它只是不工作。这是不可能的吗? 【参考方案1】:

你需要在 ajax 调用中处理 onSuccess 的数据,你可以这样做来打开文件,如果你想保存文件,你可能需要使用 FileSaverJS (https://github.com/eligrey/FileSaver.js/)

success: function (data) 

    var file = new Blob([data],  type: 'application/pdf' );
    var fileURL = URL.createObjectURL(file);
    window.open(fileURL);

【讨论】:

这是打开文件流还是希望文件存在于服务器上?由于此步骤会生成 PDF 草案,因此我想避免污染服务器,只需将 PDF 文件的内存副本推送到浏览器即可。 这试图工作,但我正在为 fileURL 得到这个并且只打开一个空选项卡:blob:E9D06943-1619-4B89-BCF9-CD208BB9BAA9 在ajax调用中,请加上$.ajax( url: "/AnnualFees/showStatement", cache: false, responseType: 'arraybuffer', ....

以上是关于从通过 jQuery AJAX 调用的控制器返回 PDF的主要内容,如果未能解决你的问题,请参考以下文章

在Controller中使用Jquery ajax调用ActionResult方法并返回数据

从控制器返回后没有调用 Ajax Success 函数? MVC

来自 .ajax() 调用的数据的 jQuery .find() 返回未定义

Laravel - 如何通过 AJAX (jQuery) 调用控制器函数

从通过 jQuery/jQueryMobile 中的 AJAX 调用检索到的 JSON 数据正确设置变量

从 jquery ajax 调用分配变量返回未定义