使用“AJAX”下载 CSV 文件

2022-08-30 15:58:45

我正在尝试为我的网站完成一个相当简单的任务,但我不确定如何去做。我希望用户查看表,然后单击一个按钮,此时用户可以将该表的内容另存为 csv 文件。此请求有时可能非常复杂,因此我生成一个进度页来提醒用户。

除了实际生成csv文件之外,我已经弄清楚了大多数事情。(我使用jQuery和PHP)

jQuery 代码在单击时运行:

hmis_query_csv_export: function(query_name) {
    $.uiLock('<p>Query Loading.</p><img src="/images/loading.gif" />')
    $.get({
        url: '/php_scripts/utils/csv_export.php',
        data: {query_name: query_name},
        success: function(data) {
            $.uiUnlock();
        }
    });}

相关的 PHP:

header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=search_results.csv");
//
//Generate csv
//
echo $csvOutput
exit();

这样做是将文本作为PHP文件发送,但它不会生成下载。我做错了什么?


答案 1

如果要强制下载,则可以将当前页面重定向到下载链接。由于链接将生成下载对话框,因此当前页面(及其状态)将保留在原位。

基本方法:

$('a#query_name').click(function(){
    $('#wait-animation').show();
    document.location.href = '/php_scripts/utils/csv_export.php?query_name='+query_name;
    $('#wait-animation').hide();
});

更复杂:

$('a#query_name').click(function(){
    MyTimestamp = new Date().getTime(); // Meant to be global var
    $('#wait-animation').show();
    $.get('/php_scripts/utils/csv_export.php','timestamp='+MyTimestamp+'&query_name='query_name,function(){
        document.location.href = '/php_scripts/utils/csv_export.php?timestamp='+MyTimestamp+'&query_name='+query_name;
        $('#wait-animation').hide();
    });
});

在 PHP 脚本中:

@header("Last-Modified: " . @gmdate("D, d M Y H:i:s",$_GET['timestamp']) . " GMT");
@header("Content-type: text/x-csv");
// If the file is NOT requested via AJAX, force-download
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
    header("Content-Disposition: attachment; filename=search_results.csv");
}
//
//Generate csv
//
echo $csvOutput
exit();

两个请求的 URL 必须相同,以欺骗浏览器不要在 处开始新的下载,而是将副本保存在缓存中。我不完全确定,但似乎很有希望。document.location.href


答案 2

编辑我刚刚用一个10MB的文件尝试了这个,似乎val()太慢而无法插入数据。呼啦啦。


好吧,所以我让这个彼此去。这可能是也可能不完全疯狂!这个想法是发出AJAX请求来创建数据,然后使用回调将数据插入到当前页面上的隐藏表单中,该表单具有第三个“下载”页面的操作;插入后,表单自动提交,下载页面发送标题并回显POST,等等,下载。

一直以来,在原始页面上,您都表示文件正在准备中,并且当它完成时,指标将更新。

注意:此测试代码未经广泛测试,并且没有真正的安全检查(或任何安全检查)。我用一个1.5MB的CSV文件测试了它,它相当时髦。

索引.html

<a id="downloadlink" href="#">Click Me</a>
<div id="wait"></div>
<form id="hiddenform" method="POST" action="download.php">
    <input type="hidden" id="filedata" name="data" value="">
</form>

测试.js

$(document).ready(function(){
  $("#downloadlink").click(function(){       // click the link to download
      lock();                                // start indicator
      $.get("create.php",function(filedata){ // AJAX call returns with CSV file data
          $("#filedata").val(filedata);      // insert into the hidden form
          unlock();                          // update indicator
          $("#hiddenform").submit();         // submit the form data to the download page
      });
  });

  function lock(){
      $("#wait").text("Creating File...");
  }

  function unlock(){
      $("#wait").text("Done");
  }
});

创建.php

<?php
//create $data
print $data;
?>

下载.php

<?php
header("Pragma: public");
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: text/x-csv");
header("Content-Disposition: attachment;filename=\"search_results.csv\""); 

if($_POST['data']){
    print $_POST['data'];
}
?>

推荐