使用 CodeIgniter 和 PHPExcel 处理从 ajax 响应下载文件的任何方式

Any way to handle file download from ajax response using CodeIgniter and PHPExcel

我正在努力实现我想要的,但不确定是否可能。我正在为我的 Web 应用程序使用 CodeIgniterPHP。我的主页视图允许用户查询数据库,结果生成并以 table 形式显示在页面上。然后用户将查看 table 并提供下载为 xlsx Excel 文件的选项。我正在使用 ajax post 将 table 数据发送到我的 PHP controller,这将创建 Excel 文件。我还需要它在所有浏览器中工作,尤其是 Safari,因为客户端将从 Ipad 和台式机访问应用程序。

我家ajaxpost:(t是生成的idtable)

$("#btnExport").click(function() {
    $.ajax({
        type: "POST",
        url: '<?php echo base_url();?>index.php/Home/excel',
        datatype: 'html',
        data: {
            'queryData': $("#t").html()},
        success: function (response) {
            alert(response);
        }             
    });
});

我的控制器功能:

public function excel()
{
    $this->load->library('excel');
    $filename = "data";
    $table = $this->input->post('queryData');
    $objPHPExcel = new PHPExcel();
    $tmpfile = time().'.html';
    file_put_contents($tmpfile,$table);
    $objReader = PHPExcel_IOFactory::createReader('HTML');
    $objPHPExcel = $objReader->load($tmpfile);

    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename='.$filename);
    header('Cache-Control: max-age=0');

    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    $objWriter->save('php://output');       
    unlink($tmpfile);
}

问题是 ajax 响应的处理 我已经读到无法从 ajax 下载文件。我尝试过的一切都不起作用响应是二进制编码的数据我假设是 excel 文件。这个问题有解决方法吗?我决定使用 ajax,因为 table 可以在给定当前查询的情况下动态更改,并且需要发送到服务器 accordingly.Thanks 以获得任何帮助。

编辑 在链接的问题中,它是关于提交表单而不是触发下载的。我没有提交任何表格,只是将 html table 传递给 PHP 以构建 Excel 文件。我看不出这与我的问题有什么关系。我是不是误会了?

我知道有两种可能性

1.将构建的table存储在浏览器localStorage

<div id="myTable">
  <table>
    <tr>
    <th>A</th>
    <th>B</th>
  </tr>
   <tr>
      <td>Value for column A</td>
      <td>Value for column B</td>
  </tr>
 </table>
</div>

// 在 jquery

        $(document).ready(function(){
           alert('nothing');

            if (typeof(Storage) !== "undefined") {
                // Code for localStorage/sessionStorage.



               var table = $('#myTable').html();

              localStorage.setItem("storedTable",table);



            } else {

                console.log('no support');
                // Sorry! No Web Storage support..
            }

        });

// now you can get the table in the next page like this

var table = localStorage.getItem("storedTable");

2.解决方案,像这样

将它们存储在$_SESSION
  session_start()
  $_SESSION["myTable"]  = $yourConstructedTable

重定向到您要打印的页面

像这样得到 table

        session_start();
 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

        $table =   $_SESSION["myTable"];
       unset($_SESSION["myTable"]); // don't forget to unset the session

    // rest of your code

提交表单是触发文件下载的最佳方式... 即使您没有表格,也最好创建一个。

var baseUrl = '<?php echo base_url();?>'

var $form = $(`<form method="post" hidden action="${baseUrl}index.php/Home/excel"><textarea name="queryData">`)
$form.find('textarea').val($("#t").html())
$form.appendTo('body').submit()

然而,有一种替代方法可以保存 ajax 响应,那就是通过从 blob 响应创建一个带有 object url 的 link,设置下载属性并触发点击(在 IE 中你需要调用 navigator.saveOrOpenBlob
有一个很好的库叫做 FileSaver 来抽象出所有讨厌的供应商细节

您可以这样使用它:

fetch(url, {method: 'post', body: data})
.then(res => {
   var cd = res.header.get('Content-Disposition')
   var filename = cd.match(/filename="(.+)"/)[1]

   return res.blob().then(blob => saveAs(blob, filename))
})

但这不如提交表单并从可以发送 Content-Disposition header 的服务器获得一些帮助好,因为并非所有浏览器(主要是 sa​​fari)都支持 links...