使用 AJAX 调用下载文件

6
我正在使用PHPExcel来读取一个Excel模板,填充数据,并要求用户下载文件。
generate_excel.php
$objPHPExcel = PHPExcel_IOFactory::load("./template.xlsx");
//populate data ...
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');

当我直接从浏览器打开generate_excel.php时,会下载结果文件。但是如果我通过ajax调用generate_excel.php,则不会得到下载提示。使用Chrome开发工具,在网络选项卡中可以看到ajax调用已成功完成,并且在响应数据中看到一堆随机字符。我认为这就是Excel对象。
有人知道如何使用ajax实现下载Excel功能吗?我不想刷新页面。当用户单击“导出”按钮时,应该对php文件进行ajax调用并提示用户下载。
谢谢!

1
我不确定 PHP 是否与 ASP.NET 的工作方式相同,但当您返回文件时,页面实际上不会重新加载。因此,它是否使用 Ajax 并不重要。 - reggaemahn
5个回答

9
我在寻找方法将JSON数据通过ajax传递到PHP,并返回一个excel文件(使用MySQL和PHPExcel),供用户保存。我查看了一些资料并整理了一些内容,希望能对某些人有所帮助。
jQuery:
$("#exportBotton").on("click",function(event) {
event.preventDefault();
// create json object;
str_json = JSON.stringify({"key01":val01, "key02":val02, "key03":val03});
        $.ajax({
              type: "post",
              data: str_json,
              url: "../../includes/dbSelect_agentFormExport.php",
              dataType: "json",
              success: function(output){
                          // output returned value from PHP t
              document.location.href =(output.url);
            }
       });
});

PHP:

 $str_json = file_get_contents('php://input');
 $objPHPExcel = new PHPExcel();
 // here i populated objPHPExcel with mysql query result.....

 function saveExcelToLocalFile($objWriter){
    // make sure you have permission to write to directory
    $filePath = '../tmp/saved_File.xlsx';
    $objWriter->save($filePath);
    return $filePath;
}

 $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
 $response = array(
     'success' => true,
     'url' => saveExcelToLocalFile($objWriter)
 );
 echo json_encode($response);
 exit();

我试图直接从AJAX调用中打开Excel,但没有成功。 MIME类型存在问题。然后我尝试了你的方法,将文件保存到服务器并将URL给到主页面。它可以直接工作。你让我开心了一整天。非常感谢。 - Ydakilux
这很有帮助。 - sradha

8

按钮是<input type="button" />。 - John Ng
我想发送到 PHP 的数据来自全局变量。最好的发送方式是什么?创建隐藏输入元素吗? - John Ng
那是一个不同的问题。没有看到 HTML 代码就无法说任何东西。您可以尝试您建议的方法。 - David Jashi

5

以下是使用AJAX调用下载文件的示例:

var xhr = new XMLHttpRequest();
xhr.open("GET", "path/to/file.ext", true);
xhr.responseType = "blob";
xhr.onload = function(e) {
   if (xhr.status === 200) {
      var a = document.createElement("a");
      a.href = URL.createObjectURL(xhr.response);
      a.download = "file.ext";
      a.style.display = "none";
      document.body.appendChild(a);
      a.click();
   }
};
xhr.send();

有没有办法将文件保存在服务器上,并自动在新窗口中打开它? - John Ng

3

我找到了一种方法来实现这个,但我不确定这是否是一个理想的方法。

我在页面中添加了一个隐藏的iframe。当ajax调用返回时,它会返回创建数据的url。我使用javascript将iframe重定向到该url,从而自动触发下载操作。


0

您可以尝试以下方式:

  1. 使用Jquery AJAX POST请求发送要用于生成Excel报告的数据,并将该数据存储在会话变量中。返回任意字符串(如“success”)作为响应。
  2. 如果上述AJAX调用的输出为“success”,则向应用程序中的另一个URL发出GET请求,该URL从会话中读取数据(存储在第一步中),否则抛出错误,准备一个Excel文件并强制下载该Excel文件到浏览器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接